Udostępnij przez


punkty końcowe kompatybilne z OpenAI

Platforma Agent Framework obsługuje protokoły zgodne z OpenAI zarówno do hostingu agentów obsługiwanych przez standardowe interfejsy API, jak i do nawiązywania połączenia z dowolnym punktem końcowym zgodnym z OpenAI.

Co to są protokoły OpenAI?

Obsługiwane są dwa protokoły OpenAI:

  • Interfejs API uzupełniania czatów — standardowy bezstanowy format żądania/odpowiedzi na potrzeby interakcji z czatem
  • API odpowiedzi — zaawansowany format obsługujący konwersacje, przesyłanie strumieniowe i długoterminowe procesy agenta

API odpowiedzi jest teraz domyślnym i zalecanym podejściem zgodnie z dokumentacją OpenAI. Udostępnia on bardziej kompleksowy i bogaty w funkcje interfejs do tworzenia aplikacji sztucznej inteligencji z wbudowanym zarządzaniem konwersacjami, możliwościami przesyłania strumieniowego i obsługą długotrwałych procesów.

Użyj Responses API, gdy:

  • Tworzenie nowych aplikacji (zalecane ustawienie domyślne)
  • Potrzebujesz zarządzania konwersacjami po stronie serwera. Nie jest to jednak konieczne: nadal można używać API Responses w trybie bezstanowym.
  • Chcesz mieć trwałą historię konwersacji
  • Kompilujesz długotrwałe procesy agenta
  • Potrzebujesz zaawansowanych funkcji przesyłania strumieniowego ze szczegółowymi typami zdarzeń
  • Chcesz śledzić poszczególne odpowiedzi i zarządzać nimi (np. pobrać określoną odpowiedź według identyfikatora, sprawdzić jego stan lub anulować uruchomioną odpowiedź)

Użyj interfejsu API uzupełniania czatu gdy:

  • Migrowanie istniejących aplikacji, które korzystają z formatu uzupełniania czatu
  • Potrzebujesz prostych, bezstanowych interakcji żądań/odpowiedzi
  • Zarządzanie stanem jest obsługiwane w całości przez klienta
  • Integrujesz się z istniejącymi narzędziami, które obsługują tylko zakończenia konwersacji.
  • Potrzebna jest maksymalna zgodność ze starszymi systemami

Agenci hostingu jako punkty końcowe OpenAI (.NET)

Biblioteka Microsoft.Agents.AI.Hosting.OpenAI pozwala na udostępnienie agentów sztucznej inteligencji za pośrednictwem punktów końcowych HTTP zgodnych z protokołem OpenAI, obsługujących zarówno interfejsy API uzupełniania czatu, jak i interfejsy API odpowiedzi. Umożliwia to integrację agentów z dowolnym klientem lub narzędziem zgodnym z interfejsem OpenAI.

Pakiet NuGet:

API Uzupełnień Czatów

API kompletacji czatu zapewnia prosty, bezstanowy interfejs ułatwiający interakcję z agentami przy użyciu standardowego formatu czatu OpenAI.

Konfigurowanie agenta w ASP.NET Core z integracją ChatCompletions

Oto kompletny przykład udostępniania agenta za pośrednictwem API do uzupełniania czatu:

Wymagania wstępne

1. Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core

Utwórz nowy projekt internetowego interfejsu API platformy ASP.NET Core lub użyj istniejącego.

2. Zainstaluj wymagane zależności

Zainstaluj następujące pakiety:

Uruchom następujące polecenia w katalogu projektu, aby zainstalować wymagane pakiety NuGet:

# Hosting.A2A.AspNetCore for OpenAI ChatCompletions/Responses protocol(s) integration
dotnet add package Microsoft.Agents.AI.Hosting.OpenAI --prerelease

# Libraries to connect to Azure OpenAI
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease

# Swagger to test app
dotnet add package Microsoft.AspNetCore.OpenApi
dotnet add package Swashbuckle.AspNetCore

3. Konfigurowanie połączenia azure OpenAI

Aplikacja wymaga połączenia azure OpenAI. Skonfiguruj punkt końcowy i nazwę wdrożenia przy użyciu dotnet user-secrets lub zmiennych środowiskowych. Można również po prostu edytować element appsettings.json, ale nie jest to zalecane dla aplikacji wdrożonych w środowisku produkcyjnym, ponieważ niektóre dane mogą być uważane za tajne.

dotnet user-secrets set "AZURE_OPENAI_ENDPOINT" "https://<your-openai-resource>.openai.azure.com/"
dotnet user-secrets set "AZURE_OPENAI_DEPLOYMENT_NAME" "gpt-4o-mini"

4. Dodaj kod do Program.cs

Zastąp zawartość Program.cs następującym kodem:

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");

// Register the chat client
IChatClient chatClient = new AzureOpenAIClient(
        new Uri(endpoint),
        new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsIChatClient();
builder.Services.AddSingleton(chatClient);

builder.AddOpenAIChatCompletions();

// Register an agent
var pirateAgent = builder.AddAIAgent("pirate", instructions: "You are a pirate. Speak like a pirate.");

var app = builder.Build();

app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();

// Expose the agent via OpenAI ChatCompletions protocol
app.MapOpenAIChatCompletions(pirateAgent);

app.Run();

Testowanie punktu końcowego uzupełniania czatów

Po uruchomieniu aplikacji możesz przetestować agenta przy użyciu zestawu SDK openAI lub żądań HTTP:

Korzystanie z żądania HTTP

POST {{baseAddress}}/pirate/v1/chat/completions
Content-Type: application/json
{
  "model": "pirate",
  "stream": false,
  "messages": [
    {
      "role": "user",
      "content": "Hey mate!"
    }
  ]
}

Uwaga: zastąp {{baseAddress}} punktem końcowym serwera.

Oto przykładowa odpowiedź:

{
	"id": "chatcmpl-nxAZsM6SNI2BRPMbzgjFyvWWULTFr",
	"object": "chat.completion",
	"created": 1762280028,
	"model": "gpt-5",
	"choices": [
		{
			"index": 0,
			"finish_reason": "stop",
			"message": {
				"role": "assistant",
				"content": "Ahoy there, matey! How be ye farin' on this fine day?"
			}
		}
	],
	"usage": {
		"completion_tokens": 18,
		"prompt_tokens": 22,
		"total_tokens": 40,
		"completion_tokens_details": {
			"accepted_prediction_tokens": 0,
			"audio_tokens": 0,
			"reasoning_tokens": 0,
			"rejected_prediction_tokens": 0
		},
		"prompt_tokens_details": {
			"audio_tokens": 0,
			"cached_tokens": 0
		}
	},
	"service_tier": "default"
}

Odpowiedź zawiera identyfikator komunikatu, zawartość i statystyki użycia.

Uzupełnianie czatów obsługuje również przesyłanie strumieniowe, gdzie dane wyjściowe są zwracane we fragmentach natychmiast po udostępnieniu zawartości. Ta funkcja umożliwia stopniowe wyświetlanie danych wyjściowych. Możesz włączyć przesyłanie strumieniowe, określając wartość "stream": true. Format danych wyjściowych składa się z fragmentów Server-Sent Events (SSE), jak zdefiniowano w specyfikacji Chat Completions OpenAI.

POST {{baseAddress}}/pirate/v1/chat/completions
Content-Type: application/json
{
  "model": "pirate",
  "stream": true,
  "messages": [
    {
      "role": "user",
      "content": "Hey mate!"
    }
  ]
}

A dane wyjściowe, które otrzymujemy, to zestaw fragmentów ChatCompletions:

data: {"id":"chatcmpl-xwKgBbFtSEQ3OtMf21ctMS2Q8lo93","choices":[],"object":"chat.completion.chunk","created":0,"model":"gpt-5"}

data: {"id":"chatcmpl-xwKgBbFtSEQ3OtMf21ctMS2Q8lo93","choices":[{"index":0,"finish_reason":"stop","delta":{"content":"","role":"assistant"}}],"object":"chat.completion.chunk","created":0,"model":"gpt-5"}

...

data: {"id":"chatcmpl-xwKgBbFtSEQ3OtMf21ctMS2Q8lo93","choices":[],"object":"chat.completion.chunk","created":0,"model":"gpt-5","usage":{"completion_tokens":34,"prompt_tokens":23,"total_tokens":57,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}}}

Odpowiedź przesyłania strumieniowego zawiera podobne informacje, ale są one dostarczane jako tzw. „Server-Sent Events”.

Odpowiedzi API

API Odpowiedzi udostępnia zaawansowane funkcje, w tym zarządzanie konwersacjami, przesyłanie strumieniowe i obsługę długotrwałych procesów agenta.

Konfiguracja agenta w ASP.NET Core z integracją API odpowiedzi

Oto kompletny przykład użycia Responses API:

Wymagania wstępne

Postępuj zgodnie z tymi samymi wymaganiami wstępnymi co przykład ukończenia czatu (kroki 1–3).

4. Dodaj kod do Program.cs

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");

// Register the chat client
IChatClient chatClient = new AzureOpenAIClient(
        new Uri(endpoint),
        new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsIChatClient();
builder.Services.AddSingleton(chatClient);

builder.AddOpenAIResponses();
builder.AddOpenAIConversations();

// Register an agent
var pirateAgent = builder.AddAIAgent("pirate", instructions: "You are a pirate. Speak like a pirate.");

var app = builder.Build();

app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();

// Expose the agent via OpenAI Responses protocol
app.MapOpenAIResponses(pirateAgent);
app.MapOpenAIConversations();

app.Run();

Testowanie API odpowiedzi

Interfejs API odpowiedzi jest podobny do uzupełniania czatu, ale jest stanowy, co umożliwia przekazanie parametru conversation . Podobnie jak w przypadku uzupełniania czatów, obsługuje parametr stream, który kontroluje format danych wyjściowych: pojedyncza odpowiedź JSON lub strumień zdarzeń. Interfejs API odpowiedzi definiuje własne typy zdarzeń przesyłania strumieniowego, w tym response.created, response.output_item.added, response.output_item.done, response.completed i innych.

Tworzenie konwersacji i odpowiedzi

Możesz wysłać żądanie Odpowiedzi bezpośrednio lub najpierw utworzyć konwersację przy użyciu interfejsu API konwersacji, a następnie połączyć kolejne żądania z tej konwersacji.

Aby rozpocząć, utwórz nową konwersację:

POST http://localhost:5209/v1/conversations
Content-Type: application/json
{
  "items": [
    {
        "type": "message",
        "role": "user",
        "content": "Hello!"
      }
  ]
}

Odpowiedź zawiera identyfikator konwersacji:

{
  "id": "conv_E9Ma6nQpRzYxRHxRRqoOWWsDjZVyZfKxlHhfCf02Yxyy9N2y",
  "object": "conversation",
  "created_at": 1762881679,
  "metadata": {}
}

Następnie wyślij żądanie i określ parametr konwersacji. (Aby otrzymać odpowiedź jako zdarzenia strumieniowe, ustaw "stream": true w żądaniu).

POST http://localhost:5209/pirate/v1/responses
Content-Type: application/json
{
  "stream": false,
  "conversation": "conv_E9Ma6nQpRzYxRHxRRqoOWWsDjZVyZfKxlHhfCf02Yxyy9N2y",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
            "type": "input_text",
            "text": "are you a feminist?"
        }
      ]
    }
  ]
}

Agent zwraca odpowiedź i zapisuje elementy konwersacji w magazynie na potrzeby późniejszego pobierania:

{
  "id": "resp_FP01K4bnMsyQydQhUpovK6ysJJroZMs1pnYCUvEqCZqGCkac",
  "conversation": "conv_E9Ma6nQpRzYxRHxRRqoOWWsDjZVyZfKxlHhfCf02Yxyy9N2y",
  "object": "response",
  "created_at": 1762881518,
  "status": "completed",
  "incomplete_details": null,
  "output": [
    {
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Arrr, matey! As a pirate, I be all about respect for the crew, no matter their gender! We sail these seas together, and every hand on deck be valuable. A true buccaneer knows that fairness and equality be what keeps the ship afloat. So, in me own way, I’d say I be supportin’ all hearty souls who seek what be right! What say ye?"
        }
      ],
      "type": "message",
      "status": "completed",
      "id": "msg_1FAQyZcWgsBdmgJgiXmDyavWimUs8irClHhfCf02Yxyy9N2y"
    }
  ],
  "usage": {
    "input_tokens": 26,
    "input_tokens_details": {
      "cached_tokens": 0
    },
    "output_tokens": 85,
    "output_tokens_details": {
      "reasoning_tokens": 0
    },
    "total_tokens": 111
  },
  "tool_choice": null,
  "temperature": 1,
  "top_p": 1  
}

Odpowiedź zawiera identyfikatory konwersacji i wiadomości, zawartość i statystyki użycia.

Aby pobrać elementy konwersacji, wyślij następujące żądanie:

GET http://localhost:5209/v1/conversations/conv_E9Ma6nQpRzYxRHxRRqoOWWsDjZVyZfKxlHhfCf02Yxyy9N2y/items?include=string

Zwraca to odpowiedź JSON zawierającą komunikaty wejściowe i wyjściowe:

{
  "object": "list",
  "data": [
    {
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Arrr, matey! As a pirate, I be all about respect for the crew, no matter their gender! We sail these seas together, and every hand on deck be valuable. A true buccaneer knows that fairness and equality be what keeps the ship afloat. So, in me own way, I’d say I be supportin’ all hearty souls who seek what be right! What say ye?",
          "annotations": [],
          "logprobs": []
        }
      ],
      "type": "message",
      "status": "completed",
      "id": "msg_1FAQyZcWgsBdmgJgiXmDyavWimUs8irClHhfCf02Yxyy9N2y"
    },
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "are you a feminist?"
        }
      ],
      "type": "message",
      "status": "completed",
      "id": "msg_iLVtSEJL0Nd2b3ayr9sJWeV9VyEASMlilHhfCf02Yxyy9N2y"
    }
  ],
  "first_id": "msg_1FAQyZcWgsBdmgJgiXmDyavWimUs8irClHhfCf02Yxyy9N2y",
  "last_id": "msg_lUpquo0Hisvo6cLdFXMKdYACqFRWcFDrlHhfCf02Yxyy9N2y",
  "has_more": false
}

Uwidacznianie wielu agentów

Można uwidocznić wielu agentów jednocześnie przy użyciu obu protokołów:

var mathAgent = builder.AddAIAgent("math", instructions: "You are a math expert.");
var scienceAgent = builder.AddAIAgent("science", instructions: "You are a science expert.");

// Add both protocols
builder.AddOpenAIChatCompletions();
builder.AddOpenAIResponses();

var app = builder.Build();

// Expose both agents via Chat Completions
app.MapOpenAIChatCompletions(mathAgent);
app.MapOpenAIChatCompletions(scienceAgent);

// Expose both agents via Responses
app.MapOpenAIResponses(mathAgent);
app.MapOpenAIResponses(scienceAgent);

Agenci będą dostępni pod adresem:

  • Ukończenie czatu: /math/v1/chat/completions i /science/v1/chat/completions
  • Odpowiedzi: /math/v1/responses i /science/v1/responses

Niestandardowe punkty końcowe

Ścieżki punktów końcowych można dostosować:

// Custom path for Chat Completions
app.MapOpenAIChatCompletions(mathAgent, path: "/api/chat");

// Custom path for Responses
app.MapOpenAIResponses(scienceAgent, responsesPath: "/api/responses");

Nawiązywanie połączenia z interfejsami API OpenAI-Compatible (Python)

Język Python OpenAIChatClient i OpenAIResponsesClient obsługują parametr base_url, umożliwiając łączenie się z dowolnym punktem końcowym zgodnym z OpenAI — w tym z własnymi agentami, lokalnymi serwerami inferencyjnymi (Ollama, LM Studio, vLLM) lub interfejsami API zgodnymi z OpenAI innych firm.

pip install agent-framework --pre

Klient uzupełnień czatu

Użyj OpenAIChatClient z base_url , aby wskazać dowolny serwer zgodny z uzupełnianiem czatu:

import asyncio
from agent_framework import tool
from agent_framework.openai import OpenAIChatClient

@tool(approval_mode="never_require")
def get_weather(location: str) -> str:
    """Get the weather for a location."""
    return f"Weather in {location}: sunny, 22°C"

async def main():
    # Point to any OpenAI-compatible endpoint
    agent = OpenAIChatClient(
        base_url="http://localhost:11434/v1/",  # e.g. Ollama
        api_key="not-needed",                   # placeholder for local servers
        model_id="llama3.2",
    ).as_agent(
        name="WeatherAgent",
        instructions="You are a helpful weather assistant.",
        tools=get_weather,
    )

    response = await agent.run("What's the weather in Seattle?")
    print(response)

asyncio.run(main())

Klient odpowiedzi

Użyj OpenAIResponsesClient z base_url dla punktów końcowych obsługujących Responses API:

import asyncio
from agent_framework.openai import OpenAIResponsesClient

async def main():
    agent = OpenAIResponsesClient(
        base_url="https://your-hosted-agent.example.com/v1/",
        api_key="your-api-key",
        model_id="gpt-4o-mini",
    ).as_agent(
        name="Assistant",
        instructions="You are a helpful assistant.",
    )

    # Non-streaming
    response = await agent.run("Hello!")
    print(response)

    # Streaming
    async for chunk in agent.run("Tell me a joke", stream=True):
        if chunk.text:
            print(chunk.text, end="", flush=True)

asyncio.run(main())

Typowe serwery OpenAI-Compatible

Takie base_url podejście działa z dowolnym serwerem uwidaczniającym format uzupełniania czatu OpenAI:

Server Podstawowy adres URL Notatki
Ollama http://localhost:11434/v1/ Wnioskowanie lokalne, klucz API nie jest potrzebny
LM Studio http://localhost:1234/v1/ Wnioskowanie lokalne z graficznym interfejsem użytkownika
VLLM http://localhost:8000/v1/ Obsługa wysokiej przepływności
Azure AI Foundry Punkt końcowy wdrożenia Używa poświadczeń platformy Azure
Hostowani agenci programu Agent Framework Punkt końcowy agenta Agenci .NET uwidocznieni za pośrednictwem MapOpenAIChatCompletions

Uwaga / Notatka

Można również ustawić zmienną OPENAI_BASE_URL środowiskową zamiast przekazywać base_url bezpośrednio. Klient użyje go automatycznie.

Korzystanie z klientów usługi Azure OpenAI

Warianty Azure OpenAI (AzureOpenAIChatClient, AzureOpenAIResponsesClient) łączą się z punktami końcowymi usługi Azure OpenAI przy użyciu poświadczeń platformy Azure — nie ma potrzeby na base_url:

from agent_framework.azure import AzureOpenAIResponsesClient

agent = AzureOpenAIResponsesClient().as_agent(
    name="Assistant",
    instructions="You are a helpful assistant.",
)

Konfigurowanie za pomocą zmiennych środowiskowych:

export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME="gpt-4o-mini"

Zobacz też

Dalsze kroki