Çerez kullanıyoruz. Çerezler ve tarayıcı depolaması oturumunu açık tutar ve tercihlerini hatırlar. İzin verirsen sitenin nasıl kullanıldığını da ölçeriz. İstediğin zaman . Ayrıntılar için çerez politikamıza bak.

Rehber: araç çağıran ajanlar

Başlarken

Rehber: araç çağıran ajanlar

Adım sınırı, paralel araç çalıştırma, yapılandırılmış nihai yanıt ve maliyet kontrolleriyle küçük bir tool-calling ajanı kurun; Python ve Node örnekleriyle.

Ajan bir döngüdür: model konuşmayı okur, araçlarınızdan birini veya birkaçını çağırmaya karar verir, siz bunları çalıştırıp sonuçları geri gönderirsiniz ve model yanıt verebilene kadar devam eder. api14, araç destekli her modelde OpenAI tools formatıyla bunu destekler; bu yüzden model kimliğini değiştirerek aynı kod OpenAI, Anthropic, Google ve diğer sağlayıcılarla çalışır.

Bu rehber; adım sınırı, paralel araç çalıştırma, yapılandırılmış nihai yanıt ve maliyet kontrolleri olan küçük bir ajan kurar. Kod, https://api14.com/api/v1 base URL'iyle resmi openai paketini kullanır.

Araçları tanımlama

Her araç bir ad, modelin okuduğu bir açıklama ve argümanları için bir JSON Schema'dan oluşur. Açıklamaları spesifik tutun; modelin tek dokümantasyonu onlardır.

import json, os
from openai import OpenAI

client = OpenAI(base_url="https://api14.com/api/v1", api_key=os.environ["API14_API_KEY"])

def search_orders(customer_email: str) -> list:
    return [{"id": "A-1001", "status": "shipped"}]  # your database query

def get_shipment(order_id: str) -> dict:
    return {"order_id": order_id, "carrier": "UPS", "eta": "2026-10-09"}  # your API call

TOOLS = {"search_orders": search_orders, "get_shipment": get_shipment}

tools = [
    {"type": "function", "function": {
        "name": "search_orders",
        "description": "List a customer's orders with their status.",
        "parameters": {"type": "object", "properties": {"customer_email": {"type": "string"}},
                       "required": ["customer_email"]},
    }},
    {"type": "function", "function": {
        "name": "get_shipment",
        "description": "Carrier and estimated delivery date for one order.",
        "parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
                       "required": ["order_id"]},
    }},
]

Adım sınırlı döngü

Her yineleme ayrı bir faturalandırılan istektir; bu yüzden adım sayısını her zaman sınırlayın. Araç hatalarını çökmek yerine modele içerik olarak döndürün; modeller genellikle argümanları düzelterek toparlar.

MAX_STEPS = 8

def run_tool(call):
    try:
        args = json.loads(call.function.arguments)
        result = TOOLS[call.function.name](**args)
    except Exception as e:  # bad JSON, unknown tool, or your function failed
        result = {"error": str(e)}
    return {"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)}

def agent(task, model="openai/gpt-5-mini"):
    messages = [
        {"role": "system", "content": "You are a support agent. Use tools to look things up. Be brief."},
        {"role": "user", "content": task},
    ]
    spent = 0.0
    for step in range(MAX_STEPS):
        r = client.chat.completions.create(model=model, messages=messages, tools=tools, max_tokens=1000)
        spent += r.usage.cost
        msg = r.choices[0].message
        if not msg.tool_calls:
            return msg.content, spent
        messages.append(msg)
        messages.extend(run_tool(call) for call in msg.tool_calls)
    raise RuntimeError(f"No answer after {MAX_STEPS} steps (spent ${spent:.4f})")

print(agent("Where is my order? My email is ada@example.com"))

Döngüdeki her istekte tools gönderin. Birçok sağlayıcı, istekte araç tanımları yoksa bir tool mesajını reddeder.

Paralel araç çağrıları

parallel_tool_calls ile (desteklenen yerlerde varsayılan olarak açıktır) model tek turda birkaç çağrı isteyebilir; örneğin üç sipariş için get_shipment. Bunları eşzamanlı çalıştırın ve her çağrı için herhangi bir sırada bir tool mesajı ekleyin; tool_call_id her sonucu çağrısına bağlar. Node'da:

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api14.com/api/v1", apiKey: process.env.API14_API_KEY });
const MAX_STEPS = 8;

async function agent(messages, tools, impl, model = "openai/gpt-5-mini") {
  for (let step = 0; step < MAX_STEPS; step++) {
    const res = await client.chat.completions.create({ model, messages, tools, max_tokens: 1000 });
    const msg = res.choices[0].message;
    if (!msg.tool_calls?.length) return msg.content;

    messages.push(msg);
    const results = await Promise.all(msg.tool_calls.map(async (call) => {
      let content;
      try {
        content = JSON.stringify(await impl[call.function.name](JSON.parse(call.function.arguments)));
      } catch (err) {
        content = JSON.stringify({ error: String(err) });
      }
      return { role: "tool", tool_call_id: call.id, content };
    }));
    messages.push(...results);
  }
  throw new Error(`No answer after ${MAX_STEPS} steps`);
}

Araçlarınızın sırayla gerçekleşmesi gereken yan etkileri varsa (önce oluştur, sonra güncelle) parallel_tool_calls: false ayarlayın; böylece model her turda tek çağrı ister.

Yapılandırılmış nihai çıktı

Ajanın yanıtı başka bir koda girdi oluyorsa, bir şemaya uyan JSON isteyin. Basit ve taşınabilir bir desen, döngü bilgileri topladıktan sonra tek bir ek çağrı yapmaktır (buradaki messages, döngüdeki konuşmadır; bunu agent() fonksiyonundan yanıtla birlikte döndürün):

schema = {
    "type": "object",
    "properties": {
        "order_id": {"type": "string"},
        "status": {"type": "string", "enum": ["processing", "shipped", "delivered", "unknown"]},
        "eta": {"type": ["string", "null"]},
        "reply": {"type": "string"},
    },
    "required": ["order_id", "status", "eta", "reply"],
    "additionalProperties": False,
}

final = client.chat.completions.create(
    model="openai/gpt-5-mini",
    messages=messages + [{"role": "user", "content": "Summarize the result for our ticket system."}],
    tools=tools,
    tool_choice="none",
    response_format={"type": "json_schema", "json_schema": {"name": "ticket", "strict": True, "schema": schema}},
)
ticket = json.loads(final.choices[0].message.content)

tool_choice: "none", tools alanını istekte tutar (geçmiş araç mesajları içerdiği için gereklidir) ve yeni çağrıları engeller. Ayrıştırılan JSON'u her zaman doğrulayın. Bkz. Structured outputs.

Model seçimi

  • Yetenek: modelin supported_parameters alanında tools bulunmalıdır. GET /models ile kontrol edin, bkz. Modeller. Son adım için structured_outputs veya response_format arayın.
  • Yönlendirme: isteklerin yalnızca gönderdiğiniz her parametreyi destekleyen sağlayıcılara gitmesi için provider: { "require_parameters": true } ekleyin (Python'da extra_body ile). Bkz. Sağlayıcı yönlendirme.
  • Boyut: openai/gpt-5-mini gibi küçük modeller, iyi tanımlanmış birkaç aracı güvenilir ve ucuz biçimde yönetir. Ajanın çok sayıda aracı, uzun çok adımlı planları varsa veya sürekli yanlış aracı seçiyorsa daha büyük bir modele geçin.
  • Araçlarınızla test edin: aynı 20 ila 50 gerçek görevi iki veya üç aday modelde çalıştırın ve başarı oranını, görev başına adım sayısını ve toplam usage.cost değerini karşılaştırın.
curl -s "https://api14.com/api/v1/models?category=text" \
  | jq -r '.data[] | select(.supported_parameters | index("tools")) | "\(.id)  \(.pricing.prompt)"'

Maliyeti kontrol etme

Bir ajan tek görev için çok sayıda istek yapabilir ve tüm konuşma her adımda yeniden gönderilir. Harcamayı birkaç düzeyde sınırlayın:

  • Yukarıdaki gibi adım sınırı (MAX_STEPS) ve istek başına max_tokens.
  • Görev başına bütçe: adımlar boyunca usage.cost değerlerini toplayın ve eşiğinizi aştığında durun.
  • Kısa araç sonuçları: yalnızca modelin ihtiyaç duyduğu alanları döndürün. Büyük araç çıktıları sonraki her adımda girdi token'ı olarak ödenir.
  • Anahtar başına günlük USD limiti: API anahtarları sayfasında ajan için özel bir anahtar oluşturun ve günlük limit koyun. Limite ulaşıldığında istekler bir sonraki UTC gününe kadar 429 daily_limit_reached döndürür; bu kodu yeniden deneyerek değil, ajanı durdurarak ele alın.
  • Model izin listesi: anahtarı test ettiğiniz modellerle sınırlayın; diğer her şey 403 model_not_allowed döndürür.
  • Prompt caching: önbelleğe alınmış önek indirimlerinin geçerli olması için sistem prompt'unu ve araç tanımlarını her istekte aynı ve en başta tutun. Bkz. Prompt caching.

Bkz. Tool calling, Hız limitleri ve Hatalar.