Przykłady referencyjne
Jakość wydobycia danych często można poprawić, dostarczając przykładowe referencyjne dla LLM.
wskazówka: Chociaż ten samouczek skupia się na użyciu przykładów w narzędziu wywołującym model, ta technika jest ogólnie zastosowalna i będzie działać również z technikami opartymi na JSON lub zapytaniach.
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"Jesteś ekspertem w algorytmach ekstrakcji. "
"Wydobywaj tylko istotne informacje z tekstu. "
"Jeśli nie znasz wartości danego atrybutu, "
"proszę zwrócić null jako wartość atrybutu.",
),
MessagesPlaceholder("examples"), # <-- PRZYKŁADY!
("human", "{text}"),
]
)
Wypróbuj szablon:
from langchain_core.messages import (
HumanMessage,
)
prompt.invoke(
{"text": "to jest jakiś tekst", "examples": [HumanMessage(content="testowanie 1 2 3")]}
)
ChatPromptValue(messages=[SystemMessage(content='Jesteś ekspertem w algorytmach ekstrakcji. Wydobywaj tylko istotne informacje z tekstu. Jeśli nie znasz wartości danego atrybutu, proszę zwrócić null jako wartość atrybutu.'), HumanMessage(content='testowanie 1 2 3'), HumanMessage(content='to jest jakiś tekst')])
Zdefiniuj schemat
Ponownie użyjemy schematu osoby z szybkiego startu.
from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
class Person(BaseModel):
"""Informacje o osobie."""
name: Optional[str] = Field(..., description="Imię osoby")
hair_color: Optional[str] = Field(
..., description="Kolor oczu osoby, jeśli znany"
)
height_in_meters: Optional[str] = Field(..., description="Wzrost w metrach")
class Data(BaseModel):
"""Wydobyte dane o osobach."""
people: List[Person]
Zdefiniuj przykłady odniesienia
Przykłady mogą być zdefiniowane jako lista par wejście-wyjście.
Każdy przykład zawiera tekst wejścia
oraz oczekiwane wyjście
, pokazujące co powinno zostać wyodrębnione z tekstu.
info
To trochę zagłębione, więc śmiało można zignorować, jeśli nie jest jasne!
Format przykładu musi pasować do używanego interfejsu API (np. wywołanie narzędzia lub tryb JSON itp.).
Tutaj sformatowane przykłady będą pasować do oczekiwanego formatu dla interfejsu wywołującego narzędzie, ponieważ to właśnie używamy.
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):
"""Reprezentacja przykładu składającego się z tekstu wejściowego i oczekiwanych wywołań narzędzi.
Dla wyodrębnienia wywołania narzędzi są reprezentowane jako instancje modelu pydantic.
"""
input: str # To jest tekst przykładu
tool_calls: List[BaseModel] # Instancje modeli pydantic, które powinny zostać wyodrębnione
def tool_example_to_messages(example: Example) -> List[BaseMessage]:
"""Konwertuje przykład na listę wiadomości, które można podać do modelu językowego.
Ten kod stanowi adapter, który konwertuje nasz przykład na listę wiadomości,
które można podać do modelu rozmowy.
Lista wiadomości na przykład odpowiada:
1) HumanMessage: zawiera treść, z której powinna zostać wyodrębniona zawartość.
2) AIMessage: zawiera wyodrębnioną informację z modelu
3) ToolMessage: zawiera potwierdzenie dla modelu, że poprawnie wywołano narzędzie.
Wiadomość ToolMessage jest wymagana, ponieważ niektóre modele rozmowy są hiperzoptymalizowane dla agentów
niż dla zastosowania wyodrębniania.
"""
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 [
"Poprawnie wywołałeś to narzędzie."
] * 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
Teraz zdefiniujmy nasze przykłady i przekształćmy je na format wiadomości.
examples = [
(
"Ocean jest ogromny i niebieski. Ma ponad 20 000 stóp głębokości. Wiele ryb w nim pływa.",
Person(name=None, height_in_meters=None, hair_color=None),
),
(
"Fiona podróżowała daleko od Francji do Hiszpanii.",
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]})
)
Sprawdźmy teraz polecenie
prompt.invoke({"text": "to jest jakiś tekst", "examples": messages})
ChatPromptValue(messages=[SystemMessage(content="Jesteś ekspertem od ekstrakcji algorytmów. Wydobywaj tylko istotne informacje z tekstu. Jeśli nie znasz wartości pytanej cechy do wydobycia, zwróć null dla wartości tej cechy."), HumanMessage(content="Ocean jest ogromny i niebieski. Ma ponad 20 000 stóp głębokości. Wiele ryb znajduje się w nim."), 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='Poprawnie wywołałeś ten narzędzie.', tool_call_id='c75e57cc-8212-4959-81e9-9477b0b79126'), HumanMessage(content='Fiona podróżowała daleko od Francji do Hiszpanii.'), 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='Poprawnie wywołałeś to narzędzie.', tool_call_id='69da50b5-e427-44be-b396-1e56d821c6b0'), HumanMessage(content='to jest jakiś tekst')])
Stwórz ekstraktor
Tutaj stworzymy ekstraktor używając 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: Funkcja `with_structured_output` jest w fazie beta. Aktualnie jest aktywnie rozwijana, więc API może ulec zmianie.
warn_beta(
Bez przykładów
Zauważ, że mimo iż używamy gpt-4, zawodzi on przy bardzo prostym teście przypadku!
for _ in range(5):
text = "Układ słoneczny jest duży, ale Ziemia ma tylko 1 księżyc."
print(runnable.invoke({"text": text, "examples": []}))
ludzie=[]
ludzie=[Osoba(imię='ziemia', kolor_włosów=None, wzrost_w_metrach=None)]
ludzie=[Osoba(imię='ziemia', kolor_włosów=None, wzrost_w_metrach=None)]
ludzie=[]
ludzie=[]
Z przykładami
Przykłady referencyjne pomagają naprawić niepowodzenie!
for _ in range(5):
text = "Układ słoneczny jest duży, ale Ziemia ma tylko 1 księżyc."
print(runnable.invoke({"text": text, "examples": messages}))
ludzie=[]
ludzie=[]
ludzie=[]
ludzie=[]
ludzie=[]
runnable.invoke(
{
"text": "Mam na imię Harrison. Moje włosy są czarne.",
"examples": messages,
}
)
Dane(people=[Osoba(imię='Harrison', kolor_włosów='czarne', wzrost_w_metrach=None)])