Skip to content

代理类型总览

Microsoft Agent Framework 为多种代理类型提供支持,以满足不同的用例和要求。所有代理都派生自通用基类 AIAgent,该类为所有代理类型提供一致的接口。


AIAgent 基类

AIAgent 是所有 Agent 的抽象基类,定义了统一的接口:

csharp
public abstract class AIAgent
{
    // 非流式运行
    public abstract Task<AgentResponse> RunAsync(
        string input, AgentSession? session = null,
        AgentRunOptions? options = null,
        CancellationToken ct = default);

    public abstract Task<AgentResponse> RunAsync(
        ChatMessage message, AgentSession? session = null,
        AgentRunOptions? options = null,
        CancellationToken ct = default);

    // 流式运行
    public abstract IAsyncEnumerable<AgentResponseUpdate> RunStreamingAsync(
        string input, AgentSession? session = null,
        AgentRunOptions? options = null,
        CancellationToken ct = default);

    // 结构化输出
    public virtual Task<AgentResponse<T>> RunAsync<T>(
        string input, AgentSession? session = null,
        AgentRunOptions? options = null,
        CancellationToken ct = default);
}

AIAgent 的通用接口使得更高级别的功能(如多 Agent 编排、中间件管道)可以与具体代理类型无关地编写。

默认代理运行时执行模型

MAF 中的所有代理都使用结构化运行时模型执行。此模型在确定性循环中协调用户交互、模型推理和工具执行:

用户输入


┌──────────────┐
│  接收输入     │
└──────┬───────┘

┌──────────────┐
│  准备消息     │ ← 聊天历史 + AI 上下文提供程序
└──────┬───────┘

┌──────────────┐
│  模型推理     │ ← 发送给 LLM
└──────┬───────┘

┌──────────────┐     是
│  需要工具?    │────→ 执行工具 → 返回结果
└──────┬───────┘
       │ 否

┌──────────────┐
│  返回响应     │
└──────────────┘

这个循环是 Agent 区别于普通 LLM API 调用的核心特征——Agent 可以自主决定是否调用工具、调用哪些工具、以及何时结束。

基于推理服务的简单代理

使用 Agent Framework,可以轻松基于许多不同的推理服务创建简单的代理。提供 Microsoft.Extensions.AI.IChatClient 实现的任何推理服务都可用于生成这些代理。

Microsoft.Agents.AI.ChatClientAgent 是为任何 IChatClient 实现提供代理的类。

csharp
using Microsoft.Agents.AI;

var agent = new ChatClientAgent(
    chatClient,
    instructions: "You are a helpful assistant");

这些代理原生支持多种功能:

  1. 函数调用 — 通过 AIFunctionFactory.Create 注册工具
  2. 多轮对话 — 使用本地或服务提供的聊天历史记录管理
  3. 自定义工具 — MCP、代码执行等
  4. 结构化输出 — 类型安全的结果返回
  5. 流式响应 — 逐 Token 输出

代理类型的对比

代理类型基类适用场景
ChatClientAgentAIAgent标准聊天代理,基于 IChatClient,支持函数调用、多轮对话、流式
自定义 AgentAIAgent(继承)需要完全控制行为,自定义 LLM 交互逻辑
远程 Agent 代理 (A2A)AIAgent通过 A2A 协议连接远程 Agent 实例
GitHubCopilotAgentAIAgent与 GitHub Copilot 生态集成
CopilotStudioAgentAIAgent与 Microsoft Copilot Studio 集成

自定义 Agent

如果 ChatClientAgent 的默认行为不满足需求——例如想在每次 Agent 响应前都做安全检查,或想用自定义调度逻辑控制决策流程——可以继承 AIAgent 基类:

csharp
public class MyCustomAgent : AIAgent
{
    private readonly IChatClient _chatClient;

    public MyCustomAgent(IChatClient chatClient, string name)
        : base(name)
    {
        _chatClient = chatClient;
    }

    public override async Task<AgentResponse> RunAsync(
        string input, AgentSession? session = null,
        AgentRunOptions? options = null,
        CancellationToken ct = default)
    {
        // 自定义逻辑:安全检查、日志、转换
        var safeInput = await SanitizeInput(input);

        // 与 LLM 通信
        var response = await _chatClient.SendAsync(safeInput, ct);

        return new AgentResponse(response);
    }
}

这种方式给了你对 Agent 行为的完全控制权,但代价是需要自己管理与 LLM 的通信和工具调用的协调。

远程 Agent(A2A)

远程 Agent 代理不代表本地运行的 Agent,而是通过 A2A 协议连接到远端的一个 Agent 实例。当你构建多 Agent 系统时,远程 Agent 代理让你可以像调用本地 Agent 一样调用其他服务上的 Agent。

A2A 协议负责底层的网络通信、任务调度和状态同步。

响应内容类型

AgentResponse 的响应内容是一个 IEnumerable<IAgentContent> 集合,了解这些类型有助于正确解析 Agent 的响应:

类型说明
TextContent文本片段,最常见的响应类型
DataContent二进制数据(如图片、文件),Base64 编码
UriContent指向外部资源的 URI 引用
FunctionCallContentAgent 决定调用的工具函数信息
FunctionResultContent工具函数的执行结果

这种结构化设计意味着 Agent 的响应不只是"一段文字"——它可以同时包含文字解释、图片、文件链接和工具调用结果。


下一步:运行代理 — 深入了解流式与非流式运行模式。

学而不思则罔,思而不学则殆