파싱
잘 지시를 따르는 LLMs(Large Language Models)는 주어진 형식으로 정보를 출력하는 것을 처리할 수 있습니다.
이 접근 방식은 좋은 프롬프트를 설계한 다음 LLMs의 출력을 구문 분석하여 정보를 추출하는 데 의존합니다.
여기서는 Claude를 사용할 것입니다. Claude는 지시를 잘 따르는 능력이 뛰어나죠! 앤트로픽 모델.
from langchain_anthropic.chat_models import ChatAnthropic
model = ChatAnthropic(model_name="claude-3-sonnet-20240229", temperature=0)
팁: 파싱 접근 방식에 대해 추출 품질에 대한 동일한 고려사항이 모두 적용됩니다. 추출 품질 지침을 검토하세요.
이 튜토리얼은 간단하게 유지되어야 하지만 일반적으로 성능을 극대화하기 위해 참조 예제를 포함해야 합니다!
PydanticOutputParser 사용
다음 예제는 내장된 PydanticOutputParser
를 사용하여 채팅 모델의 출력을 구문 분석하는 방법을 보여줍니다.
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):
"""사람에 관한 정보."""
name: str = Field(..., description="사람의 이름")
height_in_meters: float = Field(
..., description="미터로 표시된 사람의 키입니다."
)
class People(BaseModel):
"""텍스트에서 모든 사람에 대한 식별 정보."""
people: List[Person]
parser = PydanticOutputParser(pydantic_object=People)
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"사용자 쿼리에 응답하세요. 출력을 `json` 태그로 둘러십시오\n{format_instructions}",
),
("human", "{query}"),
]
).partial(format_instructions=parser.get_format_instructions())
이제 모델에게 보내는 정보를 살펴봅시다
query = "안나는 23살이고 키가 6피트입니다"
print(prompt.format_prompt(query=query).to_string())
System: 사용자 쿼리에 응답하세요. 출력을 `json` 태그로 둘러십시오
출력은 아래의 JSON 스키마를 준수하는 JSON 인스턴스로 형식화되어야 합니다.
예를 들어 스키마 {"properties": {"foo": {"title": "Foo", "description": "문자열의 목록", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}에 대해 객체 {"foo": ["bar", "baz"]}는 스키마의 잘 형식화된 인스턴스입니다. 객체 {"properties": {"foo": ["bar", "baz"]}}는 잘 형식화된 것이 아닙니다.
여기 출력 스키마입니다:
{"description": "텍스트에서 모든 사람에 대한 식별 정보.", "properties": {"people": {"title": "People", "type": "array", "items": {"$ref": "#/definitions/Person"}}}, "required": ["people"], "definitions": {"Person": {"title": "Person", "description": "사람에 관한 정보.", "type": "object", "properties": {"name": {"title": "Name", "description": "사람의 이름", "type": "string"}, "height_in_meters": {"title": "Height In Meters", "description": "미터로 표시된 사람의 키입니다.", "type": "number"}}, "required": ["name", "height_in_meters"]}}}
Human: 안나는 23살이고 키가 6피트입니다
chain = prompt | model | parser
chain.invoke({"query": query})
People(people=[Person(name='안나', height_in_meters=1.83)])
사용자 정의 구문 분석
LangChain
및 LCEL
을 사용하여 사용자 정의 프롬프트와 구문 분석기를 만드는 것은 쉽습니다.
모델에서 출력을 구문 분석하는 간단한 함수를 사용할 수 있습니다!
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):
"""개인에 대한 정보."""
name: str = Field(..., description="개인의 이름")
height_in_meters: float = Field(
..., description="미터 단위로 표현된 개인의 키."
)
class People(BaseModel):
"""텍스트에 있는 모든 사람에 대한 식별 정보."""
people: List[Person]
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"사용자 질의에 답변하십시오. 주어진 스키마와 일치하는 JSON 형식으로 답변을 출력하십시오: ```json\n{schema}\n```. "
"답변을 반드시 ```json 및 ``` 태그로 감싸야 합니다.",
),
("human", "{query}"),
]
).partial(schema=People.schema())
def extract_json(message: AIMessage) -> List[dict]:
"""JSON이 ```json 및 ``` 태그 사이에 포함된 문자열에서 JSON 콘텐츠를 추출합니다.
매개변수:
text (str): JSON 콘텐츠가 포함된 텍스트입니다.
반환:
list: 추출된 JSON 문자열의 리스트입니다.
"""
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"구문 분석 실패: {message}")
query = "안나는 23살이고 키가 6피트입니다"
print(prompt.format_prompt(query=query).to_string())
System: 사용자 질의에 답변하십시오. 주어진 스키마와 일치하는 JSON 형식으로 답변을 출력하십시오: \`\`\`json
{'title': 'People', 'description': '텍스트에 있는 모든 사람에 대한 식별 정보.', 'type': 'object', 'properties': {'people': {'title': 'People', 'type': 'array', 'items': {'$ref': '#/definitions/Person'}}}, 'required': ['people'], 'definitions': {'Person': {'title': 'Person', 'description': '개인에 대한 정보.', 'type': 'object', 'properties': {'name': {'title': 'Name', 'description': '개인의 이름', 'type': 'string'}, 'height_in_meters': {'title': 'Height In Meters', 'description': '미터 단위로 표현된 개인의 키.', 'type': 'number'}}, 'required': ['name', 'height_in_meters']}}}
\`\`\`. 답변을 반드시 \`\`\`json 및 \`\`\` 태그로 감싸야 합니다
Human: 안나는 23살이고 키가 6피트입니다
chain = prompt | model | extract_json
chain.invoke({"query": query})
[{'people': [{'name': '안나', 'height_in_meters': 1.83}]}]
다른 라이브러리
만약 구문 분석 접근 방식으로 추출해야 한다면 Kor 라이브러리를 확인해보세요. 이 라이브러리는 LangChain
유지 보수자 중 한 명이 작성한 것으로 예제를 고려하여 프롬프트를 작성하고, 형식(예: JSON 또는 CSV)을 제어할 수 있으며 TypeScript로 스키마를 표현할 수 있도록 도와줍니다. 매우 효과적으로 작동하는 것으로 보입니다!