Parsing

LLM yang mampu mengikuti instruksi dengan baik dapat diberi tugas untuk mengeluarkan informasi dalam format yang diberikan.

Pendekatan ini bergantung pada desain prompt yang baik dan kemudian menguraikan keluaran dari LLM untuk membuat mereka mengekstrak informasi dengan baik.

Di sini, kita akan menggunakan Claude yang sangat baik dalam mengikuti instruksi! Lihat model Anthropik.

from langchain_anthropic.chat_models import ChatAnthropic

model = ChatAnthropic(model_name="claude-3-sonnet-20240229", temperature=0)

tip: Semua pertimbangan yang sama untuk kualitas ekstraksi berlaku untuk pendekatan parsing. Tinjau panduan untuk kualitas ekstraksi.

Tutorial ini dimaksudkan untuk sederhana, tetapi seharusnya benar-benar mencakup contoh referensi untuk meningkatkan kinerja!

Menggunakan PydanticOutputParser

Contoh berikut menggunakan PydanticOutputParser bawaan untuk mengurai keluaran dari model obrolan.

from typing import List, Optional

from langchain.output_parsers import PydanticOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator


class Person(BaseModel):
    """Informasi tentang seseorang."""

    name: str = Field(..., description="Nama orang")
    height_in_meters: float = Field(..., description="Tinggi orang dalam meter.")


class People(BaseModel):
    """Informasi identifikasi tentang semua orang dalam teks."""

    people: List[Person]


parser = PydanticOutputParser(pydantic_object=People)

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "Jawab pertanyaan pengguna. Bungkus keluaran dalam tag `json`\n{format_instructions}",
        ),
        ("human", "{query}"),
    ]
).partial(format_instructions=parser.get_format_instructions())

Mari kita lihat informasi apa yang dikirim ke model

query = "Anna berusia 23 tahun dan tingginya 6 kaki"
print(prompt.format_prompt(query=query).to_string())
Sistem: Jawab pertanyaan pengguna. Bungkus keluaran dalam tag `json`
Keluaran harus diformat sebagai contoh JSON yang sesuai dengan skema JSON di bawah ini.

Sebagai contoh, untuk skema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
objek {"foo": ["bar", "baz"]} merupakan contoh yang diformat dengan baik dari skema tersebut. Objek {"properties": {"foo": ["bar", "baz"]}} tidak diformat dengan baik.

Berikut adalah skema keluaran:
{"description": "Informasi identifikasi tentang semua orang dalam teks.", "properties": {"people": {"title": "People", "type": "array", "items": {"$ref": "#/definitions/Person"}}}, "required": ["people"], "definitions": {"Person": {"title": "Person", "description": "Informasi tentang seseorang.", "type": "object", "properties": {"name": {"title": "Name", "description": "Nama orang", "type": "string"}, "height_in_meters": {"title": "Tinggi Dalam Meter", "description": "Tinggi orang dalam meter.", "type": "number"}}, "required": ["name", "height_in_meters"]}}}

Pengguna: Anna berusia 23 tahun dan tingginya 6 kaki
chain = prompt | model | parser
chain.invoke({"query": query})
People(people=[Person(name='Anna', height_in_meters=1.83)])

Pemutaran Kustom

Mudah untuk membuat prompt dan parser kustom dengan LangChain dan LCEL.

Anda dapat menggunakan fungsi sederhana untuk mem-parsing output dari model!

import json
import re
from typing import List, Optional

from langchain_anthropic.chat_models import ChatAnthropic
from langchain_core.messages import AIMessage
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator


class Person(BaseModel):
    """Informasi tentang seseorang."""

    name: str = Field(..., description="Nama orang tersebut")
    height_in_meters: float = Field(
        ..., description="Tinggi orang tersebut dalam meter."
    )


class People(BaseModel):
    """Informasi identifikasi tentang semua orang dalam sebuah teks."""

    people: List[Person]


prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "Jawab pertanyaan pengguna. Output jawaban Anda sebagai JSON yang  " 
            "cocok dengan schema yang diberikan: ```json\n{schema}\n```. "
            "Pastikan untuk membungkus jawaban dalam tag ```json dan ```",
        ),
        ("human", "{query}"),
    ]
).partial(schema=People.schema())


def extract_json(message: AIMessage) -> List[dict]:
    """Mengekstrak konten JSON dari sebuah string di mana JSON tertanam di antara tag ```json dan ```.

    Parameters:
        text (str): Teks yang berisi konten JSON.

    Returns:
        list: Sebuah daftar string JSON yang diekstrak.
    """
    text = message.content
    pattern = r"```json(.*?)```"

    matches = re.findall(pattern, text, re.DOTALL)

    try:
        return [json.loads(match.strip()) for match in matches]
    except Exception:
        raise ValueError(f"Gagal mem-parsing: {message}")
query = "Anna berusia 23 tahun dan tingginya 6 kaki"
print(prompt.format_prompt(query=query).to_string())
System: Jawab pertanyaan pengguna. Output jawaban Anda sebagai JSON yang  cocok dengan schema yang diberikan: \`\`\`json
{'title': 'People', 'description': 'Informasi identifikasi tentang semua orang dalam sebuah teks.', 'type': 'object', 'properties': {'people': {'title': 'People', 'type': 'array', 'items': {'$ref': '#/definitions/Person'}}}, 'required': ['people'], 'definitions': {'Person': {'title': 'Person', 'description': 'Informasi tentang seseorang.', 'type': 'object', 'properties': {'name': {'title': 'Nama', 'description': 'Nama orang tersebut', 'type': 'string'}, 'height_in_meters': {'title': 'Tinggi Dalam Meter', 'description': 'Tinggi orang tersebut dalam meter.', 'type': 'number'}}, 'required': ['name', 'height_in_meters']}}}
\`\`\`. Pastikan untuk membungkus jawaban dalam \`\`\`json dan \`\`\`
Human: Anna berusia 23 tahun dan tingginya 6 kaki
chain = prompt | model | extract_json
chain.invoke({"query": query})
[{'people': [{'name': 'Anna', 'height_in_meters': 1.83}]}]

Perpustakaan Lainnya

Jika Anda mencari pendekatan pemutaran, coba lihat perpustakaan Kor. Ini ditulis oleh salah satu pemelihara LangChain dan membantu dalam membuat prompt yang memperhitungkan contoh, memungkinkan pengendalian format (misalnya, JSON atau CSV) dan mengekspresikan skema dalam TypeScript. Sepertinya cukup bagus!