# LLM에 참조 예제를 제공하여 추출 품질을 향상시킬 수 있습니다.
> 팁: 이 튜토리얼은 모델을 호출하는 도구를 사용하는 방법에 중점을 두지만, 이 기술은 일반적으로 적용 가능하며 JSON 또는 프롬프트 기반 기술과도 작동합니다.
```python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"당신은 전문적인 추출 알고리즘입니다. "
"텍스트에서 관련된 정보만 추출하세요. "
"추출해야 할 속성의 값이 불명확한 경우 해당 속성의 값에는 null을 반환하세요.",
),
MessagesPlaceholder("예시"), # <-- 예제!
("human", "{text}"),
]
)
템플릿을 테스트해 보세요:
from langchain_core.messages import (
HumanMessage,
)
prompt.invoke(
{"text": "이것은 일부 텍스트입니다", "examples": [HumanMessage(content="테스트 1 2 3")]}
)
ChatPromptValue(messages=[SystemMessage(content="당신은 전문적인 추출 알고리즘입니다. 텍스트에서 관련된 정보만 추출하세요. 추출해야 할 속성의 값이 불명확한 경우 해당 속성의 값에는 null을 반환하세요."), HumanMessage(content='테스트 1 2 3'), HumanMessage(content='이것은 일부 텍스트입니다')])
스키마 정의
빠른 시작 가이드에서 '사람' 스키마를 재사용합시다.
from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
class Person(BaseModel):
"""사람에 대한 정보."""
name: Optional[str] = Field(..., description="사람의 이름")
hair_color: Optional[str] = Field(
..., description="알려진 경우 사람의 눈 색상"
)
height_in_meters: Optional[str] = Field(..., description="미터 단위의 키")
class Data(BaseModel):
"""사람에 대한 추출된 데이터."""
people: List[Person]
참조 예제 정의
예제는 입력-출력 쌍의 목록으로 정의될 수 있습니다.
각 예제는 예제 입력
텍스트와 텍스트에서 추출되어야 하는 내용을 보여주는 예제 출력
을 포함합니다.
정보
이 부분은 좀 깊이 들어간 내용이므로 이해하지 못하셔도 무시해 주셔도 됩니다!
예제의 형식은 사용된 API와 일치해야 합니다 (예: 도구 호출 또는 JSON 모드 등).
여기서 형식에 맞춰져 있는 예제는 도구 호출 API를 위해 예상되는 형식과 일치하게 됩니다. 왜냐하면 우리가 사용하는 것이기 때문입니다.
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):
"""텍스트 입력과 예상된 툴 호출로 구성된 예제의 표현입니다.
추출을 위해, 툴 호출은 pydantic 모델의 인스턴스로 나타냅니다.
"""
input: str # 이것은 예제 텍스트입니다.
tool_calls: List[BaseModel] # 추출되어야 하는 pydantic 모델의 인스턴스들
def tool_example_to_messages(example: Example) -> List[BaseMessage]:
"""예제를 LLM으로 공급할 수 있는 메시지 목록으로 변환합니다.
이 코드는 예제를 채팅 모델에 공급할 수 있는 메시지 목록으로 변환하는 어댑터입니다.
예제 당 메시지 목록은 다음에 해당합니다:
1) HumanMessage: 내용에 추출해야 하는 내용을 포함합니다.
2) AIMessage: 모델에서 추출된 정보를 포함합니다.
3) ToolMessage: 모델에 대해 툴이 정확하게 호출되었음을 확인하는 내용을 포함합니다.
툴 메시지는 채팅 모델 중 일부는 추출 사용 사례보다는 에이전트에게 초적화된 경우가 있기 때문에 필요합니다.
"""
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 [
"You have correctly called this tool."
] * 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
그 다음, 예제를 정의하고 메시지 형식으로 변환하겠습니다.
examples = [
(
"바다는 광활하고 푸르다. 깊이는 20,000피트 이상이다. 거기에는 많은 물고기가 있다.",
Person(name=None, height_in_meters=None, hair_color=None),
),
(
"피오나는 프랑스에서 스페인으로 멀리 여행했다.",
Person(name="피오나", 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]})
)
프롬프트를 테스트해 봅시다.
prompt.invoke({"text": "이것은 일부 텍스트입니다.", "examples": messages})
ChatPromptValue(messages=[SystemMessage(content="당신은 전문적인 추출 알고리즘입니다. 텍스트에서 관련 정보만 추출하세요. 추출해야 하는 속성 값의 값을 모르는 경우, 해당 속성의 값에 대해 null을 반환하세요."), HumanMessage(content="바다는 광활하고 푸르다. 깊이는 20,000피트 이상이다. 그 안에는 많은 물고기가 있다."), 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='당신은 이 도구를 올바르게 호출했습니다.', tool_call_id='c75e57cc-8212-4959-81e9-9477b0b79126'), HumanMessage(content='피오나는 프랑스에서 스페인으로 멀리 여행했다.'), 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='당신은 이 도구를 올바르게 호출했습니다.', tool_call_id='69da50b5-e427-44be-b396-1e56d821c6b0'), HumanMessage(content='이것은 어떤 텍스트입니다')])
추출기 만들기
여기서는 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: `with_structured_output` 함수는 베타 버전입니다. 활발하게 작업 중이므로 API가 변경될 수 있습니다.
warn_beta(
예제 없이
알림: gpt-4를 사용하더라도 아주 간단한 테스트 케이스에서 실패하는 것을 주목하세요!
for _ in range(5):
text = "태양계는 넓지만 지구에는 달이 하나뿐이에요."
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=[]
예제를 포함한 경우
참조 예제는 실패를 수정하는 데 도움이 됩니다!
for _ in range(5):
text = "태양계는 넓지만 지구에는 달이 하나뿐이에요."
print(runnable.invoke({"text": text, "examples": messages}))
people=[]
people=[]
people=[]
people=[]
people=[]
runnable.invoke(
{
"text": "내 이름은 Harrison이에요. 내 머리는 검은색이에요.",
"examples": messages,
}
)
Data(people=[Person(name='Harrison', hair_color='black', height_in_meters=None)])