Azure OpenAI Yanıtları API'siyle programlı araç çağrısı

Programatik araç çağırma, bir modelin Yanıtlar API'si isteği sırasında araçları orkestre etmek için kod kullanmasına olanak tanır. Model, her araç çağrısı için ayrı bir model dönüşü gerektirmek yerine araçları çağıran ve sonuçlarını işleyen bir program oluşturabilir. Program dallanma veya yineleme gibi işlemler gerçekleştirebilir.

Bu makalede, programatik araç çağrısının ne zaman yararlı olduğu ve işlev çağrısı, paralel araç çağrısı ve araç aramasından nasıl farklılaştığı açıklanmaktadır.

Kullanılabilirlik konuları

Programatik araç çağırmayı uygulamadan önce, Azure OpenAI model dağıtımınızın ve SDK sürümünüzün özelliği desteklediğini onaylayın. Yanıtlar API'sine yönelik desteğin programatik araç çağrısının da desteklendiği anlamına geldiğini varsaymayın.

Uç nokta ve kimlik doğrulaması kurulumu için bkz. Azure OpenAI Responses API'sini kullanma.

Programatik araç çağrısı ve işlev çağrısı

Standart işlev çağrısı ile uygulamanız genellikle her araç çağırma adımına katılır:

Model -> araç çağrısı -> uygulama aracı yürütür -> model -> sonraki araç çağrısı -> uygulama aracı yürütür -> model

Programlı araç çağrısı ile model, birden çok araç işlemini düzenleyen kod oluşturabilir:

Model -> oluşturulan program -> araç işlemleri -> program sonucu -> model

Bu yaklaşım, çeşitli araçlar içeren iş akışları için gereken model etkileşimlerinin sayısını azaltabilir.

Bu akışlar orkestrasyondaki kavramsal farkı gösterir. Onlar, uygulamanızın veya hizmetin hangi işlemleri yürüttüğünü belirtmez.

Örnek: Envanteri taleple karşılaştırın

Bu Python örnek, örnek envanter ve talep verileri döndüren uygulama tanımlı iki işlevi kullanıma sunar. Model, sonuçları karşılaştırmak için programatik araç çağırma kullanır. Uygulamanız işlevleri yürütür ve çalışma zamanının oluşturulan programı sürdürebilmesi için sonuçlarını döndürür.

Kod blokları bir betik oluşturur. Bunları gösterilen sırayla birleştirin.

Azure OpenAI istemcisi

Programlı araç çağrısını destekleyen bir Azure OpenAI dağıtımı ve allowed_callers, output_schema ve çağıran bilgilerini içeren bir OpenAI SDK sürümü kullanın. openai ve azure-identity paketlerini Python ortamınıza yükleyin:

pip install --upgrade openai azure-identity

Microsoft Entra ID kimlik doğrulamasını, Azure OpenAI Responses API'yi kullanma bölümünde açıklandığı gibi yapılandırın. Azure OpenAI dağıtımınızı çağırmak için kimliğinizin izne ihtiyacı vardır.

YOUR-RESOURCE-NAME öğesini kaynak adınızla değiştirin. Örneğin ilerleyen kısmındaki model değeri, model kataloğu tanımlayıcısı değil Azure dağıtım adınızdır.

import json

from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import OpenAI

# Use the Azure OpenAI v1 endpoint and Microsoft Entra ID authentication.
endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
    credential, "https://cognitiveservices.azure.com/.default"
)
openai = OpenAI(base_url=endpoint, api_key=token_provider)

Uygulama tanımlı işlevler

İşlevler sabit örnek veriler döndürür: Belirtilen SKU için 42 kullanılabilir birim ve 31 istenen birim. Bunların gerçeklemelerini uygulamanızdaki envanter ve talep veri kaynaklarıyla değiştirin.

def get_inventory(sku):
    return {"sku": sku, "available_units": 42}


def get_demand(sku):
    return {"sku": sku, "requested_units": 31}


implementations = {
    "get_inventory": get_inventory,
    "get_demand": get_demand,
}

Araç tanımları

Her işlev bir giriş şeması ve JSON sonucunu açıklayan bir output_schema bildirir. ["programmatic"] ayarını allowed_callers olarak ayarlamak, işlevi doğrudan model çağrıları yerine oluşturulan programların kullanımına sunar.

tools = [
    {
        "type": "function",
        "name": "get_inventory",
        "description": "Return the SKU and available inventory units.",
        "strict": True,
        "parameters": {
            "type": "object",
            "properties": {"sku": {"type": "string"}},
            "required": ["sku"],
            "additionalProperties": False,
        },
        "output_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "available_units": {"type": "number"},
            },
            "required": ["sku", "available_units"],
            "additionalProperties": False,
        },
        "allowed_callers": ["programmatic"],
    }
]

Talep işlevini ve programlı araç çağırma özelliğini aynı listeye ekleyin:

tools.extend([
    {
        "type": "function",
        "name": "get_demand",
        "description": "Return the SKU and requested demand units.",
        "strict": True,
        "parameters": {
            "type": "object",
            "properties": {"sku": {"type": "string"}},
            "required": ["sku"],
            "additionalProperties": False,
        },
        "output_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "requested_units": {"type": "number"},
            },
            "required": ["sku", "requested_units"],
            "additionalProperties": False,
        },
        "allowed_callers": ["programmatic"],
    },
    {"type": "programmatic_tool_calling"},
])

Araç sonuçları ve arayan bilgileri

Uygulama işlev çağrılarını isme göre yönlendirir ve her sonucu seri hale getirir. Çalışma zamanının doğru programı sürdürebilmesi için çağrının caller bilgilerini koruyun. Bilinmeyen araç adları ve geçersiz bağımsız değişkenler, uydurulan sonuçları döndürmek yerine hatalara neden olur.

def run_tool(call):
    run = implementations.get(call.name)
    if run is None:
        raise ValueError(f"Unknown tool: {call.name}")

    arguments = json.loads(call.arguments)
    if (
        not isinstance(arguments, dict)
        or set(arguments) != {"sku"}
        or not isinstance(arguments["sku"], str)
    ):
        raise ValueError(f"Invalid arguments for tool: {call.name}")

    result = run(**arguments)
    output = {
        "type": "function_call_output",
        "call_id": call.call_id,
        "output": json.dumps(result),
    }
    if call.caller is not None:
        output["caller"] = call.caller.model_dump(exclude_none=True)
    return output

Yanıt devamı

YOUR-MODEL-DEPLOYMENT öğesini, desteklenen Azure OpenAI dağıtımınızın adıyla değiştirin.

store=False ile uygulama konuşmayı sürdürür. Araç sonuçları eklemeden önce program ve mantık öğeleri de dahil olmak üzere tüm çıkış öğelerini koruyun. Döngü, nihai bir yanıtta veya reddetmede durur ve yanıt başarısız olursa veya istek sınırına ulaşılırsa hata verir.

input_items = [
    {"role": "user", "content": "Compare inventory with demand for sku_123."}
]
MAX_REQUESTS = 10
for _ in range(MAX_REQUESTS):
    response = openai.responses.create(
        model="YOUR-MODEL-DEPLOYMENT",
        store=False, input=input_items, tools=tools,
    )
    if response.status != "completed":
        raise RuntimeError(f"Response ended with status {response.status}")
    input_items.extend(
        item.model_dump(exclude_none=True) for item in response.output
    )
    calls = [item for item in response.output if item.type == "function_call"]
    if calls:
        input_items.extend(run_tool(call) for call in calls)
        continue
    if response.output_text:
        print(response.output_text)
        break
    refusals = [
        part.refusal for item in response.output if item.type == "message"
        for part in item.content if part.type == "refusal"
    ]
    if refusals:
        print("\n".join(refusals))
        break
else:
    raise RuntimeError("Programmatic tool calling exceeded the request limit")

Son yanıt, envanterin talebi kapsadığını açıklamalıdır: 42 kullanılabilir birim eksi 31 istenen birim 11 birim bırakır. İfade farklılık gösterebilir. Model isteği reddederse, bunun yerine bir reddetme yazdırılır.

Uygulama stok ve talep işlevlerini yürütürken, oluşturulan program bunların kullanımını koordine eder ve sonuçları işler.

Programatik araç çağırma ne zaman kullanılır?

Bir görev olduğunda programatik araç çağrısını göz önünde bulundurun:

  • Çeşitli ilgili araç çağrıları gerektirir.
  • Koşullu mantık içerir.
  • Araç sonuçları üzerinde yineleme yapılması gerekiyor.
  • Bir yanıt oluşturmadan önce ara veri işleme gerçekleştirir.
  • Aksi takdirde, araçları koordine etmek için yinelenen model etkileşimleri gerekir.

Bir veya iki bağımsız işlev içeren basit iş akışları için standart işlev çağrısının uygulanması daha kolay olabilir.

Programatik araç çağrısı ve paralel araç çağrısı

Paralel araç çağrısı ve programatik araç çağrısı, farklı orkestrasyon gereksinimlerini karşılar.

Aynı anda birkaç bağımsız işlem yürütülebildiğinde paralel araç çağrısı kullanın. Örneğin, beş bağımsız konum için hava durumunu alın.

Araç işlemleri koordinasyon, ara hesaplama, dallanma veya yineleme gerektirdiğinde programatik araç çağrısı kullanın. Örneğin, müşterinin siparişlerini alın, bir koşulla eşleşen siparişleri seçin ve bu siparişler için sevkiyat bilgilerini sorgula.

Araç arama, modelin bağlamı içine hangi araç tanımlarının yüklendiğini denetler.

Programatik araç çağırma, modelin araçlar kullanılabilir hâle geldikten sonra araçları nasıl düzenlediğini denetler.

Ayrım, araç bulma ve araç orkestrasyonu arasındadır. Kavramsal ilişkileri, dağıtımınızın aynı istekte her iki özelliğin de kullanılmasını destekleyip desteklemediğini belirlemez.

Güvenlik konuları

Oluşturulan programları güvenilmeyen kod olarak kabul edin.

Araçları kullanıma sunarken:

  • Asgari ayrıcalık ilkesini izleyin.
  • Araç bağımsız değişkenlerini doğrulayın.
  • Hassas işlemlere erişimi kısıtlayın.
  • İşlemleri model çıkışından bağımsız olarak doğrulayın ve yetkilendirin.
  • Gizli bilgileri veya gereksiz hassas verileri kaydetmeden, denetim ve tanılama için araç yürütmesini günlüğe kaydedin.
  • Gereksiz araçları veya verileri açığa çıkarmaktan kaçının.

Yetkilendirme sınırı olarak model tarafından oluşturulan koda güvenmeyin.