Ayrıştırma

İyi talimatları takip edebilen LLM'ler görevlendirilerek belirli bir formatta bilgi çıkarmaları mümkün olabilir.

Bu yaklaşım, iyi talimatlar tasarlamaya ve ardından LLM'lerin çıktılarını başarılı bir şekilde bilgi çıkarmalarını sağlamak için ayrıştırmaya dayanmaktadır.

Burada, talimatları iyi bir şekilde takip edebilen Claude kullanacağız! Anthropic modelleri'ni görün.

from langchain_anthropic.chat_models import ChatAnthropic

model = ChatAnthropic(model_name="claude-3-sonnet-20240229", temperature=0)

ipucu: Ayrıştırma yaklaşımı için çıkarma kalitesi için tüm aynı düşünceler geçerlidir. Performansı artırmak için talimatların yönergelerini inceleyin.

Bu öğretici basit olması amaçlanmıştır, ancak genellikle performansı maksimuma çıkarmak için referans örnekler içermelidir!

PydanticOutputParser Kullanımı

Aşağıdaki örnek, yerleşik PydanticOutputParser'ın sohbet modelinin çıktısını ayrıştırmak için kullanılmasını göstermektedir.

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 Kişi(BaseModel):
    """Bir kişi hakkında bilgiler."""

    ad: str = Field(..., description="Kişinin adı")
    boyu_metre_cinsinden: float = Field(
        ..., description="Kişinin boyu metre cinsinden ifade edilmiştir."
    )


class Kişiler(BaseModel):
    """Metindeki tüm kişiler hakkında tanımlayıcı bilgiler."""

    kişiler: List[Kişi]


parser = PydanticOutputParser(pydantic_object=Kişiler)

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "sistem",
            "Kullanıcı sorgusunu yanıtlayın. Çıktıyı `json` etiketleri içine alın\n{formatlama_talimatları}",
        ),
        ("insan", "{sorgu}"),
    ]
).partial(formatlama_talimatları=parser.get_format_instructions())

Gönderilen bilgilere bir göz atalım

sorgu = "Anna 23 yaşındadır ve boyu 1.83 metredir"
print(prompt.format_prompt(sorgu=sorgu).to_string())
Sistem: Kullanıcı sorgusunu yanıtlayın. Çıktıyı `json` etiketleri içine alın
Çıktı, aşağıdaki JSON şemasına uyacak şekilde biçimlendirilmelidir.

Örneğin, {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]} şeması için
{"foo": ["bar", "baz"]} nesnesi, şema için iyi biçimlendirilmiş bir örnektir. {"properties": {"foo": ["bar", "baz"]}} nesnesi iyi biçimlendirilmemiştir.

İşte çıktı şeması:
{"description": "Metindeki tüm kişiler hakkında tanımlayıcı bilgiler.", "properties": {"kişiler": {"title": "Kişiler", "type": "array", "items": {"$ref": "#/definitions/Kişi"}}},
"required": ["kişiler"], "definitions": {"Kişi": {"title": "Kişi", "description": "Bir kişi hakkında bilgiler.", "type": "object",
"properties": {"ad": {"title": "Ad", "description": "Kişinin adı", "type": "string"}, "boyu_metre_cinsinden": {"title": "Boyu Metre Cinsinden",
"description": "Kişinin boyu metre cinsinden ifade edilmiştir.", "type": "number"}}, "required": ["ad", "boyu_metre_cinsinden"]}}}

İnsan: Anna 23 yaşındadır ve boyu 1.83 metredir
zincir = prompt | model | parser
zincir.invoke({"sorgu": sorgu})
Kişiler(kişiler=[Kişi(ad='Anna', boyu_metre_cinsinden=1.83)])

Özel Ayrıştırma

LangChain ve LCEL ile özel bir giriş ve ayrıştırıcı oluşturmak çok kolaydır.

Modelden gelen çıktıyı ayrıştırmak için basit bir fonksiyon kullanabilirsiniz!

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):
    """Bir kişi hakkında bilgiler."""

    name: str = Field(..., description="Kişinin adı")
    height_in_meters: float = Field(
        ..., description="Kişinin boyu metre cinsinden ifade edilmiştir."
    )


class People(BaseModel):
    """Metindeki tüm kişilerle ilgili bilgiler."""

    people: List[Person]


prompt = ChatPromptTemplate.from_messages(
    [
        (
            "sistem",
            "Kullanıcı sorusunu cevaplayın. Cevabınızı verilen şemayla eşleşen JSON olarak çıktılayın: ```json\n{schema}\n```. "
            "Cevabı mutlaka ```json ve ``` etiketleri arasına alın.",
        ),
        ("insan", "{query}"),
    ]
).partial(schema=People.schema())


def extract_json(message: AIMessage) -> List[dict]:
    """JSON içeriğini ```json ve ``` etiketleri arasına gömülü bir dizeden ayıklar.

    Parametreler:
        text (str): JSON içeren metin.

    Returns:
        list: Ayıklanmış JSON dizelerinin bir listesi.
    """
    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"Analiz edilemedi: {message}")