Menggunakan Contoh Referensi

Kualitas ekstraksi seringkali dapat ditingkatkan dengan memberikan contoh referensi kepada LLM.

tip: Meskipun tutorial ini berfokus pada cara menggunakan contoh dengan model panggilan alat, teknik ini umumnya dapat diterapkan, dan akan berfungsi juga dengan teknik berbasis JSON atau prompt lainnya.

from langchain_core.prompts import ChatPromptBaru, PesanPengganti

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "sistem",
            "Anda adalah algoritma ekstraksi yang ahli. "
            "Hanya ekstrak informasi yang relevan dari teks. "
            "Jika Anda tidak tahu nilai dari atribut yang ditanyakan "
            "untuk diekstrak, kembalikan null untuk nilai atribut tersebut.",
        ),
        PesanPengganti("contoh"),  # <-- CONTOH!
        ("manusia", "{teks}"),
    ]
)

Coba template tersebut:

from langchain_core.messages import (
    PesanManusia,
)

prompt.invoke(
    {"teks": "ini adalah beberapa teks", "contoh": [PesanManusia(isi="testing 1 2 3")]}
)
ChatPromptValue(messages=[SystemMessage(content="Anda adalah algoritma ekstraksi yang ahli. Hanya ekstrak informasi yang relevan dari teks. Jika Anda tidak tahu nilai dari atribut yang ditanyakan untuk diekstrak, kembalikan null untuk nilai atribut tersebut."), HumanMessage(content='testing 1 2 3'), HumanMessage(content='ini adalah beberapa teks')]) 

Mendefinisikan Skema

Mari kita gunakan skema orang dari panduan cepat.

from typing import List, Optional

from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI


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


    name: Optional[str] = Field(..., description="Nama orang")
    hair_color: Optional[str] = Field(
        ..., description="Warna mata orang jika diketahui"
    )
    height_in_meters: Optional[str] = Field(..., description="Tinggi dalam METER")

class Data(BaseModel):
    """Data yang diekstrak tentang orang."""

    people: List[Person]

Mendefinisikan contoh acuan

Contoh dapat didefinisikan sebagai daftar pasangan input-output.

Setiap contoh berisi teks input contoh dan output contoh yang menunjukkan apa yang harus diekstraksi dari teks tersebut.

info

Ini agak rumit, jadi jangan ragu untuk mengabaikannya jika Anda tidak memahaminya!

Format contoh harus sesuai dengan API yang digunakan (misalnya, pemanggilan alat atau mode JSON, dll.).

Di sini, contoh yang diformat akan sesuai dengan format yang diharapkan untuk API pemanggilan alat karena itulah yang kita gunakan.

import uuid
from typing import Dict, List, TypedDict

from langchain_core.messages import (
    AIMessage,
    BaseMessage,
    HumanMessage,
    SystemMessage,
    ToolMessage,
)
from langchain_core.pydantic_v1 import BaseModel, Field


class Example(TypedDict):
    """Representasi contoh terdiri dari teks input dan pemanggilan alat yang diharapkan.

    Untuk ekstraksi, pemanggilan alat direpresentasikan sebagai contoh model pydantic.
    """

    input: str  # Ini adalah teks contoh
    tool_calls: List[BaseModel]  # Instansi model pydantic yang harus diekstraksi


def tool_example_to_messages(example: Example) -> List[BaseMessage]:
    """Konversi contoh menjadi daftar pesan yang dapat dimasukkan ke dalam LLM.

    Kode ini adalah adapter yang mengonversi contoh kita menjadi daftar pesan
    yang dapat dimasukkan ke dalam model obrolan.

    Daftar pesan per contoh sesuai dengan:

    1) HumanMessage: berisi konten dari mana konten harus diekstraksi.
    2) AIMessage: berisi informasi yang diekstraksi dari model
    3) ToolMessage: berisi konfirmasi ke model bahwa model telah meminta alat dengan benar.

    ToolMessage diperlukan karena beberapa model obrolan sangat dioptimalkan untuk agen
    daripada untuk penggunaan ekstraksi.
    """
    messages: List[BaseMessage] = [HumanMessage(content=example["input"])]
    openai_tool_calls = []
    for tool_call in example["tool_calls"]:
        openai_tool_calls.append(
            {
                "id": str(uuid.uuid4()),
                "type": "function",
                "function": {
                    "name": tool_call.__class__.__name__,
                    "arguments": tool_call.json(),
                },
            }
        )
    messages.append(
        AIMessage(content="", additional_kwargs={"tool_calls": openai_tool_calls})
    )
    tool_outputs = example.get("tool_outputs") or [
        "Anda telah memanggil alat ini dengan benar."
    ] * len(openai_tool_calls)
    for output, tool_call in zip(tool_outputs, openai_tool_calls):
        messages.append(ToolMessage(content=output, tool_call_id=tool_call["id"]))
    return messages

Selanjutnya, mari tentukan contoh-contoh kita dan kemudian ubah menjadi format pesan.

examples = [
    (
        "Lautan luas dan biru. Lebih dari 20.000 kaki dalam. Banyak ikan di dalamnya.",
        Person(name=None, height_in_meters=None, hair_color=None),
    ),
    (
        "Fiona bepergian jauh dari Prancis ke Spanyol.",
        Person(name="Fiona", height_in_meters=None, hair_color=None),
    ),
]


messages = []

for text, tool_call in examples:
    messages.extend(
        tool_example_to_messages({"input": text, "tool_calls": [tool_call]})
    )

Mari uji prompt tersebut

prompt.invoke({"text": "ini adalah beberapa teks", "examples": messages})
ChatPromptValue(messages=[SystemMessage(content="Anda adalah algoritma ekstraksi ahli. Hanya ekstrak informasi yang relevan dari teks. Jika Anda tidak tahu nilai dari atribut yang diminta untuk diekstrak, kembalikan nol untuk nilai atribut tersebut."), HumanMessage(content="Lautan sangat luas dan berwarna biru. Lebih dari 20.000 kaki dalamnya. Banyak ikan di dalamnya."), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'c75e57cc-8212-4959-81e9-9477b0b79126', 'type': 'function', 'function': {'name': 'Person', 'arguments': '{"name": null, "hair_color": null, "height_in_meters": null}'}}]}), ToolMessage(content='Anda telah memanggil alat ini dengan benar.', tool_call_id='c75e57cc-8212-4959-81e9-9477b0b79126'), HumanMessage(content='Fiona melakukan perjalanan jauh dari Prancis ke Spanyol.'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': '69da50b5-e427-44be-b396-1e56d821c6b0', 'type': 'function', 'function': {'name': 'Person', 'arguments': '{"name": "Fiona", "hair_color": null, "height_in_meters": null}'}}]}), ToolMessage(content='Anda telah memanggil alat ini dengan benar.', tool_call_id='69da50b5-e427-44be-b396-1e56d821c6b0'), HumanMessage(content='ini adalah beberapa teks')])

Membuat extractor

Di sini, kita akan membuat sebuah extractor menggunakan gpt-4.

llm = ChatOpenAI(
    model="gpt-4-0125-preview",
    temperature=0,
)


runnable = prompt | llm.with_structured_output(
    schema=Data,
    method="function_calling",
    include_raw=False,
)
/Users/harrisonchase/workplace/langchain/libs/core/langchain_core/_api/beta_decorator.py:86: LangChainBetaWarning: Fungsi `with_structured_output` berada dalam tahap beta. Ini sedang aktif dikerjakan, jadi API dapat berubah.
  warn_beta(

Tanpa contoh

Perhatikan bahwa meskipun kita menggunakan gpt-4, itu gagal dengan kasus uji yang sangat sederhana!

for _ in range(5):
    text = "Sistem tata surya itu besar, tapi bumi hanya punya 1 bulan."
    print(runnable.invoke({"text": text, "examples": []}))
people=[]
people=[Person(name='earth', hair_color=None, height_in_meters=None)]
people=[Person(name='earth', hair_color=None, height_in_meters=None)]
people=[]
people=[]

Dengan contoh

Contoh referensi membantu memperbaiki kegagalan!

for _ in range(5):
    text = "Sistem tata surya itu besar, tapi bumi hanya punya 1 bulan."
    print(runnable.invoke({"text": text, "examples": messages}))
people=[]
people=[]
people=[]
people=[]
people=[]
runnable.invoke(
    {
        "text": "Nama saya Harrison. Rambut saya hitam.",
        "examples": messages,
    }
)
Data(people=[Person(name='Harrison', hair_color='hitam', height_in_meters=None)])