· AI Development  · 6 min read

Tool Search, Context Management & Authentication: AI Agent Sistemlerinin Temel Taşları

AI agentlarının gücünü belirleyen üç kritik yetenek: tool search, context management ve authentication. Production-ready sistemler için kapsamlı bir rehber.

AI agentlarının gücünü belirleyen üç kritik yetenek: tool search, context management ve authentication. Production-ready sistemler için kapsamlı bir rehber.

Bir AI agent’ın “akıllı” olup olmadığını belirleyen şey, sadece büyük bir model kullanması değil. Üç temel yetenek var:

  1. Doğru tool’u bulabilmek (Tool Search)
  2. Bağlamı koruyabilmek (Context Management)
  3. Güvenli erişim sağlayabilmek (Authentication)

Bu yazıda bu üç konuyu derinlemesine inceleyeceğim - sadece teoride değil, production ortamında nasıl çalıştığını göstererek.

1. Tool Search: Agent’ın Beyni

Problem Nedir?

Bir agent’a “müşteri siparişini kontrol et” dediğinizde, sistem şunları yapabilir:

  • get_order(id) - sipariş bilgisi
  • check_inventory(product_id) - stok durumu
  • get_customer(id) - müşteri profili
  • send_email(to, subject, body) - e-posta gönderme
  • update_crm(lead_id, status) - CRM güncelleme

Hangisi doğru? Agent bunu nasıl seçiyor?

Naive Yaklaşım: Tool Calling

Çoğu başlangıç implementation’ı şöyle çalışır:

# Naive approach - her tool'u description ile gönder
tools = [
    {
        "name": "get_order",
        "description": "Sipariş detaylarını getir",
        "parameters": {"order_id": "string"}
    },
    # ... 50+ tool daha
]

response = llm.chat(messages, tools=tools)

Problem: 50+ tool’u context’e sığdırmak hem pahalı hem yavaş. Model “hangi tool doğru” kararını verirken noise artsın.

Semantic Tool Search: Vector Embedding ile

Production sistemlerde şöyle çalışır:

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma

# Tool'ları embed et
tools_collection = [
    {"name": "get_order", "description": "Müşteri sipariş detaylarını getir", "embedding": [...]},
    {"name": "check_inventory", "description": "Ürün stok durumunu kontrol et", "embedding": [...]},
]

# Query'yi embed et ve en yakın tool'ları bul
query_embedding = embeddings.embed_query("müşteri siparişi ne durumda?")
top_tools = vectorstore.similarity_search(query_embedding, k=3)

Avantajları:

  • Sadece en alakalı 3-5 tool gönderilir
  • Context window verimli kullanılır
  • Latency düşer

En iyi sonuç, ikisini birleştirmek:

class ToolRouter:
    def __init__(self, tools: list, embeddings):
        self.tools = tools
        self.vectorstore = Chroma.from_texts(
            [t["description"] for t in tools],
            embeddings
        )

    def route(self, query: str, top_k: int = 5) -> list:
        # Semantic search ile adayları bul
        candidates = self.vectorstore.similarity_search(query, k=top_k*2)

        # Function calling ile kesin eşleşmeleri bul
        function_matches = self.detect_exact_matches(query)

        # Fusion: Her iki sinyalden tool'ları seç
        return self.fuse_results(semantic=candidates, exact=function_matches)

2. Context Management: Hafıza Mimarisi

Problem Nedir?

Kullanıcı: “Dün Emre’nin siparişini kontrol” Model: “Emre kim?”

Agent hafızası olmadan her konuşma sıfırdan başlar. Context management, Uzun süreli hafıza (long-term memory) ve Kısa süreli hafıza (short-term memory) yönetimidir.

Memory Hiyerarşisi

┌─────────────────────────────────────────────┐
│  Working Memory (LLM Context Window)         │
│  - Son X mesaj / Son Y token                │
│  - Anlık kararlar için                      │
└─────────────────────────────────────────────┘

                      │ Semantic检索

┌─────────────────────────────────────────────┐
│  Short-Term Memory (Vector Store)            │
│  - Son 24 saat konuşmaları                  │
│  - Aktif projeler, görevler                  │
│  - Semantic search ile erişim               │
└─────────────────────────────────────────────┘

                      │ Archive

┌─────────────────────────────────────────────┐
│  Long-Term Memory (Persistent Store)         │
│  - Müşteri profilleri, geçmiş işler         │
│  - Öğrenilen bilgiler, tercihler            │
│  - Graph database + Vector store            │
└─────────────────────────────────────────────┘

Implementation: LangChain Memory

from langchain.memory import ConversationBufferWindowMemory
from langchain.memory.vectorstores import VectorStoreRetrieverMemory

class AgentMemory:
    def __init__(self, vectorstore, k=5):
        # Short-term: Son konuşmalar
        self.short_term = ConversationBufferWindowMemory(k=10)

        # Long-term: Vector store
        self.long_term = VectorStoreRetrieverMemory(
            vectorstore=vectorstore,
            k=k,
            index_name="memories"
        )

    def add_interaction(self, input_text: str, output_text: str):
        # Short-term'e ekle
        self.short_term.save_context(
            {"input": input_text},
            {"output": output_text}
        )

        # Long-term'e archive et (önemli bilgileri)
        if self.is_important(input_text, output_text):
            self.long_term.save_context(
                {"input": input_text},
                {"output": output_text}
            )

    def get_context(self, query: str, max_tokens: int = 4000) -> str:
        # Short-term'den son konuşmalar
        recent = self.short_term.load_memory_variables({})["history"]

        # Long-term'den alakalı anılar
        memories = self.long_term.load_memory_variables(
            {"query": query}
        )["history"]

        # Token limitine göre birleştir
        return self.merge_contexts(recent, memories, max_tokens)

Context Compression: Token Optimizasyonu

Context window pahalı. Her request’te gereksiz bilgi göndermemek için:

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

class SmartContextManager:
    def __init__(self, retriever, llm, max_tokens=4000):
        # Compressor: Her retrieved document'u özetle
        self.compressor = LLMChainExtractor(llm=llm)
        self.compression_retriever = ContextualCompressionRetriever(
            base_compressor=self.compressor,
            base_retriever=retriever
        )

    def get_compressed_context(self, query: str) -> list:
        # Önce semantic search
        docs = self.compression_retriever.get_relevant_documents(query)

        # Sonra her doc'u özetle (orijinalin %30-50'i)
        compressed = [self.compressor.compress_documents([doc], query) for doc in docs]

        # Token limitini kontrol et, gerekirse daha az doc döndür
        return self.trim_to_token_limit(compressed, max_tokens)

3. Authentication: Güvenlik Katmanı

Problem Nedir?

Agent’a “tüm müşterilerin e-postalarını çek” dediğinizde, herkes her şeye erişebilir mi? Hayır.

Authentication iki seviyede çalışır:

  1. User Authentication: Kim bu kullanıcı?
  2. Permission System: Bu kullanıcı bu kaynağa erişebilir mi?

Tool-Level Permissions

from enum import Enum
from typing import Callable

class Permission(Enum):
    PUBLIC = "public"           # Herkes kullanabilir
    USER = "user"               # Giriş yapmış kullanıcılar
    ADMIN = "admin"             # Sadece adminler
    SCOPED = "scoped"           # Belirli kaynaklara erişim

class AuthenticatedTool:
    def __init__(self, name: str, permission: Permission, scopes: list = None):
        self.name = name
        self.permission = permission
        self.scopes = scopes or []

    def __call__(self, user: dict, **params):
        # Permission kontrolü
        if not self.check_permission(user):
            raise PermissionError(f"No access to {self.name}")

        # Scope kontrolü (eğer scoped ise)
        if self.permission == Permission.SCOPED:
            self.check_scopes(user, params)

        # Tool'u çalıştır
        return self.execute(**params)

    def check_permission(self, user: dict) -> bool:
        if self.permission == Permission.PUBLIC:
            return True
        if not user.get("authenticated"):
            return False
        if self.permission == Permission.USER:
            return True
        if self.permission == Permission.ADMIN:
            return user.get("role") == "admin"
        return True

MCP Authentication Pattern

Model Context Protocol (MCP) ile tool’ları expose ederken:

# MCP Server - Authentication ile
from mcp.server import Server
from mcp.types import Tool, CallToolResult

app = Server("authenticated-agent")

@app.list_tools()
async def list_tools(user: dict) -> list[Tool]:
    """Kullanıcının erişebildiği tool'ları döndür"""
    all_tools = [
        Tool(name="get_order", description="...", requires_auth=True),
        Tool(name="list_products", description="...", requires_auth=True),
        Tool(name="search_public", description="...", requires_auth=False),
    ]

    # Sadece yetkili tool'ları döndür
    return [t for t in all_tools if self.user_can_access(user, t)]

@app.call_tool()
async def call_tool(name: str, arguments: dict, user: dict) -> CallToolResult:
    # 1. Tool var mı kontrol et
    tool = self.get_tool(name)

    # 2. Yetki kontrolü
    if not self.user_can_access(user, tool):
        return CallToolResult(error="Unauthorized")

    # 3. Audit log
    self.audit_log(user, tool, arguments)

    # 4. Execute
    return await tool.execute(**arguments)

Multi-Tenant Security

Birden fazla müşteri/organizasyon için:

class TenantAwareTool:
    def __init__(self, base_tool: Callable):
        self.base_tool = base_tool

    def execute(self, user: dict, tenant_id: str, **params):
        # Kullanıcının bu tenant'a erişimi var mı?
        if user["tenant_id"] != tenant_id:
            audit_log.warning(f"Cross-tenant access attempt: {user['id']} -> {tenant_id}")
            raise PermissionError("Cross-tenant access denied")

        # Tenant isolation - her query'e tenant_id ekle
        params["tenant_filter"] = tenant_id

        return self.base_tool(**params)

Production’da Birlikte Çalışma

Üç sistem birlikte çalışınca:

class ProductionAgent:
    def __init__(self):
        self.tool_router = ToolRouter(tools=self.get_tools())
        self.memory = AgentMemory(vectorstore=self.get_vectorstore())
        self.auth = AuthManager()

    async def process(self, user: dict, query: str) -> str:
        # 1. Authentication
        if not self.auth.validate_user(user):
            return "Lütfen giriş yapın"

        # 2. Context'i al
        context = self.memory.get_context(query)

        # 3. Tool'ları bul (permission-filtered)
        available_tools = self.auth.filter_accessible_tools(
            user,
            self.tool_router.route(query)
        )

        # 4. LLM'e gönder
        response = await self.llm.chat(
            messages=[{"role": "user", "content": query}],
            tools=available_tools,
            context=context
        )

        # 5. Tool çağrıları varsa çalıştır
        if response.tool_calls:
            for call in response.tool_calls:
                # Permission tekrar kontrol
                if self.auth.can_execute_tool(user, call.name):
                    result = await self.execute_tool(call.name, call.args)
                else:
                    result = "Bu işlem için yetkiniz yok"

            # Tool sonuçlarını memory'ye kaydet
            self.memory.add_interaction(query, response.content)

        return response.content

Sonuç

Üç temel yetenek - tool search, context management, authentication - bir AI agent’ı sadece “sohbet eden” bir sistemden production-ready bir asistan’a dönüştürür.

Tool Search = Doğru araçları seçmek Context Management = Bilgiyi korumak ve erişilebilir kılmak
Authentication = Güvenliği sağlamak

Bu üçünü doğru implement ettiğinizde, agent’ınız hem akıllı hem güvenli hem de verimli çalışır.


AI agent sistemleri ve authentication hakkında detaylı bilgi için ebartan.dev üzerinden iletişime geçebilirsiniz.

Back to Blog

Related Posts

View All Posts »
WhatsApp ile yazin