تجزیه و تحلیل

LLMs که قادر به دنبال کردن دستورات به خوبی هستند، می‌توانند برای تولید اطلاعات به یک فرمت داده شده مشخص وظایف داده شوند.

این رویکرد بر این اعتماد دارد که ابتدا دستورهای خوب طراحی شود و سپس خروجی LLMs را برای استخراج اطلاعات مورد نیاز خوب تجزیه کند.

در اینجا، ما از کلود استفاده می‌کنیم که عالی در دنبال کردن دستورات است! مشاهده کنید مدلهای Anthropics.

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 سال دارد و قدش ۶ فوت است"
print(prompt.format_prompt(query=query).to_string())
System: پاسخ به پرسش کاربر. خروجی را در برچسب‌های `json` بسته بندی کنید
خروجی باید به عنوان یک نمونه JSON که به شما معتاد به طرح زیر مطابقت دارد، فرمت دهی شود.

به عنوان یک مثال، برای طرح {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "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": "قد به متر", "description": "قد شخص به متر", "type": "number"}}, "required": ["name", "height_in_meters"]}}}

Human: آنا 23 سال دارد و قدش ۶ فوت است
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 و ``` جاسازی شده است.

    Parameters:
        text (str): متنی که حاوی محتوای JSON است.

    Returns:
        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"Failed to parse: {message}")
query = "آنا ۲۳ ساله است و قدش ۶ فوت است"
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: آنا ۲۳ ساله است و قدش ۶ فوت است
chain = prompt | model | extract_json
chain.invoke({"query": query})
[{'people': [{'name': 'آنا', 'height_in_meters': 1.83}]}]

کتابخانه‌های دیگر

اگر به دنبال استخراج با استفاده از رویکرد تجزیه هستید، کتابخانه Kor را بررسی کنید. این کتابخانه توسط یکی از نگهدارندگان LangChain نوشته شده است و به شما کمک می‌کند تا یک سفارشی را با در نظر گرفتن مثال‌ها ایجاد کرده، قالب‌ها را کنترل کرده (مانند JSON یا CSV) و طرح داده را در TypeScript بیان کنید. به نظر می‌رسد کار خوبی انجام می‌دهد!