Agent Frameworks

LLM Ajanlarını Test Etme: PydanticAI Bağımlılık Enjeksiyonu Stratejileri

Giriş: Yapay Zekâyı Test Etmenin Zorlukları

Büyük Dil Modelleri (LLM) ile akıllı ajanlar geliştirmek heyecan vericidir, ancak yazılım mühendisliğinde önemli zorluklar ortaya çıkarır. Geleneksel deterministik kodun aksine, LLM ajanları harici API'lere, stokastik çıktılara ve karmaşık durum yönetimine bağımlıdır. Bu da test etmeyi zorlaştırır. Uygulamanızın "beyni" deterministik olmayan bir API çağrısı olduğunda mantığı nasıl doğrularsınız? Çözüm, katı yazılım tasarım kalıplarında, özellikle Bağımlılık Enjeksiyonu (DI) yaklaşımında yatar. LLM uygulamaları geliştirmek için modern bir Python çerçevesi olan PydanticAI, bağımlılıkları temiz bir şekilde yönetmek için tip ipuçlarını ve pydantic modellerini kullanarak bu alanda mükemmel bir performans sergiler. LLM istemcisini iş mantığınızdan izole ederek, API token'larında size maliyet çıkarmayan veya kararsız ağ sorunlarından etkilenmeyen hızlı ve güvenilir birim testleri yazabilirsiniz.

Ajanlar İçin Bağımlılık Enjeksiyonu Neden Önemlidir?

Tipik bir ajan iş akışında, web'de arama yapan, sonuçları işleyen ve ardından bir özet üreten bir ajanınız olabilir. Web arama aracı ajana sabit kodlanmışsa, bir arama motoruna gerçekten erişmeden özetleme mantığını test edemezsiniz. Bağımlılık Enjeksiyonu, bu bağımlılıkları değiştirmenizi sağlar. Üretim ortamında gerçek bir `WebSearchTool` enjekte edersiniz. Testlerde ise önceden tanımlanmış verileri döndüren bir `MockWebSearchTool` enjekte edersiniz. Bu kalıp, birim testlerinizin harici servislerin güvenilirliğine değil, ajanınızın mantığına odaklanmasını sağlar.

Test Edilebilir Bir Ajan Kurulumu

Öncelikle, bir bağımlılık kullanan basit bir ajan tanımlayalım. Araç bağımlılıklarını yönetmek için PydanticAI'ın sistemini kullanacağız.

from pydantic_ai import Agent
from pydantic_ai.models import Model
from pydantic_ai.toolsets import Toolset
from pydantic import BaseModel

class Fact(BaseModel):
    fact: str
    source: str

# Bağımlılıkları yönetmek için özel bir Toolset tanımlayın
class FactToolset(Toolset):
    model: Model
    facts: list[Fact]

    def __init__(self, model: Model, facts: list[Fact]):
        self.model = model
        self.facts = facts

    @property
    def get_facts(self):
        """Bilinen olguların listesini döndürür."""
        return self.facts

# Ajanı tanımlayın
agent = Agent[FactToolset](
    model='openai:gpt-4o',
    system_prompt='Bir olgu denetçisisiniz. Soruları yanıtlamak için sağlanan olguları kullanın.',
)

async def main():
    # Üretim ortamında gerçek olguları enjekte edersiniz
    toolset = FactToolset(model=agent.model, facts=[Fact(fact="Su ıslaktır", source="Fizik")])
    
    try:
        result = await agent.run('Su ıslak mı?', toolset=toolset)
        print(result.output)
    finally:
        await toolset.aclose()

Sahte (Mock) ile Birim Test Etme

Şimdi bir birim testi yazabiliriz. Anahtar nokta, gerçek API çağrıları yapmamak için `Model`'in kendisini sahte (mock) hale getirmektir. PydanticAI bu amaçla bir `MockModel` sağlar.

import pytest
from pydantic_ai import Agent
from pydantic_ai.models import MockModel
from pydantic_ai.toolsets import Toolset
from pydantic import BaseModel
from pydantic_ai.messages import ModelResponse, TextPart, ToolCallPart

class Fact(BaseModel):
    fact: str
    source: str

class FactToolset(Toolset):
    def __init__(self, facts: list[Fact]):
        self.facts = facts

    def get_facts(self):
        return self.facts

# Ajanı bir yer tutucu model ile oluşturun. Gerçek model daha sonra enjekte edilecektir.
agent = Agent[FactToolset](
    model='mock', 
    system_prompt='Bir olgu denetçisisiniz.'
)

@pytest.mark.anyio
async def test_agent_facts():
    # 1. LLM'den beklenen yanıtı tanımlayın
    # LLM, 'get_facts' aracını çağırmalıdır
    mock_response = ModelResponse(
        parts=[
            ToolCallPart(tool_name='get_facts', args={}),
            TextPart(content='Olgulara göre su ıslaktır.')
        ]
    )
    
    # 2. Önceden tanımlı yanıtımızı döndüren bir MockModel oluşturun
    mock_model = MockModel(messages=[mock_response])
    
    # 3. Test verileriyle toolset oluşturun
    test_facts = [Fact(fact="Su ıslaktır", source="Test Kaynağı")]
    toolset = FactToolset(facts=test_facts)
    
    # 4. Ajanı sahte model ve toolset ile çalıştırın
    # Not: Sahte modeli ajan bağlamına enjekte ediyoruz
    async with agent.run_with_tools('Su ıslak mı?', toolset=toolset, model=mock_model) as result:
        assert result.output == 'Olgulara göre su ıslaktır.'

Sağlam Testler İçin En İyi Uygulamalar

1. Durumu İzole Edin: Her testin toolset'inin taze bir örneğini oluşturduğundan emin olun. Testler arasında kirlenmeyi önlemek için paylaşılan durumlardan kaçının. 2. Araçları Doğrulayın: Testlerinizde, doğru araçların çağrıldığını doğrulayın. Belirli isimlere sahip `ToolCallPart` nesnelerinin varlığını iddia etmek için `result.all_messages`'ı inceleyebilirsiniz. 3. Yapılandırılmış Çıktıları Kullanın: PydanticAI yapılandırılmış çıktıları (pydantic modelleri) destekler. LLM'in yanıtının şemanıza uyduğunu test edin. Bu, aşağı akış veri işleme için hayati önem taşır.

Sonuç

LLM ajanlarını uygulamak, "betikleme"den "mühendislik"e bir düşünce değişikliği gerektirir. PydanticAI'ın bağımlılık enjeksiyonu yeteneklerinden yararlanarak, yalnızca işlevsel değil, aynı zamanda test edilebilir ve sürdürülebilir ajanlar geliştirebilirsiniz. LLM yanıtları için `MockModel` ve veri bağımlılıkları için özel `Toolset`'lerin kombinasyonu, mantığınızı yapay zekanın deterministik olmayan doğasından ayırmanızı sağlar. Araçlarınızı izole ederek, modellerinizi sahteleyerek (mock) başlayın ve güvenle ölçeklenebilecek güvenilir yapay zeka uygulamaları için bir temel oluşturacaksınız.
Share: