运行代理

基本代理抽象公开用于运行代理的各种选项。 调用方可以选择提供零条、一条或多条输入消息。 调用方还可以在流式处理和非流式处理之间进行选择。 让我们深入了解不同的使用方案。

流式处理和非流式处理

Microsoft代理框架支持流式处理和非流式处理方法,用于运行代理。

对于非流式处理,请使用 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 该方法。

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

代理运行选项

基本代理抽象允许为每个代理运行传递选项对象,但自定义抽象级别的运行的能力相当有限。 代理可能有很大差异,因此没有真正常见的自定义选项。

对于调用方知道其使用的代理类型的情况,可以传递特定类型选项以允许自定义运行。

例如,此处的代理是一个 ChatClientAgent ,可以传递 ChatClientAgentRunOptions 继承自 AgentRunOptions的对象。 这样,调用方就可以提供与任何代理级别选项合并的自定义 ChatOptions 项,然后再传递到 IChatClient 构建的 ChatClientAgent 代理级别选项。

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 代理支持传递关键字参数来自定义每个运行。 可用的特定选项取决于代理类型,但 ChatAgent 支持许多可以传递给两者 run 以及 run_stream 方法的聊天客户端参数。

常见 ChatAgent 选项包括:

  • max_tokens:要生成的令牌的最大数目
  • temperature:控制响应生成的随机性
  • model:覆盖此特定运行的模型
  • tools:仅为此运行添加其他工具
  • response_format:指定响应格式(例如结构化输出)
# Run with custom options
result = await agent.run(
    "What is the weather like in Amsterdam?",
    temperature=0.3,
    max_tokens=150,
    model="gpt-4o"
)

# Streaming with custom options
async for update in agent.run_stream(
    "Tell me a detailed weather forecast",
    temperature=0.7,
    tools=[additional_weather_tool]
):
    if update.text:
        print(update.text, end="", flush=True)

当同时提供代理级默认值和运行级别选项时,运行级别选项优先。

响应类型

来自代理的流式处理和非流式处理响应都包含代理生成的所有内容。 内容可能包括来自代理的结果(即用户问题的答案)的数据。 返回的其他数据的示例包括函数工具调用、函数工具调用的结果、推理文本、状态更新等。

由于并非所有返回的内容都是结果,因此在尝试将结果与其他内容隔离时查找特定内容类型非常重要。

若要从响应中提取文本结果,需要聚合来自所有项的所有TextContentChatMessages项。 为了简化这一点,我们在聚合所有TextContent响应类型上提供一个Text属性。

对于非流式处理情况,所有内容均在一个 AgentRunResponse 对象中返回。 AgentRunResponse 允许通过 Messages 属性访问生成的消息。

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

对于流式处理情况, AgentRunResponseUpdate 对象在生成时进行流式处理。 每个更新可能包含来自代理的结果的一部分,以及各种其他内容项。 与非流式处理情况类似,可以使用 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);
}

对于非流式处理情况,所有内容均在一个 AgentRunResponse 对象中返回。 AgentRunResponse 允许通过 messages 属性访问生成的消息。

若要从响应中提取文本结果,需要聚合来自所有项的所有TextContentChatMessage项。 为了简化这一点,我们在聚合所有TextContent响应类型上提供一个text属性。

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}")

对于流式处理情况, AgentRunResponseUpdate 对象在生成时进行流式处理。 每个更新可能包含来自代理的结果的一部分,以及各种其他内容项。 与非流式处理情况类似,可以使用 text 该属性获取更新中包含的结果部分,并通过属性钻取详细信息 contents

async for update in agent.run_stream("What is the weather like in Amsterdam?"):
    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}")

消息类型

代理的输入和输出表示为消息。 消息细分为内容项。

Microsoft代理框架使用抽象提供 Microsoft.Extensions.AI 的消息和内容类型。 消息由 ChatMessage 类表示,所有内容类都继承自基 AIContent 类。

存在各种 AIContent 子类,用于表示不同类型的内容。 有些作为基础 Microsoft.Extensions.AI 抽象的一部分提供,但提供程序还可以根据需要添加自己的类型。

下面是以下一些常用类型:Microsoft.Extensions.AI

类型 Description
TextContent 可以是输入的文本内容,例如来自用户或开发人员,以及代理的输出。 通常包含代理的文本结果。
DataContent 可以是输入和输出的二进制内容。 可用于向代理传入和传出图像、音频或视频数据(其中受支持)。
UriContent 通常指向托管内容(如图像、音频或视频)的 URL。
FunctionCallContent 推理服务调用函数工具的请求。
FunctionResultContent 函数工具调用的结果。

Python 代理框架使用包中的 agent_framework 消息和内容类型。 消息由 ChatMessage 类表示,所有内容类都继承自基 BaseContent 类。

存在各种 BaseContent 子类,用于表示不同类型的内容:

类型 Description
TextContent 可以是代理的输入和输出的文本内容。 通常包含代理的文本结果。
DataContent 表示为数据 URI 的二进制内容(例如 base64 编码的图像)。 可用于向代理传入和传出二进制数据。
UriContent 指向托管内容的 URI,例如图像、音频文件或文档。
FunctionCallContent AI 服务调用函数工具的请求。
FunctionResultContent 函数工具调用的结果。
ErrorContent 处理失败时的错误信息。
UsageContent AI 服务的令牌使用情况和计费信息。

下面介绍如何使用不同的内容类型:

from agent_framework import ChatMessage, TextContent, DataContent, UriContent

# Create a text message
text_message = ChatMessage(role="user", text="Hello!")

# Create a message with multiple content types
image_data = b"..."  # your image bytes
mixed_message = ChatMessage(
    role="user",
    contents=[
        TextContent("Analyze this image:"),
        DataContent(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 isinstance(content, TextContent):
            print(f"Text: {content.text}")
        elif isinstance(content, DataContent):
            print(f"Data URI: {content.uri}")
        elif isinstance(content, UriContent):
            print(f"External URI: {content.uri}")

后续步骤