Поделиться через


Запуск агентов

Абстракция базового агента предоставляет различные варианты запуска агента. Вызывающие могут предоставлять ноль, один или несколько входных сообщений. Вызывающие пользователи также могут выбирать между потоковой и непотоковой передачей. Давайте рассмотрим различные сценарии использования.

Потоковая передача и не потоковая передача

Microsoft Agent Framework поддерживает как методы потоковой передачи, так и непотоковые для запуска агента.

Для непотоковых RunAsync данных используйте этот метод.

Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));

Для потоковой передачи RunStreamingAsync используйте метод.

await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
    Console.Write(update);
}

Для непотоковых run данных используйте этот метод.

result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)

Для потоковой передачи run используйте метод с stream=True. ResponseStream Возвращает объект, который можно асинхронно итерировать:

async for update in agent.run("What is the weather like in Amsterdam?", stream=True):
    if update.text:
        print(update.text, end="", flush=True)

ResponseStream

Объект, возвращаемый ResponseStreamrun(..., stream=True) двумя шаблонами потребления:

Шаблон 1. Асинхронная итерация — обработка обновлений по мере их поступления для отображения в режиме реального времени:

response_stream = agent.run("Tell me a story", stream=True)
async for update in response_stream:
    if update.text:
        print(update.text, end="", flush=True)

Шаблон 2. Прямая финализация — пропуск итерации и получение полного ответа:

response_stream = agent.run("Tell me a story", stream=True)
final = await response_stream.get_final_response()
print(final.text)

Шаблон 3. Объединенный — итерацию для отображения в режиме реального времени, а затем получите агрегированный результат:

response_stream = agent.run("Tell me a story", stream=True)

# First, iterate to display streaming output
async for update in response_stream:
    if update.text:
        print(update.text, end="", flush=True)

# Then get the complete response (uses already-collected updates, does not re-iterate)
final = await response_stream.get_final_response()
print(f"\n\nFull response: {final.text}")
print(f"Messages: {len(final.messages)}")

Параметры запуска агента

Абстракция базового агента позволяет передавать объект options для каждого запуска агента, однако возможность настройки выполнения на уровне абстракции довольно ограничена. Агенты могут значительно отличаться и поэтому не существует распространенных параметров настройки.

В случаях, когда вызывающий пользователь знает тип агента, с которым они работают, можно передать определенные параметры типа, чтобы разрешить настройку выполнения.

Например, здесь агент является агентом ChatClientAgent и можно передать ChatClientAgentRunOptions объект, наследуемый от AgentRunOptions. Это позволяет вызывающей стороне предоставлять пользовательские ChatOptions параметры уровня агента перед передачей IChatClientChatClientAgent в созданный объект.

var chatOptions = new ChatOptions() { Tools = [AIFunctionFactory.Create(GetWeather)] };
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", options: new ChatClientAgentRunOptions(chatOptions)));

Агенты Python поддерживают настройку каждого запуска с помощью options параметра. Параметры передаются в виде TypedDict и могут быть заданы как во время строительства (через default_options) так и для каждого запуска (через options). У каждого поставщика есть собственный класс TypedDict, обеспечивающий полную автозавершение интегрированной среды разработки и проверку типов для параметров, относящихся к поставщику.

Распространенные варианты включают:

  • max_tokens: максимальное число маркеров для создания
  • temperature: управляет случайностью в создании ответов
  • model_id: переопределите модель для этого конкретного запуска.
  • top_p: параметр выборки ядра
  • response_format: укажите формат отклика (например, структурированные выходные данные)

Замечание

tools Параметры instructions остаются в качестве прямых аргументов ключевых слов и не передаются через options словарь.

from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions

# Set default options at construction time
agent = OpenAIChatClient().as_agent(
    instructions="You are a helpful assistant",
    default_options={
        "temperature": 0.7,
        "max_tokens": 500
    }
)

# Run with custom options (overrides defaults)
# OpenAIChatOptions provides IDE autocomplete for all OpenAI-specific settings
options: OpenAIChatOptions = {
    "temperature": 0.3,
    "max_tokens": 150,
    "model_id": "gpt-4o",
    "presence_penalty": 0.5,
    "frequency_penalty": 0.3
}

result = await agent.run(
    "What is the weather like in Amsterdam?",
    options=options
)

# Streaming with custom options
async for update in agent.run(
    "Tell me a detailed weather forecast",
    stream=True,
    options={"temperature": 0.7, "top_p": 0.9},
    tools=[additional_weather_tool]  # tools is still a keyword argument
):
    if update.text:
        print(update.text, end="", flush=True)

У каждого поставщика есть собственный класс TypedDict (например, OpenAIChatOptions, , AnthropicChatOptions), OllamaChatOptionsпредоставляющий полный набор параметров, поддерживаемых этим поставщиком.

При наличии обоих default_options и каждого запуска параметры каждого запуска options имеют приоритет и объединяются со значениями по умолчанию.

Типы ответов

Как потоковая передача, так и непотоковые ответы от агентов содержат все содержимое, созданное агентом. Содержимое может включать данные, которые не являются результатом (т. е. ответом на вопрос пользователя) от агента. Примеры других возвращаемых данных включают вызовы инструментов функции, результаты вызовов инструментов функции, вывод текста, обновления состояния и многое другое.

Так как не все возвращаемое содержимое является результатом, важно искать определенные типы контента при попытке изолировать результат от другого содержимого.

Чтобы извлечь результат текста из ответа, необходимо агрегировать все TextContent элементы из всех ChatMessages элементов. Чтобы упростить эту процедуру Text , свойство доступно для всех типов ответов, которые агрегируют все TextContent.

В случае без потоковой передачи все возвращается в одном AgentResponse объекте. AgentResponse разрешает доступ к созданным сообщениям через Messages свойство.

var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text);
Console.WriteLine(response.Messages.Count);

В случае AgentResponseUpdate потоковой передачи объекты передаются по мере их создания. Каждое обновление может содержать часть результата от агента, а также различные другие элементы содержимого. Как и в случае без потоковой передачи, можно использовать Text свойство для получения части результата, содержащегося в обновлении, и детализации сведений с помощью Contents свойства.

await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
    Console.WriteLine(update.Text);
    Console.WriteLine(update.Contents.Count);
}

В случае без потоковой передачи все возвращается в одном AgentResponse объекте. AgentResponse разрешает доступ к созданным сообщениям через messages свойство.

Чтобы извлечь результат текста из ответа, необходимо агрегировать все TextContent элементы из всех Message элементов. Чтобы упростить эту процедуру Text , свойство доступно для всех типов ответов, которые агрегируют все TextContent.

response = await agent.run("What is the weather like in Amsterdam?")
print(response.text)
print(len(response.messages))

# Access individual messages
for message in response.messages:
    print(f"Role: {message.role}, Text: {message.text}")

В случае AgentResponseUpdate потоковой передачи объекты передаются по мере их создания с помощью возвращаемого run(..., stream=True)ResponseStream объекта. Каждое обновление может содержать часть результата от агента, а также различные другие элементы содержимого. Как и в случае без потоковой передачи, можно использовать text свойство для получения части результата, содержащегося в обновлении, и детализации сведений с помощью contents свойства.

response_stream = agent.run("What is the weather like in Amsterdam?", stream=True)
async for update in response_stream:
    print(f"Update text: {update.text}")
    print(f"Content count: {len(update.contents)}")

    # Access individual content items
    for content in update.contents:
        if hasattr(content, 'text'):
            print(f"Content: {content.text}")

# Get the aggregated final response after streaming
final = await response_stream.get_final_response()
print(f"Complete text: {final.text}")

Типы сообщений

Входные и выходные данные агентов представлены в виде сообщений. Сообщения разделены на элементы содержимого.

Microsoft Agent Framework использует типы сообщений и контента, Microsoft.Extensions.AI предоставляемые абстракциями. Сообщения представлены классом и всеми классами ChatMessage содержимого, наследуемыми от базового AIContent класса.

Существуют различные AIContent подклассы, которые используются для представления различных типов содержимого. Некоторые из них предоставляются в рамках базовых Microsoft.Extensions.AI абстракций, но поставщики также могут добавлять собственные типы, если это необходимо.

Ниже приведены некоторые популярные типы из Microsoft.Extensions.AI:

Тип Description
TextContent Текстовое содержимое, которое может быть как входным, например от пользователя или разработчика, так и выходными данными агента. Обычно содержит результат текста от агента.
DataContent Двоичное содержимое, которое может быть как входным, так и выходным. Можно использовать для передачи изображений, аудио- или видеоданных в агент (где поддерживается).
UriContent URL-адрес, который обычно указывает на размещенное содержимое, например изображение, звук или видео.
FunctionCallContent Запрос службы вывода для вызова средства функции.
FunctionResultContent Результат вызова средства функции.

Платформа агента Python использует типы сообщений и контента из agent_framework пакета. Сообщения представлены классом и всеми классами Message содержимого, наследуемыми от базового Content класса.

Существуют различные Content подклассы, которые используются для представления различных типов содержимого:

Тип Description
Content Унифицированный тип контента с методами фабрики (Content.from_text(), Content.from_data(), Content.from_uri()). type Используйте свойство для проверки типа контента ("text", "data", "URI").
FunctionCallContent Запрос службы ИИ для вызова средства функции.
FunctionResultContent Результат вызова средства функции.
ErrorContent Сведения об ошибке при сбое обработки.
UsageContent Сведения об использовании маркеров и выставлении счетов из службы ИИ.

Вот как работать с различными типами контента:

from agent_framework import Message, Content

# Create a text message
text_message = Message(role="user", contents=["Hello!"])

# Create a message with multiple content types
image_data = b"..."  # your image bytes
mixed_message = Message(
    role="user",
    contents=[
        Content.from_text("Analyze this image:"),
        Content.from_data(data=image_data, media_type="image/png"),
    ]
)

# Access content from responses
response = await agent.run("Describe the image")
for message in response.messages:
    for content in message.contents:
        if content.type == "text":
            print(f"Text: {content.text}")
        elif content.type == "data":
            print(f"Data URI: {content.uri}")
        elif content.type == "uri":
            print(f"External URI: {content.uri}")

Дальнейшие шаги