运行代理
基本代理抽象公开用于运行代理的各种选项。调用方可以选择提供零条、一条或多条输入消息,也可以在流式处理和非流式处理之间选择。
流式处理和非流式处理
非流式处理 - RunAsync
使用 RunAsync 方法获取完整的代理响应:
csharp
Console.WriteLine(
await agent.RunAsync("What is the weather like in Amsterdam?"));RunAsync 返回一个 AgentResponse 对象,其中包含 LLM 生成的完整回复内容。所有内容(包括工具调用结果、文本、文件等)都在一个对象中返回。
流式处理 - RunStreamingAsync
使用 RunStreamingAsync 方法逐 Token 获取响应:
csharp
await foreach (var update in agent
.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.Write(update);
}流式输出让 Agent 在 LLM 生成的同时逐步返回结果,用户界面可以实现"打字机效果",大幅改善等待体验。
代理运行选项
AgentRunOptions 允许为每次调用传递自定义选项:
csharp
var chatOptions = new ChatOptions()
{
Tools = [AIFunctionFactory.Create(GetWeather)]
};
Console.WriteLine(await agent.RunAsync(
"What is the weather like in Amsterdam?",
options: new ChatClientAgentRunOptions(chatOptions)));当调用方知道代理的具体类型时,可以传递类型特定的选项(如 ChatClientAgentRunOptions),这些选项会与代理级别的默认选项合并。
响应类型
来自代理的流式和非流式响应都包含代理生成的所有内容,可能包括:
- 用户问题的答案(文本)
- 函数工具调用信息
- 工具调用结果
- 推理文本
- 状态更新
提取文本结果
由于并非所有返回的内容都是结果,需要聚合所有 TextContent 项来提取纯文本:
csharp
// 非流式
var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text); // 聚合的文本
Console.WriteLine(response.Messages.Count); // 包含所有内容的消息数
// 流式
await foreach (var update in agent
.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.WriteLine(update.Text); // 当前更新的文本片段
Console.WriteLine(update.Contents.Count); // 包含的内容项数
}消息类型
Agent 的输入和输出表示为消息。消息细分为内容项。MAF 使用 Microsoft.Extensions.AI 抽象提供的消息和内容类型:
| 类型 | 说明 |
|---|---|
TextContent | 文本内容,既可以是输入也可以是输出。通常包含 Agent 的文本结果 |
DataContent | 二进制内容,用于传入和传出图像、音频或视频数据 |
UriContent | 指向托管内容(如图像、音频、视频)的 URL |
FunctionCallContent | LLM 调用函数工具的请求 |
FunctionResultContent | 函数工具调用的结果 |
csharp
// 解析响应中的不同内容类型
foreach (var content in response)
{
switch (content)
{
case TextContent text:
Console.WriteLine($"文本: {text.Text}");
break;
case DataContent data:
Console.WriteLine($"数据: {data.Data.Length} bytes");
break;
case UriContent uri:
Console.WriteLine($"URI: {uri.Uri}");
break;
case FunctionCallContent fnCall:
Console.WriteLine($"函数调用: {fnCall.Name}");
break;
case FunctionResultContent fnResult:
Console.WriteLine($"函数结果: {fnResult.Result}");
break;
}
}要点:
Text属性是在AgentResponse和AgentResponseUpdate上都可用的便捷属性,自动聚合所有TextContent项。对于只需获取纯文本结果的场景,是最简方式。
下一步:代理管道 — 理解三层管道架构。