BiSoft Logo

Hizmetler

Ürünler

Ortaklık

Blog

Turkish

Genel

Production Ortamda OpenAI Agents SDK

SDK'nin tüm kabiliyetleri, tüm provider'lar ve kimsenin size vermediği production playbook'u — aynı agent kodunu OpenAI'dan vLLM'e, NVIDIA Triton'a, Together AI'ya ve Azure AI Foundry'ye nasıl taşıyacağınız dahil.

Ekipler ilk ciddi agentic sistemlerini kurmaya oturduğunda ilginç bir şey olur: Çoğu önce OpenAI Agents SDK'ya yönelir. Tek seçenek olduğu için değil — LangGraph, CrewAI, Autogen ve onlarca alternatif var — ama yolunuzdan çekildiği için. Küçük, type-safe, altyapınız konusunda dayatmasız ve tasarımı gereği provider-agnostic. Bir agent'ı on satırda prototipleyip, aynı kodu kendi GPU'larınızın arkasında production'a alabiliyorsunuz.

Bu rehber, o vaadin uzun versiyonu. SDK'nin tüm temel kabiliyetlerini tek tek geçeceğiz, sonra ikinci yarıyı asıl önemli olan kısma ayıracağız: Production'da çalıştırmak. Yol boyunca pek çok adoption'ın arkasındaki senaryoyu da işleyeceğiz — MVP'yi OpenAI ile yapıp, modeli sonradan kendi donanımınızda bir vLLM veya Triton backend'ine ya da Azure AI Foundry'ye agent'larınızı yeniden yazmadan taşımak.

Bu rehberdeki kod, güncel openai-agents Python paketini hedefler. Kurulum: pip install openai-agents (Python 3.10+).

Bölüm 1 — Bu SDK ilk kararı neden sürekli kazanıyor?

API turuna başlamadan önce, Agents SDK'nin neden bu kadar çok projede varsayılan başlangıç noktası olduğunu netleştirelim.

Uygulamanızı ele geçiren bir framework değil, ince bir orchestration katmanı. İki primitive — Agent ve Runner — turn loop'unu yönetir (modeli çağır, tool'ları çalıştır, handoff'ları takip et, guardrail'leri uygula, session'ı kalıcılaştır). Geri kalan her şey inceleyebileceğiniz, clone'layabileceğiniz, test edebileceğiniz sade Python nesneleridir.

Provider-agnostic. OpenAI Responses API ve Chat Completions API'yi native konuşur; tek satır konfigürasyonla herhangi bir OpenAI-compatible endpoint'e ve adapter'larla 100'den fazla modele bağlanır. Tüm projenin riskini azaltan özellik tam da budur: Model seçiminiz tek yönlü bir kapı değildir.

Type-safe ve küçük. Pydantic tabanlı şemalar, context üzerinde gerçek generic'ler ve dar bir yüzey alanı sayesinde IDE'niz ve type checker'ınız sizin için gerçekten çalışır.

Tracing dahili. İlk run'dan itibaren model çağrılarının, tool çağrılarının, handoff'ların ve guardrail'lerin yapılandırılmış bir trace'ini alırsınız — hem lokalde hem OpenAI Traces dashboard'unda — Logfire, Langfuse, Braintrust, Datadog, W&B, MLflow ve daha fazlası için birinci sınıf entegrasyonlarla.

Production kaygıları sonradan eklenmiş değil, birinci sınıf. Retry'lar, timeout'lar, human-in-the-loop approval'lar, durable execution entegrasyonları (Temporal, Dapr, Restate, DBOS) ve zero-data-retention kontrolleri kutudan çıkar.

Bu beş maddeyi aklınızda tutun — rehberin geri kalanı aslında bunların açılmış halidir.

Bölüm 2 — Core: Agent'lar ve Runner

Bir Agent

Bir Agent; instructions, tools, guardrails, handoffs ve opsiyonel bir structured output type ile yapılandırılmış bir LLM'dir.

from agents import Agent, Runner, function_tool


@function_tool
def get_weather(city: str) -> str:
    """Bir şehir için hava durumunu döndürür."""
    return f"{city} için hava güneşli."


agent = Agent(
    name="Assistant",
    instructions="Kısa ve yardımcı ol.",
    model="gpt-5.5",
    tools=[get_weather],
)

result = Runner.run_sync(agent, "İstanbul'da hava nasıl?")
print(result.final_output)
from agents import Agent, Runner, function_tool


@function_tool
def get_weather(city: str) -> str:
    """Bir şehir için hava durumunu döndürür."""
    return f"{city} için hava güneşli."


agent = Agent(
    name="Assistant",
    instructions="Kısa ve yardımcı ol.",
    model="gpt-5.5",
    tools=[get_weather],
)

result = Runner.run_sync(agent, "İstanbul'da hava nasıl?")
print(result.final_output)
from agents import Agent, Runner, function_tool


@function_tool
def get_weather(city: str) -> str:
    """Bir şehir için hava durumunu döndürür."""
    return f"{city} için hava güneşli."


agent = Agent(
    name="Assistant",
    instructions="Kısa ve yardımcı ol.",
    model="gpt-5.5",
    tools=[get_weather],
)

result = Runner.run_sync(agent, "İstanbul'da hava nasıl?")
print(result.final_output)

Agent loop

Runner.run() çağırdığınızda SDK bir loop çalıştırır:

  • Mevcut agent için, mevcut input ile LLM'i çağır.

  • Çıktıyı incele:

    • Final output ise (tool çağrısı olmayan, istenen tipte metin), dur ve RunResult döndür.

    • Handoff ise, mevcut agent'ı değiştir ve loop'u tekrarla.

    • Tool call'lar varsa, çalıştır, sonuçları ekle ve loop'u tekrarla.

  • Loop max_turns'ü aşarsa MaxTurnsExceeded fırlat (max_turns=None ile devre dışı bırakılır).

Üç giriş noktası vardır:

  • Runner.run(...) — async, RunResult döndürür.

  • Runner.run_sync(...) — senkron wrapper.

  • Runner.run_streamed(...) — async, RunResultStreaming döndürür; model token ve item ürettikçe .stream_events()'i tüketirsiniz.

Bilmeye değer agent konfigürasyonu

instructions sabit bir string ya da bir fonksiyon olabilir (dynamic instructions); fonksiyon context ve agent alır, böylece her run'da kullanıcının adını, locale'ini veya güncel tarihi enjekte edebilirsiniz.

output_type düz metni typed, structured bir çıktıya dönüştürür (Pydantic model, dataclass, TypedDict vb.). Arka planda bu, structured outputs'u devreye sokar.

model_settings; temperature, top_p, tool_choice, parallel_tool_calls ve fazlasını taşır.

tool_use_behavior; tool sonuçlarının modele geri dönüp dönmeyeceğini kontrol eder ("run_llm_again" varsayılan), ilk tool'da durur ("stop_on_first_tool"), belirli tool'larda durur (StopAtTools(...)) veya karar veren özel bir fonksiyon çalıştırır.

clone() bir agent'ı override'larla çoğaltır — A/B varyantları için mükemmel.

from openai.types.shared import Reasoning
from agents import Agent, ModelSettings

research_agent = Agent(
    name="Research agent",
    model="gpt-5.5",
    model_settings=ModelSettings(reasoning=Reasoning(effort="high"), verbosity="low"),
)
from openai.types.shared import Reasoning
from agents import Agent, ModelSettings

research_agent = Agent(
    name="Research agent",
    model="gpt-5.5",
    model_settings=ModelSettings(reasoning=Reasoning(effort="high"), verbosity="low"),
)
from openai.types.shared import Reasoning
from agents import Agent, ModelSettings

research_agent = Agent(
    name="Research agent",
    model="gpt-5.5",
    model_settings=ModelSettings(reasoning=Reasoning(effort="high"), verbosity="low"),
)

Run result: Runner aslında ne döndürür?

Çoğu tutorial'ın atladığı kısım burası; o yüzden net olalım. Runner.run() / run_sync() bir RunResult döndürür; Runner.run_streamed() bir RunResultStreaming döndürür. İkisi de RunResultBase'den miras alır ve her gün kullanacağınız yüzeyleri açar:



Property / helper

Ne tutar

Ne için

final_output

Son agent'ın çıktısı: bir str, output_type instance'ı ya da run bitmeden duraklamışsa None

Kullanıcıya gösterdiğiniz yanıt

new_items

Zengin RunItem wrapper'ları (MessageOutputItem, ReasoningItem, ToolCallItem, ToolCallOutputItem, HandoffCallItem, ToolApprovalItem, …)

Log, UI, audit, debugging

to_input_list()

Tüm run'ın input-item görünümü; sonraki turn'e verilmeye hazır

Manuel conversation loop'ları

last_agent

Run'ı bitiren agent (sonraki turn için genelde doğru olan)

Sonraki user turn'ünü route etmek

last_response_id

En son model response ID'si

previous_response_id ile OpenAI Responses zincirleme

raw_responses

Her model çağrısından gelen ham ModelResponse nesneleri

Provider seviyesi diagnostics

interruptions + to_state()

Bekleyen approval'lar ve resume edilebilir RunState snapshot'ı

Human-in-the-loop

input_guardrail_results / output_guardrail_results / tool_input_guardrail_results / tool_output_guardrail_results

Biriken guardrail kararları

Bir run'ın neden bloklandığını loglamak

context_wrapper

App context'iniz artı SDK runtime metadata'sı — usage dahil

Token tracking, DI, approval'lar

result = await Runner.run(agent, "Bu thread'i özetle.")

print(result.final_output)          # yanıt (str veya sizin output_type'ınız)
print(result.last_agent.name)       # handoff'lardan sonra kim bitirdi
for item in result.new_items:       # run'ın zengin, typed transcript'i
    print(type(item).__name__)
result = await Runner.run(agent, "Bu thread'i özetle.")

print(result.final_output)          # yanıt (str veya sizin output_type'ınız)
print(result.last_agent.name)       # handoff'lardan sonra kim bitirdi
for item in result.new_items:       # run'ın zengin, typed transcript'i
    print(type(item).__name__)
result = await Runner.run(agent, "Bu thread'i özetle.")

print(result.final_output)          # yanıt (str veya sizin output_type'ınız)
print(result.last_agent.name)       # handoff'lardan sonra kim bitirdi
for item in result.new_items:       # run'ın zengin, typed transcript'i
    print(type(item).__name__)

final_output'un tipi Any'dir (handoff'lar hangi agent'ın — ve hangi output_type'ın — bitireceğini değiştirebilir) ve streaming modunda stream_events()'i tüketmeyi bitirene kadar None kalır. RunResultStreaming ek olarak stream_events(), current_agent, is_complete ve cancel() sağlar.

Token tracking ve Usage objesi

Her run otomatik olarak token usage takip eder. Bunu result.context_wrapper.usage'dan okursunuz; bu bir Usage objesidir:

result = await Runner.run(agent, "Tokyo'da hava nasıl?")
usage = result.context_wrapper.usage

print("Requests:     ", usage.requests)        # bu run'daki LLM API çağrısı sayısı
print("Input tokens: ", usage.input_tokens)    # toplam prompt token
print("Output tokens:", usage.output_tokens)   # toplam completion token
print("Total tokens: ", usage.total_tokens)    # input + output

# Subset detayları:
print("Cached input tokens:", usage.input_tokens_details.cached_tokens)
print("Reasoning tokens:    ", usage.output_tokens_details.reasoning_tokens)
result = await Runner.run(agent, "Tokyo'da hava nasıl?")
usage = result.context_wrapper.usage

print("Requests:     ", usage.requests)        # bu run'daki LLM API çağrısı sayısı
print("Input tokens: ", usage.input_tokens)    # toplam prompt token
print("Output tokens:", usage.output_tokens)   # toplam completion token
print("Total tokens: ", usage.total_tokens)    # input + output

# Subset detayları:
print("Cached input tokens:", usage.input_tokens_details.cached_tokens)
print("Reasoning tokens:    ", usage.output_tokens_details.reasoning_tokens)
result = await Runner.run(agent, "Tokyo'da hava nasıl?")
usage = result.context_wrapper.usage

print("Requests:     ", usage.requests)        # bu run'daki LLM API çağrısı sayısı
print("Input tokens: ", usage.input_tokens)    # toplam prompt token
print("Output tokens:", usage.output_tokens)   # toplam completion token
print("Total tokens: ", usage.total_tokens)    # input + output

# Subset detayları:
print("Cached input tokens:", usage.input_tokens_details.cached_tokens)
print("Reasoning tokens:    ", usage.output_tokens_details.reasoning_tokens)

Faturalandırmayı doğru yapmak için üç şey önemli

Usage tüm run boyunca aggregate edilir — tool loop'ları ve handoff'lar tarafından tetiklenenler dahil her model çağrısı. Tek bir Runner.run() üç LLM çağrısı yapıyorsa, usage üçünün toplamını yansıtır.

reasoning_tokens, output_tokens'ın bir subset'idir; ona eklenen bir şey değildir. OpenAI Responses API'de reasoning token'ları output token olarak faturalandırılır; yani zaten output_tokens içinde sayılırlar ve görünürlük için ayrıca output_tokens_details.reasoning_tokens altında sunulurlar. Benzer şekilde input_tokens_details.cached_tokens, input_tokens'ın bir subset'idir (cache'lenmiş prompt prefix'leri, genelde indirimli faturalandırılır). Bu subset alanlarını toplamlara geri eklemeyin, yoksa çift sayarsınız.

Per-request kırılımları request_usage_entries'de yaşar. Aggregate değer tek tek çağrıları gizler; bu liste her request'in token'larını korur ki bu, isabetli per-call maliyet hesabı veya context-window izleme için tam istediğiniz şeydir.

for i, req in enumerate(usage.request_usage_entries, start=1):
    print(f"Request {i}: {req.input_tokens} in / {req.output_tokens} out "
          f"({req.output_tokens_details.reasoning_tokens} reasoning)")
for i, req in enumerate(usage.request_usage_entries, start=1):
    print(f"Request {i}: {req.input_tokens} in / {req.output_tokens} out "
          f"({req.output_tokens_details.reasoning_tokens} reasoning)")
for i, req in enumerate(usage.request_usage_entries, start=1):
    print(f"Request {i}: {req.input_tokens} in / {req.output_tokens} out "
          f"({req.output_tokens_details.reasoning_tokens} reasoning)")

Usage'ı lifecycle hook'ları içinde canlı da okuyabilirsiniz — context.usage, RunHooks / AgentHooks içinde erişilebilir; böylece on_agent_end'de agent başına token harcamasını loglayabilirsiniz:

from agents import RunHooks

class UsageHooks(RunHooks):
    async def on_agent_end(self, context, agent, output):
        u = context.usage
        print(f"{agent.name}: {u.requests} requests, {u.total_tokens} token "
              f"({u.output_tokens_details.reasoning_tokens} reasoning)")
from agents import RunHooks

class UsageHooks(RunHooks):
    async def on_agent_end(self, context, agent, output):
        u = context.usage
        print(f"{agent.name}: {u.requests} requests, {u.total_tokens} token "
              f"({u.output_tokens_details.reasoning_tokens} reasoning)")
from agents import RunHooks

class UsageHooks(RunHooks):
    async def on_agent_end(self, context, agent, output):
        u = context.usage
        print(f"{agent.name}: {u.requests} requests, {u.total_tokens} token "
              f"({u.output_tokens_details.reasoning_tokens} reasoning)")

Session'larda her Runner.run() yalnızca o run'ın usage'ını döndürür — ve session history her turn'de input olarak yeniden beslendiği için input_tokens'ınız turn başına doğal olarak büyür (getirmeyi SessionSettings(limit=...) veya compaction ile sınırlamak için iyi bir sebep). Son olarak bir production tuzağı: third-party adapter'larda (LiteLLM, Any-LLM) bazı provider backend'leri, özellikle streamed Chat Completions backend'lerinde, ModelSettings(include_usage=True) set etmedikçe usage raporlamaz. OpenAI dışı bir provider'da total_tokens 0 dönüyorsa, ilk bakmanız gereken şey bu flag'dir.

Bölüm 3 — Tools: Agent'lar nasıl aksiyon alır?

SDK beş tool kategorisini destekler.

1. Function tools

Herhangi bir Python fonksiyonunu decorate edin. SDK, JSON şemasını imzadan (inspect + Pydantic), açıklamaları ise docstring'den (griffe) çıkarır.

from typing import Annotated
from agents import function_tool


@function_tool
async def fetch_invoice(
    invoice_id: Annotated[str, "Getirilecek fatura ID'si."],
) -> str:
    """ID ile fatura getirir."""
    return await billing_api.get(invoice_id)
from typing import Annotated
from agents import function_tool


@function_tool
async def fetch_invoice(
    invoice_id: Annotated[str, "Getirilecek fatura ID'si."],
) -> str:
    """ID ile fatura getirir."""
    return await billing_api.get(invoice_id)
from typing import Annotated
from agents import function_tool


@function_tool
async def fetch_invoice(
    invoice_id: Annotated[str, "Getirilecek fatura ID'si."],
) -> str:
    """ID ile fatura getirir."""
    return await billing_api.get(invoice_id)

Function tool'ların zengin bir production yüzeyi vardır

Timeout

@function_tool(timeout=2.0); timeout_behavior="error_as_result" (varsayılan, modele görünür mesaj döner) veya "raise_exception" (ToolTimeoutError fırlatır).

Error handling

failure_error_function=... ile crash anında modele giden mesajı kontrol edin, ya da None ile yeniden fırlatın.

Validation

JSON şemasına yansıyan kısıtlar için Pydantic Field(..., ge=0, le=100).

Zengin dönüş tipleri

Metin, görsel (ToolOutputImage) veya dosya (ToolOutputFileContent).

2. Hosted tools (OpenAI Responses)

Model ile birlikte OpenAI sunucularında çalışır: WebSearchTool, FileSearchTool (kendi vector store'larınız), CodeInterpreterTool, ImageGenerationTool, HostedMCPTool ve ToolSearchTool (büyük tool yüzeyleri için deferred loading).

from agents import Agent, WebSearchTool, FileSearchTool

agent = Agent(
    name="Researcher",
    tools=[
        WebSearchTool(),
        FileSearchTool(max_num_results=3, vector_store_ids=["vs_..."]),
    ],
)
from agents import Agent, WebSearchTool, FileSearchTool

agent = Agent(
    name="Researcher",
    tools=[
        WebSearchTool(),
        FileSearchTool(max_num_results=3, vector_store_ids=["vs_..."]),
    ],
)
from agents import Agent, WebSearchTool, FileSearchTool

agent = Agent(
    name="Researcher",
    tools=[
        WebSearchTool(),
        FileSearchTool(max_num_results=3, vector_store_ids=["vs_..."]),
    ],
)

Hosted tool'lar OpenAI Responses modelleri gerektirir. Chat Completions'ta veya OpenAI dışı backend'lerde kullanılamaz.

3. Local / runtime execution tools

ComputerTool (sizin implemente ettiğiniz bir Computer üzerinde GUI/browser otomasyonu), ShellTool (lokal veya hosted-container execution) ve ApplyPatchTool (editörünüz üzerinden diff uygulama). Bunlar bir agent'ın gerçek bir ortamı işletmesini sağlar.

4. Agents as tools

Bir agent'ı, kontrolü devretmeden çağrılabilir bir tool olarak sunar — manager pattern. Orchestrator konuşmayı elinde tutar ve uzman agent'ları fonksiyon gibi çağırır.

orchestrator = Agent(
    name="Orchestrator",
    tools=[
        spanish_agent.as_tool(tool_name="to_spanish", tool_description="İspanyolca'ya çevir"),
        french_agent.as_tool(tool_name="to_french", tool_description="Fransızca'ya çevir"),
    ],
)
orchestrator = Agent(
    name="Orchestrator",
    tools=[
        spanish_agent.as_tool(tool_name="to_spanish", tool_description="İspanyolca'ya çevir"),
        french_agent.as_tool(tool_name="to_french", tool_description="Fransızca'ya çevir"),
    ],
)
orchestrator = Agent(
    name="Orchestrator",
    tools=[
        spanish_agent.as_tool(tool_name="to_spanish", tool_description="İspanyolca'ya çevir"),
        french_agent.as_tool(tool_name="to_french", tool_description="Fransızca'ya çevir"),
    ],
)

as_tool(); structured input (parameters=), output extraction (custom_output_extractor=), streaming (on_stream=), koşullu etkinleştirme (is_enabled=) ve approval gate (needs_approval=) destekler.

5. MCP (Model Context Protocol)

MCP, "AI tool'ları için USB-C"dir. SDK dört entegrasyon stilini destekler:

Hosted MCP

HostedMCPTool ile Hosted MCP — OpenAI'nin Responses API'si sizin yerinize public bir MCP server çağırır.

Streamable HTTP

MCPServerStreamableHttp ile Streamable HTTP — server'ı siz çalıştırır/yönetirsiniz.

HTTP+SSE

MCPServerSse ile HTTP+SSE — legacy transport.

stdio

MCPServerStdio ile stdio — lokal bir subprocess başlatır.

MCP server'ları; tool filtering (statik allow/block listeleri veya dinamik callable'lar), list_tools() caching, per-call _meta enjeksiyonu, approval politikaları ve prompt'lar destekler. Birden çok server'ı önceden bağlamak ve reconnect yönetimi için MCPServerManager kullanın.

Bölüm 4 — Multi-agent tasarım: handoff'lar vs. manager pattern

Geniş ölçüde uygulanabilir iki mimari vardır ve SDK ikisini de native destekler.

Handoff'lar

Handoff'lar merkezi değildir: bir peer agent konuşmayı bir uzmana devreder, uzman da kontrolü alır. Handoff'lar modele tool olarak sunulur (transfer_to_<agent_name>).

from agents import Agent, handoff

billing = Agent(name="Billing agent")
refund = Agent(name="Refund agent")

triage = Agent(
    name="Triage agent",
    instructions="Faturalama sorularını billing'e, iadeleri refund'a yönlendir.",
    handoffs=[billing, handoff(refund)],
)
from agents import Agent, handoff

billing = Agent(name="Billing agent")
refund = Agent(name="Refund agent")

triage = Agent(
    name="Triage agent",
    instructions="Faturalama sorularını billing'e, iadeleri refund'a yönlendir.",
    handoffs=[billing, handoff(refund)],
)
from agents import Agent, handoff

billing = Agent(name="Billing agent")
refund = Agent(name="Refund agent")

triage = Agent(
    name="Triage agent",
    instructions="Faturalama sorularını billing'e, iadeleri refund'a yönlendir.",
    handoffs=[billing, handoff(refund)],
)

handoff(); tool adını ve açıklamasını özelleştirmenize, bir on_handoff callback'i eklemenize, structured input_type metadata'sı (ör. bir reason) zorunlu kılmanıza, bir sonraki agent'ın göreceği geçmişi input_filter ile filtrelemenize ve is_enabled ile dinamik açıp kapatmanıza izin verir. Ayrıca önceki transcript'i tek bir özet mesaja indirgeyen, opt-in bir beta olan nest_handoff_history da vardır.

Manager pattern

Manager pattern (yukarıdaki agents-as-tools) merkezidir: orchestrator kontrolü hiç bırakmaz. Bir uzman konuşmanın geri kalanına sahip olacaksa handoff kullanın; birden çok uzmanı kompoze edip çıktılarını sentezlemeniz gerekiyorsa manager pattern kullanın.

Daha iyi routing için instructions'ınızın başına RECOMMENDED_PROMPT_PREFIX'i (agents.extensions.handoff_prompt'tan) ekleyin.

Bölüm 5 — Guardrails: pahalı modelleri koruyan ucuz kontroller

Guardrail'ler, agent'ınızla paralel olarak ya da ondan önce validasyon çalıştırır ve bir tripwire ile execution'ı durdurabilir.

Input guardrails

Input guardrails ilk agent'ın input'unda çalışır. run_in_parallel=True (en düşük latency, varsayılan) veya run_in_parallel=False (blocking — tripwire tetiklenirse agent hiç başlamaz, bu da token tasarrufu sağlar ve yan etkileri önler) destekler.

Output guardrails

Output guardrails son agent'ın final output'unda çalışır.

Tool guardrails

Tool guardrails tek tek function tool'ları sarar — execution öncesi input guardrail'leri (atlayabilir, çıktıyı değiştirebilir veya tetikleyebilir), sonrası ise output guardrail'leri.

from pydantic import BaseModel
from agents import Agent, GuardrailFunctionOutput, Runner, input_guardrail


class Check(BaseModel):
    is_abuse: bool


guard_agent = Agent(name="Guard", output_type=Check, model="gpt-5-nano")


@input_guardrail
async def abuse_guard(ctx, agent, user_input) -> GuardrailFunctionOutput:
    result = await Runner.run(guard_agent, user_input, context=ctx.context)
    return GuardrailFunctionOutput(
        output_info=result.final_output,
        tripwire_triggered=result.final_output.is_abuse,
    )
from pydantic import BaseModel
from agents import Agent, GuardrailFunctionOutput, Runner, input_guardrail


class Check(BaseModel):
    is_abuse: bool


guard_agent = Agent(name="Guard", output_type=Check, model="gpt-5-nano")


@input_guardrail
async def abuse_guard(ctx, agent, user_input) -> GuardrailFunctionOutput:
    result = await Runner.run(guard_agent, user_input, context=ctx.context)
    return GuardrailFunctionOutput(
        output_info=result.final_output,
        tripwire_triggered=result.final_output.is_abuse,
    )
from pydantic import BaseModel
from agents import Agent, GuardrailFunctionOutput, Runner, input_guardrail


class Check(BaseModel):
    is_abuse: bool


guard_agent = Agent(name="Guard", output_type=Check, model="gpt-5-nano")


@input_guardrail
async def abuse_guard(ctx, agent, user_input) -> GuardrailFunctionOutput:
    result = await Runner.run(guard_agent, user_input, context=ctx.context)
    return GuardrailFunctionOutput(
        output_info=result.final_output,
        tripwire_triggered=result.final_output.is_abuse,
    )

Bir tripwire tetiklendiğinde SDK InputGuardrailTripwireTriggered / OutputGuardrailTripwireTriggered fırlatır; siz bunu yakalayıp zarif bir yanıta dönüştürürsünüz.

Klasik pattern

Hızlı, ucuz bir model (gpt-5-nano) input'u, yavaş ve pahalı modeliniz hiç çalışmadan önce eler.

Bölüm 6 — Bellek: sessions, context ve conversation state

Turn'ler arasında state taşımanın dört yolu vardır ve doğru seçim bir production kararıdır:



Strateji

State nerede yaşar

En uygun olduğu yer

result.to_input_list()

Uygulama belleğiniz

Manuel kontrol, her provider

session=

Deponuz + SDK

Kalıcı, resume edilebilir sohbet

conversation_id

OpenAI Conversations API

Server-side, servisler arası paylaşımlı

previous_response_id

OpenAI Responses API

Hafif, server-managed zincirleme

Son ikisi OpenAI tarafından yönetilir ve yalnızca Responses API için geçerlidir. Her konuşma için tek bir strateji seçin — client-managed history ile server-managed state'i karıştırmak context'i tekrarlar.

Sessions

Session'lar, SDK'nin her run'dan önce geçmişi getirmesini ve sonrasında yeni item'ları kalıcılaştırmasını sağlar. Backend'ler: SQLiteSession (memory veya dosya), AsyncSQLiteSession, RedisSession, SQLAlchemySession, MongoDBSession, DaprSession, OpenAIConversationsSession, AdvancedSQLiteSession (branching + analytics), EncryptedSession (şeffaf şifreleme + TTL) ve OpenAIResponsesCompactionSession (çok uzun sohbetler için auto-compaction).

from agents import Agent, Runner, SQLiteSession

agent = Agent(name="Assistant", instructions="Kısa yanıtla.")
session = SQLiteSession("user_123", "conversations.db")

await Runner.run(agent, "Golden Gate Köprüsü hangi şehirde?", session=session)
await Runner.run(agent, "Hangi eyalette?", session=session)  # context'i hatırlar
from agents import Agent, Runner, SQLiteSession

agent = Agent(name="Assistant", instructions="Kısa yanıtla.")
session = SQLiteSession("user_123", "conversations.db")

await Runner.run(agent, "Golden Gate Köprüsü hangi şehirde?", session=session)
await Runner.run(agent, "Hangi eyalette?", session=session)  # context'i hatırlar
from agents import Agent, Runner, SQLiteSession

agent = Agent(name="Assistant", instructions="Kısa yanıtla.")
session = SQLiteSession("user_123", "conversations.db")

await Runner.run(agent, "Golden Gate Köprüsü hangi şehirde?", session=session)
await Runner.run(agent, "Hangi eyalette?", session=session)  # context'i hatırlar

Getirmeyi SessionSettings(limit=N) ile kontrol edebilir, history/yeni-input birleşimini RunConfig.session_input_callback ile özelleştirebilir ve Session protokolünü takip ederek kendi backend'inizi yazabilirsiniz.

Local context (dependency injection)

RunContextWrapper[T], lokal bir nesneyi — user ID'niz, izinler, DB handle'ları, logger — her tool'a, hook'a ve guardrail'e taşır. Asla LLM'e gönderilmez. Ayrıca toplam usage'ı ve as_tool() run'ları içinde tool_input'u açar.

from dataclasses import dataclass
from agents import Agent, RunContextWrapper, function_tool


@dataclass
class UserInfo:
    name: str
    uid: int


@function_tool
async def greet(ctx: RunContextWrapper[UserInfo]) -> str:
    return f"Merhaba, {ctx.context.name}"


agent = Agent[UserInfo](name="Assistant", tools=[greet])
from dataclasses import dataclass
from agents import Agent, RunContextWrapper, function_tool


@dataclass
class UserInfo:
    name: str
    uid: int


@function_tool
async def greet(ctx: RunContextWrapper[UserInfo]) -> str:
    return f"Merhaba, {ctx.context.name}"


agent = Agent[UserInfo](name="Assistant", tools=[greet])
from dataclasses import dataclass
from agents import Agent, RunContextWrapper, function_tool


@dataclass
class UserInfo:
    name: str
    uid: int


@function_tool
async def greet(ctx: RunContextWrapper[UserInfo]) -> str:
    return f"Merhaba, {ctx.context.name}"


agent = Agent[UserInfo](name="Assistant", tools=[greet])

Human-in-the-loop veya durable job'lar için RunState'i serialize ederseniz, context onunla birlikte taşınır — içine asla secret koymayın.

Bölüm 7 — Tracing ve observability

Tracing varsayılan olarak açıktır. Her Runner.run() bir trace ile sarılır; her agent run'ı, LLM generation'ı, tool call'ı, guardrail'i ve handoff'u bir span olur.

from agents import Runner, trace

with trace("Customer support", group_id=thread_id):
    first = await Runner.run(agent, "Merhaba")
    second = await Runner.run(agent, "Devam sorusu")
from agents import Runner, trace

with trace("Customer support", group_id=thread_id):
    first = await Runner.run(agent, "Merhaba")
    second = await Runner.run(agent, "Devam sorusu")
from agents import Runner, trace

with trace("Customer support", group_id=thread_id):
    first = await Runner.run(agent, "Merhaba")
    second = await Runner.run(agent, "Devam sorusu")

Production ayar düğmeleri

İsimlendirme ve correlation

RunConfig(workflow_name=..., trace_id=..., group_id=..., trace_metadata=...)

Sensitive data'yı hariç tutma

RunConfig(trace_include_sensitive_data=False) (veya OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATA=0)

Trace'leri anında export etme

flush_traces() ile process'in zamanında flush edemeyebileceği worker'larda (Celery, RQ, FastAPI background task) anlık export'u zorlayın.

Trace processor'ları

Trace'leri ayrıca başka bir yere göndermek için add_trace_processor(), varsayılan exporter'ı değiştirmek için set_trace_processors() kullanın.

Ekosistem geniş: Logfire, Langfuse, Braintrust, Datadog, W&B Weave, MLflow, Arize-Phoenix, LangSmith, Comet Opik, AgentOps ve daha fazlası SDK'nin tracing yüzeyini kutudan destekler.

Zero Data Retention (ZDR) politikası altında OpenAI tracing kullanılamaz — devre dışı bırakın veya custom bir processor kullanın.

Bölüm 8 — Models ve provider'lar: projenizi geleceğe taşıyan kısım

SDK'nin "tek yönlü kapı yok" felsefesinin kalbi burası.

İki OpenAI model şekli vardır

OpenAIResponsesModel (önerilen)

Responses API. Hosted tools ve tool search için zorunludur.

OpenAIChatCompletionsModel

Chat Completions API. Neredeyse her provider'ın desteklediği en düşük ortak payda.

SDK'yi api.openai.com dışında bir yere yöneltmenin dört yolu vardır



Yaklaşım

Kapsam

Ne zaman

set_default_openai_client(AsyncOpenAI(base_url=..., api_key=...))

Global default

Çoğu/tüm agent için tek bir compatible endpoint

ModelProvider + RunConfig(model_provider=...)

Run başına

Tek bir run için özel provider

Agent(model=OpenAIChatCompletionsModel(...))

Agent başına

Farklı agent, farklı provider

Third-party adapter (LiteLLM / Any-LLM)

Model başına

Adapter-managed kapsama/routing

Artı global anahtarlar: set_default_openai_api("chat_completions"), set_default_openai_key(...) ve OPENAI_BASE_URL / OPENAI_API_KEY environment değişkenleri.

Global client yaklaşımı (en çok kullanacağınız)

from openai import AsyncOpenAI
from agents import set_default_openai_client, set_default_openai_api, set_tracing_disabled

client = AsyncOpenAI(base_url="https://your-endpoint/v1", api_key="...")
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")  # çoğu OpenAI-dışı backend Responses'ı desteklemez
set_tracing_disabled(True)                  # veya ücretsiz OpenAI trace için set_tracing_export_api_key(...)
from openai import AsyncOpenAI
from agents import set_default_openai_client, set_default_openai_api, set_tracing_disabled

client = AsyncOpenAI(base_url="https://your-endpoint/v1", api_key="...")
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")  # çoğu OpenAI-dışı backend Responses'ı desteklemez
set_tracing_disabled(True)                  # veya ücretsiz OpenAI trace için set_tracing_export_api_key(...)
from openai import AsyncOpenAI
from agents import set_default_openai_client, set_default_openai_api, set_tracing_disabled

client = AsyncOpenAI(base_url="https://your-endpoint/v1", api_key="...")
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")  # çoğu OpenAI-dışı backend Responses'ı desteklemez
set_tracing_disabled(True)                  # veya ücretsiz OpenAI trace için set_tracing_export_api_key(...)

Hepsi bu kadar. Agent'larınız, tool'larınız, handoff'larınız ve guardrail'leriniz hiç değişmiyor.

Bölüm 9 — Production senaryosu, baştan sona: OpenAI → vLLM/Triton → Together AI → Azure

Çoğu adoption'ı tetikleyen yolculuk bu; o yüzden somutlaştıralım.

Aşama 1 — OpenAI ile MVP

Hızlı başlarsınız. OPENAI_API_KEY'i set edin, gpt-5.5'i seçin, yayına alın. Responses API, hosted tools, tam tracing — her şey çalışır.

Aşama 2 — Modeli kendi GPU'larınıza taşıyın (vLLM)

Maliyet, latency, veri ikametgâhı (data residency) veya compliance sizi modeli kendiniz host etmeye iter. Diyelim ki Llama veya Qwen'i, OpenAI-compatible bir /v1 endpoint'i sunan vLLM ile serve ediyorsunuz:

vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000
vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000
vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000

Şimdi SDK'yı oraya yöneltirsiniz — başka hiçbir şey değişmez:

from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client, set_default_openai_api, set_tracing_disabled

client = AsyncOpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")
set_tracing_disabled(True)

agent = Agent(name="Assistant", model="meta-llama/Llama-3.1-8B-Instruct")
print((await Runner.run(agent, "Merhaba")).final_output)
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client, set_default_openai_api, set_tracing_disabled

client = AsyncOpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")
set_tracing_disabled(True)

agent = Agent(name="Assistant", model="meta-llama/Llama-3.1-8B-Instruct")
print((await Runner.run(agent, "Merhaba")).final_output)
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client, set_default_openai_api, set_tracing_disabled

client = AsyncOpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")
set_tracing_disabled(True)

agent = Agent(name="Assistant", model="meta-llama/Llama-3.1-8B-Instruct")
print((await Runner.run(agent, "Merhaba")).final_output)

Aşama 3 — Serving katmanını NVIDIA Triton (vLLM backend) ile ölçekleyin

Trafik büyüdükçe batching, multi-model hosting ve GPU scheduling için NVIDIA Triton Inference Server'a, vLLM backend'iyle geçersiniz. Triton, OpenAI-compatible bir gateway arkasında durabilir; dolayısıyla SDK'nin perspektifinden hâlâ sadece bir base_url:

client = AsyncOpenAI(base_url="http://triton-gateway:9000/v1", api_key="EMPTY")
set_default_openai_client(client, use_for_tracing=False)
client = AsyncOpenAI(base_url="http://triton-gateway:9000/v1", api_key="EMPTY")
set_default_openai_client(client, use_for_tracing=False)
client = AsyncOpenAI(base_url="http://triton-gateway:9000/v1", api_key="EMPTY")
set_default_openai_client(client, use_for_tracing=False)

Aşama 1'de yazılan agent kodu, siz yazdığınızda var olmayan bir altyapıda değişmeden çalışır. Bütün mesele bu.

Alternatif — managed bir open-model provider (Together AI)

Hiç GPU çalıştırmak istemiyor musunuz? Together AI (ve OpenRouter, Fireworks, Groq vb.) OpenAI-compatible endpoint'ler sunar:

import os
client = AsyncOpenAI(base_url="https://api.together.xyz/v1", api_key=os.environ["TOGETHER_API_KEY"])
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")
import os
client = AsyncOpenAI(base_url="https://api.together.xyz/v1", api_key=os.environ["TOGETHER_API_KEY"])
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")
import os
client = AsyncOpenAI(base_url="https://api.together.xyz/v1", api_key=os.environ["TOGETHER_API_KEY"])
set_default_openai_client(client, use_for_tracing=False)
set_default_openai_api("chat_completions")

Azure OpenAI / Azure AI Foundry

Azure üzerindeki kurumlar özel bir client kullanır: AsyncAzureOpenAI. Temel fark: Azure'da bir model adını değil, bir deployment adını referans alırsınız.

from openai import AsyncAzureOpenAI
from agents import Agent, set_default_openai_client, set_default_openai_api

azure_client = AsyncAzureOpenAI(
    api_key="...",
    azure_endpoint="https://your-resource.openai.azure.com/",
    api_version="2024-10-21",
)
set_default_openai_client(azure_client, use_for_tracing=False)
set_default_openai_api("chat_completions")

# `model`, Azure *deployment* adıdır.
agent = Agent(name="Assistant", model="gpt-4o")
from openai import AsyncAzureOpenAI
from agents import Agent, set_default_openai_client, set_default_openai_api

azure_client = AsyncAzureOpenAI(
    api_key="...",
    azure_endpoint="https://your-resource.openai.azure.com/",
    api_version="2024-10-21",
)
set_default_openai_client(azure_client, use_for_tracing=False)
set_default_openai_api("chat_completions")

# `model`, Azure *deployment* adıdır.
agent = Agent(name="Assistant", model="gpt-4o")
from openai import AsyncAzureOpenAI
from agents import Agent, set_default_openai_client, set_default_openai_api

azure_client = AsyncAzureOpenAI(
    api_key="...",
    azure_endpoint="https://your-resource.openai.azure.com/",
    api_version="2024-10-21",
)
set_default_openai_client(azure_client, use_for_tracing=False)
set_default_openai_api("chat_completions")

# `model`, Azure *deployment* adıdır.
agent = Agent(name="Assistant", model="gpt-4o")

Azure AI Foundry, bir model kataloğunu (OpenAI ve open modeller) aynı şekilde sunar; daha geniş Foundry kapsama veya routing gerektiğinde LiteLLM'i (azure/..., azure_ai/... model string'leri) devreye sokun.

Tek workflow'da provider karıştırma

Triage için küçük/hızlı bir model, zor görevler için büyük bir model bile çalıştırabilirsiniz — model'i agent başına set ederek ya da prefix'leri MultiProvider ile route ederek (openai/..., litellm/..., any-llm/...). Yalnızca şunu unutmayın: feature desteği provider'lar arasında farklıdır (structured outputs, multimodal input, hosted tools); o yüzden yayına aldığınız tam backend'i doğrulayın.

Third-party adapter'lar (LiteLLM / Any-LLM)

Dahili yollar yetmediğinde — 100+ provider için adapter-managed kapsama ya da spesifik routing gerektiğinde — openai-agents[litellm] veya openai-agents[any-llm] kurun ve litellm/... ya da any-llm/... model adlarını kullanın (veya doğrudan LitellmModel / AnyLLMModel). Bazı adapter backend'lerinin token usage raporlamak için ModelSettings(include_usage=True) gerektirdiğini not edin.

Bölüm 10 — Production playbook'u

Kabiliyetler kolaydır; onları güvenilir şekilde çalıştırmak asıl iştir. Bir demo'yu bir servisten ayıran checklist şu:

Retry'lar — açık ve opt-in

SDK genel model çağrılarını siz istemedikçe retry etmez. ModelSettings(retry=...) ile opt-in yapın:

from agents import Agent, ModelRetrySettings, ModelSettings, retry_policies

agent = Agent(
    name="Assistant",
    model="gpt-5.5",
    model_settings=ModelSettings(
        retry=ModelRetrySettings(
            max_retries=4,
            backoff={"initial_delay": 0.5, "max_delay": 5.0, "multiplier": 2.0, "jitter": True},
            policy=retry_policies.any(
                retry_policies.provider_suggested(),
                retry_policies.retry_after(),
                retry_policies.network_error(),
                retry_policies.http_status([408, 429, 500, 502, 503, 504]),
            ),
        )
    ),
)
from agents import Agent, ModelRetrySettings, ModelSettings, retry_policies

agent = Agent(
    name="Assistant",
    model="gpt-5.5",
    model_settings=ModelSettings(
        retry=ModelRetrySettings(
            max_retries=4,
            backoff={"initial_delay": 0.5, "max_delay": 5.0, "multiplier": 2.0, "jitter": True},
            policy=retry_policies.any(
                retry_policies.provider_suggested(),
                retry_policies.retry_after(),
                retry_policies.network_error(),
                retry_policies.http_status([408, 429, 500, 502, 503, 504]),
            ),
        )
    ),
)
from agents import Agent, ModelRetrySettings, ModelSettings, retry_policies

agent = Agent(
    name="Assistant",
    model="gpt-5.5",
    model_settings=ModelSettings(
        retry=ModelRetrySettings(
            max_retries=4,
            backoff={"initial_delay": 0.5, "max_delay": 5.0, "multiplier": 2.0, "jitter": True},
            policy=retry_policies.any(
                retry_policies.provider_suggested(),
                retry_policies.retry_after(),
                retry_policies.network_error(),
                retry_policies.http_status([408, 429, 500, 502, 503, 504]),
            ),
        )
    ),
)

provider_suggested() ile başlayın — provider veto'larını ve replay-safety onaylarını korur ki bu, stateful previous_response_id / conversation_id follow-up'larında önemlidir.

Timeout'lar ve tool failure izolasyonu

Dış çağrı yapan her tool'a bir timeout verin ve timeout'un toparlaması mı (error_as_result) yoksa run'ı düşürmesi mi (raise_exception) gerektiğine karar verin. Flaky bir API'nin turn'ü çökertmek yerine modele temiz bir mesaj döndürmesi için failure_error_function kullanın.

Loop'u sınırlamak

Production'da daima bir max_turns set edin ve kontrolden çıkan bir agent'ın exception fırlatmak yerine kontrollü bir mesaj döndürmesi için error_handlers={"max_turns": ...} fallback'i sağlayın. Aynı mekanizma "model_refusal"'ı da yönetir.

Human-in-the-loop (HITL)

Hassas tool'ları needs_approval=True (veya per-call bir callable) ile işaretleyin. Model böyle bir tool'u çağırdığında run duraklar ve result.interruptions'ı yüzeye çıkarır.

result.to_state()state.to_json() ile serialize edin, bir queue veya DB'ye koyun, sonra RunState.from_json(...), state.approve(...) / state.reject(...) ve Runner.run(agent, state) ile resume edin. Bu, handoff'lar ve nested as_tool() çağrıları boyunca çalışır ve process restart'larından sağ çıkar — durable approval'ların temeli.

Durable execution

Uzun bekleyişler, retry'lar veya restart'lar boyunca süren workflow'lar için SDK; Temporal, Dapr, Restate ve DBOS ile entegre olur. Bunlar runner'ı sararak ilerlemenin failure'lardan sağ çıkmasını sağlar — saatlerce bekleyebilecek HITL approval'ları için zorunludur.

Güvenlik ve veri yönetişimi

  • OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1 ve OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1 prompt'ları/output'ları loglardan uzak tutar (varsayılan açık).

  • trace_include_sensitive_data=False onları trace'lerden uzak tutar.

  • RunState'i serialize ediyorsanız RunContextWrapper.context içine secret koymayın.

  • Conversation history'yi at-rest şifrelemek için TTL'li EncryptedSession kullanın.

  • Tool guardrail'leri tool execution'ından önce ve sonra secret'ları (API key, PII) redact edebilir.

Concurrency ve maliyet kontrolü

  • ModelSettings(parallel_tool_calls=...) modelin birden çok tool call üretip üretemeyeceğini; RunConfig(tool_execution=ToolExecutionConfig(max_function_tool_concurrency=N)) ise SDK'nin aynı anda kaçını çalıştıracağını kontrol eder.

  • Pahalı model çalışmadan harcamayı durdurmak için blocking input guardrail'leri (run_in_parallel=False) kullanın.

  • Uzun context'lerde truncation="auto", server-side context_management compaction veya OpenAIResponsesCompactionSession'a yaslanın.

  • prompt_cache_retention="24h", cache'lenmiş prefix'leri sıcak tutarak maliyeti ve latency'yi düşürür.

Observability disiplini

Her workflow'u isimlendirin (workflow_name), çoklu-run konuşmaları group_id ile ilişkilendirin, trace_metadata ekleyin ve background worker'larda flush_traces() çağırın. Birinci günden gerçek bir backend (Langfuse/Datadog/Logfire) bağlayın — agent'ları kör debug etmek bu alandaki en pahalı hatadır.

Streaming ve latency

Akıcı UI'lar için Runner.run_streamed() kullanın ve ham metin delta'larını (ResponseTextDeltaEvent) iletin. OpenAI Responses'ta websocket transport'a opt-in yapabilir (set_default_openai_responses_transport("websocket")) ve responses_websocket_session() ile turn'ler arasında bağlantıyı yeniden kullanabilirsiniz.

Bölüm 11 — Kopyalayabileceğiniz bir referans mimari

Tüm bunları somutlaştırmak için, eşlik eden agent-boilerplate projesi yukarıdaki pattern'leri plug-and-play bir başlangıç noktasına paketler:

agent-boilerplate/
├── app/
├── config.py            # Typed settings (.env -> Settings)
├── server.py            # FastAPI: /chat ve /chat/stream (SSE)
├── cli.py               # İnteraktif terminal demosu
└── ai/                  # YZ ile ilgili her şey burada
├── provider.py      # set_default_openai_client: OpenAI / Azure / compatible
├── agents.py        # Triage agent + uzmanlara handoff'lar
├── tools.py         # @function_tool tanımları
├── guardrails.py    # Input guardrail (relevance check)
├── sessions.py      # Session fabrikası (memory/sqlite/redis)
├── context.py       # Local DI context
├── service.py       # Error handling'li ince Runner wrapper
└── instructions/    # System prompt'lar versiyonlanmış .md dosyaları olarak
agent-boilerplate/
├── app/
├── config.py            # Typed settings (.env -> Settings)
├── server.py            # FastAPI: /chat ve /chat/stream (SSE)
├── cli.py               # İnteraktif terminal demosu
└── ai/                  # YZ ile ilgili her şey burada
├── provider.py      # set_default_openai_client: OpenAI / Azure / compatible
├── agents.py        # Triage agent + uzmanlara handoff'lar
├── tools.py         # @function_tool tanımları
├── guardrails.py    # Input guardrail (relevance check)
├── sessions.py      # Session fabrikası (memory/sqlite/redis)
├── context.py       # Local DI context
├── service.py       # Error handling'li ince Runner wrapper
└── instructions/    # System prompt'lar versiyonlanmış .md dosyaları olarak
agent-boilerplate/
├── app/
├── config.py            # Typed settings (.env -> Settings)
├── server.py            # FastAPI: /chat ve /chat/stream (SSE)
├── cli.py               # İnteraktif terminal demosu
└── ai/                  # YZ ile ilgili her şey burada
├── provider.py      # set_default_openai_client: OpenAI / Azure / compatible
├── agents.py        # Triage agent + uzmanlara handoff'lar
├── tools.py         # @function_tool tanımları
├── guardrails.py    # Input guardrail (relevance check)
├── sessions.py      # Session fabrikası (memory/sqlite/redis)
├── context.py       # Local DI context
├── service.py       # Error handling'li ince Runner wrapper
└── instructions/    # System prompt'lar versiyonlanmış .md dosyaları olarak

En kritik dosya provider.py'dir.

Bölüm 9'daki migration hikâyesini birebir implemente eder: tek bir fonksiyon MODEL_PROVIDER'ı okur ve global client'ı OpenAI, Azure veya herhangi bir compatible backend için yapılandırır. Tek bir environment değişkenini çevirin; aynı agent'lar gpt-5.5 üzerinde, bir vLLM kutusunda, Triton arkasında, Together AI'da veya Azure AI Foundry'de — sıfır kod değişikliğiyle — çalışır.

Bu özellik — modelin bir mimari taahhüt değil, bir deployment detayı olması — bu kadar çok ekibin neden önce OpenAI Agents SDK'ya yöneldiğini ve MVP'leri bir platforma dönüştüğünde neden hâlâ onu kullandıklarını açıklar.

Kapanış

OpenAI Agents SDK, varsayılan-seçim statüsünü kapsamı konusunda dürüst olarak hak ediyor: agent'ları orchestrate eder ve sizi bir modele, bir provider'a veya bir altyapıya kilitlemeyi reddeder.

Beş primitive'i — agents, tools, handoffs, guardrails, sessions — öğrenin, tracing ve provider konfigürasyonunu bağlayın, sonra retry'lar, timeout'lar, HITL ve veri yönetişiminden oluşan production playbook'unu üzerine ekleyin.

Bunu yaparsanız, "etkileyici demo" ile "gece 3'te çalıştırabileceğiniz servis" arasındaki uçurum büyük ölçüde kapanır.

OpenAI ile başlayın.

Mantıklı olduğunda kendi GPU'larınıza geçin.

Agent'larınızı olduğu gibi bırakın.

Vaat bu — ve bu rehberin gösterdiği gibi, SDK'nin gerçekten tuttuğu bir vaat.

250'den fazla müşterimize katılın

İster uzman danışmanlık, ister özel yazılım, ister kapsamlı veri çözümleri arıyor olun, BiSoft yanınızda. Hedeflerinize nasıl katkı sağlayabileceğimizi konuşalım.

250'den fazla müşterimize katılın

İster uzman danışmanlık, ister özel yazılım, ister kapsamlı veri çözümleri arıyor olun, BiSoft yanınızda. Hedeflerinize nasıl katkı sağlayabileceğimizi konuşalım.

250'den fazla müşterimize katılın

İster uzman danışmanlık, ister özel yazılım, ister kapsamlı veri çözümleri arıyor olun, BiSoft yanınızda. Hedeflerinize nasıl katkı sağlayabileceğimizi konuşalım.

İş büyümesi ve verimliliği için akıllı veri çözümleri

Şirket

Hizmetler

Ürün

Vispeahen

BFM

BFM4Patroni

Daha fazla içerik