Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Agent Framework поддерживает протоколы, совместимые с OpenAI, как для размещения агентов через стандартные API, так и для подключения к любой конечной точке, совместимой с OpenAI.
Что такое протоколы OpenAI?
Поддерживаются два протокола OpenAI:
- API завершения чата — стандартный формат запроса и ответа без отслеживания состояния для взаимодействия чата
- API ответов — расширенный формат, поддерживающий беседы, потоковое вещание и долговременные процессы агентов
API ответов теперь является стандартным и рекомендуемым подходом в соответствии с документацией OpenAI. Он предоставляет более комплексный и функциональный интерфейс для создания приложений ИИ со встроенным управлением беседами, возможностями потоковой передачи и поддержкой длительных процессов.
Используйте API ответов , когда:
- Создание новых приложений (рекомендуется по умолчанию)
- Вам потребуется управление беседами на стороне сервера. Однако это не обязательно: вы можете использовать API для ответов в режиме без сохранения состояния.
- Вы хотите постоянную историю бесед
- Вы создаете долговременные процессы агента
- Вам нужны расширенные возможности потоковой передачи с подробными типами событий
- Вы хотите отслеживать отдельные ответы и управлять ими (например, получать определенный ответ по идентификатору, проверять его состояние или отменять выполняемый ответ).
Используйте API завершения чата , когда:
- Перенос существующих приложений, использующих формат завершения чата
- Вам нужны простые, без отслеживания состояния взаимодействия запросов и ответа
- Управление состоянием полностью осуществляется вашим клиентом
- Вы интегрируете с существующими инструментами, поддерживающими только завершение чата
- Вам нужна максимальная совместимость с устаревшими системами
Агенты хостинга в качестве конечных точек OpenAI (.NET)
Библиотека Microsoft.Agents.AI.Hosting.OpenAI позволяет предоставлять агентов ИИ через интерфейсы HTTP, совместимые с OpenAI, поддерживая API завершения чат-диалогов и ответов. Это позволяет интегрировать агентов с любым клиентом или инструментом, совместимым с OpenAI.
Пакет NuGet:
API завершения чата
API завершения чата предоставляет простой интерфейс без отслеживания состояния для взаимодействия с агентами с помощью стандартного формата чата OpenAI.
Настройка агента в ASP.NET Core с интеграцией ChatCompletions
Вот полный пример демонстрации агента через API завершения чата:
Предпосылки
1. Создание проекта веб-API ASP.NET Core
Создайте проект веб-API ASP.NET Core или используйте существующий.
2. Установка необходимых зависимостей
Установите следующие пакеты:
Выполните следующие команды в каталоге проекта, чтобы установить необходимые пакеты 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. Настройка подключения Azure OpenAI
Приложению требуется подключение Azure OpenAI. Настройте конечную точку и имя развертывания, используя dotnet user-secrets или переменные окружения.
Вы также можете просто изменить appsettings.jsonфайл, но это не рекомендуется для приложений, развернутых в рабочей среде, так как некоторые данные могут считаться секретами.
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. Добавление кода в Program.cs
Замените все содержимое 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.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();
Тестирование конечной точки завершения чата
После запуска приложения можно протестировать агент с помощью пакета SDK OpenAI или HTTP-запросов:
Использование HTTP-запроса
POST {{baseAddress}}/pirate/v1/chat/completions
Content-Type: application/json
{
"model": "pirate",
"stream": false,
"messages": [
{
"role": "user",
"content": "Hey mate!"
}
]
}
Примечание. Замените {{baseAddress}} конечной точкой сервера.
Ниже приведен пример ответа:
{
"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"
}
Ответ содержит идентификатор сообщения, содержимое и статистику использования.
Завершение чата также поддерживает потоковую передачу, где выходные данные возвращаются в блоках, как только содержимое доступно.
Эта возможность позволяет постепенно отображать выходные данные. Вы можете включить потоковую передачу, указав "stream": true.
Формат выходных данных состоит из блоков Server-Sent Events (SSE), как определено в спецификации завершений чатов OpenAI.
POST {{baseAddress}}/pirate/v1/chat/completions
Content-Type: application/json
{
"model": "pirate",
"stream": true,
"messages": [
{
"role": "user",
"content": "Hey mate!"
}
]
}
А выходные данные, которые мы получаем, — это набор блоков 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}}}
Ответ стриминга содержит аналогичную информацию, но в виде событий Server-Sent.
API ответов на запросы
API Ответов предоставляет расширенные возможности, включая управление диалогами, потоковую передачу данных и поддержку длительных агентских процессов.
Настройка агента в ASP.NET Core с интеграцией API ответов
Ниже приведен полный пример использования API ответов:
Предпосылки
Выполните те же предварительные требования, что и пример завершения чата (шаги 1–3).
4. Добавление кода в 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();
Тестирование API ответов
API ответов аналогичен завершениям чатов, но обладает сохранением состояния, что позволяет передавать conversation параметр.
Как и завершение чата, он поддерживает параметр stream, который контролирует формат выходных данных: это может быть либо единичный ответ в формате JSON, либо поток событий.
API ответов определяет собственные типы событий потоковой передачи, включая response.created, , response.output_item.addedresponse.output_item.doneи response.completedдругие.
Создание беседы и ответа
Вы можете отправить запрос на ответы напрямую или создать беседу с помощью API бесед, а затем связать последующие запросы с этой беседой.
Чтобы начать, создайте новую беседу:
POST http://localhost:5209/v1/conversations
Content-Type: application/json
{
"items": [
{
"type": "message",
"role": "user",
"content": "Hello!"
}
]
}
Ответ содержит идентификатор беседы:
{
"id": "conv_E9Ma6nQpRzYxRHxRRqoOWWsDjZVyZfKxlHhfCf02Yxyy9N2y",
"object": "conversation",
"created_at": 1762881679,
"metadata": {}
}
Затем отправьте запрос и укажите параметр беседы.
(Чтобы получить ответ в виде событий потоковой передачи, задайте "stream": true в запросе.)
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?"
}
]
}
]
}
Агент возвращает ответ и сохраняет элементы беседы в хранилище для последующего получения:
{
"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
}
Ответ содержит идентификаторы бесед и сообщений, содержимое и статистику использования.
Чтобы получить элементы беседы, отправьте следующий запрос:
GET http://localhost:5209/v1/conversations/conv_E9Ma6nQpRzYxRHxRRqoOWWsDjZVyZfKxlHhfCf02Yxyy9N2y/items?include=string
Возвращается ответ JSON, содержащий как входные, так и выходные сообщения:
{
"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
}
Выявление нескольких агентов
Вы можете задействовать нескольких агентов одновременно, используя оба протокола.
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);
Агенты будут доступны по адресу:
- Завершение чата:
/math/v1/chat/completionsи/science/v1/chat/completions - Ответы:
/math/v1/responsesи/science/v1/responses
Пользовательские конечные точки
Пути конечных точек можно настроить:
// Custom path for Chat Completions
app.MapOpenAIChatCompletions(mathAgent, path: "/api/chat");
// Custom path for Responses
app.MapOpenAIResponses(scienceAgent, responsesPath: "/api/responses");
Подключение к конечным точкам, совместимым с OpenAI (Python)
Python OpenAIChatCompletionClient и OpenAIChatClient поддерживают параметр base_url, позволяя подключаться к любой конечной точке, совместимой с OpenAI, включая самостоятельно размещенные агенты, локальные серверы вывода (Ollama, LM Studio, vLLM) или сторонние интерфейсы API, совместимые с OpenAI.
pip install agent-framework
Клиент завершения чата
Используйте OpenAIChatCompletionClient и base_url для указания на любой сервер, совместимый с завершением чата.
import asyncio
from agent_framework import tool
from agent_framework.openai import OpenAIChatCompletionClient
@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 = OpenAIChatCompletionClient(
base_url="http://localhost:11434/v1/", # e.g. Ollama
api_key="not-needed", # placeholder for local servers
model="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())
Клиент для ответов
Используйте OpenAIChatClient вместе с base_url для конечных точек, поддерживающих API ответов:
import asyncio
from agent_framework.openai import OpenAIChatClient
async def main():
agent = OpenAIChatClient(
base_url="https://your-hosted-agent.example.com/v1/",
api_key="your-api-key",
model="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())
Общие серверы, совместимые с OpenAI
Подход base_url работает с любым сервером, предоставляющим формат завершения чата OpenAI:
| Сервер | Базовый URL-адрес | Примечания. |
|---|---|---|
| Ollama | http://localhost:11434/v1/ |
Локальная инференция, ключ API не требуется |
| LM Studio | http://localhost:1234/v1/ |
Локальный инференс с графическим интерфейсом |
| vLLM | http://localhost:8000/v1/ |
Обслуживание с высокой пропускной способностью |
| Microsoft Foundry | Конечная точка развертывания | Использование учетных данных Azure |
| Агенты платформы Hosted Agent Framework | Конечная точка агента | Агенты .NET, доступные через MapOpenAIChatCompletions |
Замечание
Можно также задать OPENAI_BASE_URL переменную среды вместо передачи base_url напрямую. Клиент будет использовать его автоматически.
Использование клиентов Azure OpenAI
Используйте те же универсальные клиенты OpenAI для Azure OpenAI, передав явные входные данные маршрутизации Azure вместо base_url.
import os
from agent_framework.openai import OpenAIChatClient
from azure.identity import AzureCliCredential
agent = OpenAIChatClient(
model=os.environ["AZURE_OPENAI_CHAT_MODEL"],
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
credential=AzureCliCredential(),
).as_agent(
name="Assistant",
instructions="You are a helpful assistant.",
)
Настройка с переменными среды:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_CHAT_MODEL="gpt-4o-mini"
export AZURE_OPENAI_API_VERSION="your-api-version"
OpenAIChatClient предпочитает AZURE_OPENAI_CHAT_MODEL; AZURE_OPENAI_MODEL остается общим резервным вариантом, если вам нужен один.
См. также
- Общие сведения об интеграции
- Интеграция A2A
- Справочник по API завершения чата OpenAI
- Справочник по API ответов OpenAI