LLM'nin Özelleştirilmesi

Mevcut yapay zeka modeli alanında, birçok farklı model bulunmaktadır ve LangChain'in resmi entegrasyonu tüm modelleri kapsamayabilir. Bazen kendi modelinizi oluşturabilir ve LangChain çerçevesine entegre edebilirsiniz.

Bu bölüm, özel bir LLM sarmalayıcı oluşturmanın ve kendi modelinizi veya LangChain tarafından desteklenmeyen modelleri kullanmanın kolaylaşmasını sağlayacak.

LangChain'de kendi LLM'nizi veya LangChain tarafından desteklenmeyen farklı bir sarmalayıcı kullanmak istiyorsanız, özel bir LLM sarmalayıcı oluşturabilirsiniz. Özel bir LLM yalnızca iki gerekli yöntemi uygulamalıdır:

  • Bir _call yöntemi, giriş olarak bir dize alır, isteğe bağlı durdurma sözcüklerini ve bir dize döndürür; _call yönteminde model çağrısını uygular.
  • Bir _llm_type özelliği, yalnızca günlükleme amaçları için kullanılan model adını temsil eden bir dize döndürür.

Gerekli yöntemlerin yanı sıra, özel bir LLM ayrıca isteğe bağlı bir yöntemi de uygulayabilir:

  • Bir _identifying_params özelliği, sınıfı yazdırmaya yardımcı olmak için kullanılır. Bir sözlük döndürmelidir.

Basit bir özel LLM'nin Uygulanması

Şimdi, sadece girişin ilk n karakterini döndüren çok basit bir özel LLM'yi uygulayalım.

from typing import Any, List, Mapping, Optional

from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM

class CustomLLM(LLM):
    n: int

    @property
    def _llm_type(self) -> str:
        return "özel"

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        if stop is not None:
            raise ValueError("durdurma sözcükleri izin verilmiyor.")
        return prompt[: self.n]

    @property
    def _identifying_params(self) -> Mapping[str, Any]:
        """Tanımlayıcı parametreleri al."""
        return {"n": self.n}

Artık bu özel LLM'yi diğer LLM'ler gibi kullanabiliriz.

Özel LLM'nin Kullanılması

Özel LLM nesnesini örnekleyebilir ve kullanabiliriz. Özel LLM'nin nasıl çağrılacağını ve özel olarak yazdırma çıktısını nasıl özelleştireceğimizi gösteriyoruz.

llm = CustomLLM(n=10)
llm.invoke("Bu bir örnek bir şeydir")
'Bu bir örn'

Ayrıca, LLM'yi yazdırabilir ve özel yazdırma çıktısını görüntüleyebiliriz.

print(llm)
CustomLLM
Parametreler: {'n': 10}

Sohbet Modelini Özelleştirme

Burada, LangChain'in sohbet modelini nasıl özelleştireceğimizi açıklayacağız.

Mesaj Girişi ve Çıkışı

Sohbet modelinde, mesajlar giriş ve çıkışın odak noktasıdır. Bir mesaj, kullanıcı tarafından girilen içerik ve model tarafından üretilen yanıtı temsil eder.

Mesajlar

Sohbet modeli, mesajları giriş olarak alır ve sonra bir veya daha fazla mesajı çıkış olarak üretir. LangChain'de, SystemMessage, HumanMessage, AIMessage, FunctionMessage/ToolMessage gibi çeşitli yerleşik mesaj türleri bulunmaktadır.

Bu mesaj türleri, function ve tool parametrelerine göre ayarlanarak genişletilebilir ve özelleştirilebilir.

from langchain_core.messages import (
    AIMessage,
    BaseMessage,
    FunctionMessage,
    HumanMessage,
    SystemMessage,
)

Akıcı Değişkenler

Tüm sohbet mesajları, isimlerinde Chunk içeren akıcı bir varyanta sahiptir.

from langchain_core.messages import (
    AIMessageChunk,
    FunctionMessageChunk,
    HumanMessageChunk,
    SystemMessageChunk,
    ToolMessageChunk,
)

Bu Chunk'lar, sohbet modelinin akışını sağlarken kullanılır ve her biri birikimli bir öznitelik tanımlar!

Örnek

AIMessageChunk(content="Merhaba") + AIMessageChunk(content=" dünya!")

Döndürür

AIMessageChunk(content='Merhaba dünya!')

Basit Sohbet Modeli

SimpleChatModel'den miras almak, hızlı bir şekilde basit bir sohbet modeli uygulamamızı sağlar.

Belki de bir sohbet modeli için gereken tüm işlevleri içermeyebilir, ancak hızlı bir uygulama sağlar. Daha fazla özellik gerektiğinde aşağıda tanımlanan BaseChatModel'e geçiş yapmak mümkündür.

SimpleChatModel'den miras almak, aşağıdaki arabirimi uygulamayı gerektirir:

  • _call methodu - harici model API çağrılarının uygulanması.

Ayrıca, aşağıdakiler belirtilebilir:

  • _identifying_params özelliği - parametre bilgilerini kaydetmek için kullanılır.

Opsiyonel:

  • _stream methodu - akış çıkışını uygulamak için kullanılır.

Temel Sohbet Modeli

BaseChatModel'den miras almak, _generate methodu ve _llm_type özelliğinin uygulanmasını gerektirir. İsteğe bağlı olarak, _stream, _agenerate, _astream ve _identifying_params'in uygulanması mümkündür.

Özel Bir Sohbet Modeli Örneği

Bu bölümde, CustomChatModelAdvanced adında özel bir sohbet modelinin kod uygulamasını, sohbet sonuçlarını oluşturmayı, akış çıkışını ve asenkron akış uygulamasını içeren bir örnek göstereceğiz.

from typing import Any, AsyncIterator, Dict, Iterator, List, Optional

from langchain_core.callbacks import (
    AsyncCallbackManagerForLLMRun,
    CallbackManagerForLLMRun,
)
from langchain_core.language_models import BaseChatModel, SimpleChatModel
from langchain_core.messages import AIMessageChunk, BaseMessage, HumanMessage
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult
from langchain_core.runnables import run_in_executor


class CustomChatModelAdvanced(BaseChatModel):
    """Son mesajın ilk `n` karakterini döndüren özel bir sohbet modeli uygulayın."""


    n: int
    """Özel model parametresi"""

    def _generate(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> ChatResult:
        """Bu noktada, genellikle üçüncü taraf bir modelin API'sini çağırarak model çağrı mantığı uygulanır ve ardından API'nin döndürdüğü sonucu langchain'in tanıyabileceği bir formata koyarız.
        Anahtar parametre açıklaması:
            messages: Mesajlardan oluşan prompt'ların listesi
        """
        son_mesaj = messages[-1]
        tokenlar = son_mesaj.icerik[: self.n]
        mesaj = AIMessage(icerik=tokenlar)
        nesil = ChatGeneration(mesaj=mesaj)
        return ChatResult(nesiller=[nesil])

    def _stream(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> Iterator[ChatGenerationChunk]:
        """Model akış çıkışı uygulaması, genellikle _generate methodu gibi, ancak akış çıkış işleme ile."""
        son_mesaj = messages[-1]
        tokenlar = son_mesaj.icerik[: self.n]

        for token in tokenlar:
            parça = ChatGenerationChunk(mesaj=AIMessageChunk(icerik=token))

            if run_manager:
                run_manager.on_llm_new_token(token, parça=parça)

            yield parça

    async def _astream(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> AsyncIterator[ChatGenerationChunk]:
        """'stream' methodunun asenkron sürümü uygulaması"""
        sonuç = await run_in_executor(
            None,
            self._stream,
            messages,
            stop=stop,
            run_manager=run_manager.get_sync() if run_manager else None,
            **kwargs,
        )
        for parça in sonuç:
            yield parça

    @property
    def _llm_type(self) -> str:
        """Özel modelin etiketi"""
        return "yankılayan-sohbet-modeli-ileri"

    @property
    def _identifying_params(self) -> Dict[str, Any]:
        """Özel hata ayıklama bilgisini döndür"""
        return {"n": self.n}

Özel Sohbet Modelini Test Etme

Sohbet modelini test edelim, invoke, batch, stream methodlarını kullanarak ve asenkron akış uygulamasını içeren astream'i kullanarak.

model = CustomChatModelAdvanced(n=3)

model.invoke([HumanMessage(icerik="merhaba!")])

model.invoke("merhaba")

model.batch(["merhaba", "hoşça kal"])

for parça in model.stream("kedi"):
    print(parça.icerik, end="|")

async for parça in model.astream("kedi"):
    print(parça.icerik, end="|")

async for olay in model.astream_events("kedi", sürüm="v1"):
    print(olay)