构建智能 Agent 系统:从对话到工作流的完整实践

引言

当你的 AI 应用需要:

  • 💬 维护长期对话记忆
  • 🧠 具备固定的身份和专业知识
  • 🔧 自动调用工具完成任务
  • 🔄 协调多个 Agent 完成复杂流程

那么,你需要的不再是简单的 IChatClient,而是一个完整的 Agent 系统

本文将基于 Microsoft Agent Framework (MAF)MEAI,带你从零构建生产级的智能 Agent 系统,并进阶到多 Agent 工作流编排。

Agent vs ChatClient:为什么需要 Agent?

核心区别

graph TB
    subgraph "IChatClient - 无状态"
        C1[调用 1] --> C2[返回]
        C3[调用 2] --> C4[返回]
        C5[调用 3] --> C6[返回]
        
        style C1 fill:#FF9800
        style C3 fill:#FF9800
        style C5 fill:#FF9800
    end
    
    subgraph "AIAgent - 有状态"
        A1[调用 1] --> A2[对话线程]
        A2 --> A3[调用 2]
        A3 --> A2
        A2 --> A5[调用 3]
        A5 --> A2
        
        style A2 fill:#4CAF50,stroke:#2E7D32,stroke-width:3px
    end

特性

IChatClient

AIAgent

状态管理

❌ 无状态,每次独立

✅ 内置对话线程(AgentThread)

身份定义

❌ 需手动传入 System Message

✅ 固定的 Instructions 和 Name

工具管理

⚠️ 需在每次调用时配置

✅ Agent 级别统一管理

对话持久化

❌ 需手动实现

✅ 内置 IMessageStore 支持

多轮交互

❌ 需手动维护消息历史

✅ 自动管理上下文

使用场景

单次查询、无状态任务

多轮对话、企业级应用


MAF Agent 快速入门

架构概览

graph TB
    subgraph "应用层"
        App[你的应用]
    end
    
    subgraph "Agent 层"
        Agent[AIAgent]
        Thread[AgentThread<br/>对话线程]
        Store[IMessageStore<br/>消息存储]
    end
    
    subgraph "AI 抽象层"
        Client[IChatClient<br/>MEAI]
    end
    
    subgraph "AI 服务层"
        Service[OpenAI / Azure OpenAI / etc.]
    end
    
    App --> Agent
    Agent --> Thread
    Thread --> Store
    Agent --> Client
    Client --> Service
    
    style Agent fill:#4CAF50,stroke:#2E7D32,stroke-width:3px
    style Thread fill:#2196F3

核心概念

1. AIAgent - 智能体

定义:具有固定身份、专业知识和工具能力的 AI 实体。

using Microsoft.Extensions.AI.Agents;

// 创建 Agent
var agent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "CodeReviewBot",
    Instructions = @"你是一个专业的代码审查专家。
        你的职责:
        1. 检查代码质量和最佳实践
        2. 识别潜在的 bug 和性能问题
        3. 提供改进建议
        
        审查标准:
        - 遵循 SOLID 原则
        - 注重可读性和可维护性
        - 关注安全性和性能",
    
    // Agent 级别的工具
    Tools = new ToolCollection
    {
        AIFunctionFactory.Create(GetCodeMetrics),
        AIFunctionFactory.Create(CheckSecurityVulnerabilities)
    }
});

2. AgentThread - 对话线程

定义:一段独立的对话上下文,自动管理消息历史。

// 创建新的对话线程
var thread = await agent.CreateThreadAsync();

// 添加消息
await thread.AddMessageAsync("请审查这段代码:public class User { ... }");

// 获取响应(自动维护上下文)
var response = await thread.InvokeAsync();
Console.WriteLine(response.Text);

// 继续对话(Agent 能记住之前的内容)
await thread.AddMessageAsync("这个类还需要实现什么接口?");
var response2 = await thread.InvokeAsync();

3. IMessageStore - 消息持久化

定义:存储对话历史,支持恢复和审计。

// 使用内存存储(开发环境)
var memoryStore = new InMemoryMessageStore();

// 使用持久化存储(生产环境)
var dbStore = new SqlMessageStore(connectionString);

var agent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "Assistant",
    MessageStore = dbStore  // 自动持久化所有消息
});


实战 1:构建智能客服 Agent

需求分析

构建一个能够:

  • 查询订单状态
  • 处理退款申请
  • 提供产品咨询
  • 记住用户的对话历史

完整实现

using Microsoft.Extensions.AI;
using Microsoft.Extensions.AI.Agents;
using Microsoft.Extensions.DependencyInjection;
using System.ComponentModel;

// 1. 定义业务工具
public class CustomerServiceTools
{
    private readonly IOrderRepository _orders;
    private readonly IProductCatalog _catalog;
    private readonly ILogger<CustomerServiceTools> _logger;
    
    public CustomerServiceTools(
        IOrderRepository orders,
        IProductCatalog catalog,
        ILogger<CustomerServiceTools> logger)
    {
        _orders = orders;
        _catalog = catalog;
        _logger = logger;
    }
    
    [Description("查询订单状态和详情")]
    public async Task<OrderInfo> GetOrderStatus(
        [Description("订单号")] string orderId)
    {
        _logger.LogInformation("查询订单: {OrderId}", orderId);
        
        var order = await _orders.GetByIdAsync(orderId);
        
        if (order == null)
        {
            return new OrderInfo
            {
                Found = false,
                Message = "未找到该订单,请检查订单号是否正确"
            };
        }
        
        return new OrderInfo
        {
            Found = true,
            OrderId = order.Id,
            ProductName = order.ProductName,
            Status = order.Status.ToString(),
            Amount = order.Amount,
            OrderDate = order.CreatedAt,
            EstimatedDelivery = order.EstimatedDeliveryDate
        };
    }
    
    [Description("申请退款")]
    public async Task<RefundResult> RequestRefund(
        [Description("订单号")] string orderId,
        [Description("退款原因")] string reason)
    {
        _logger.LogInformation("退款申请: {OrderId}, 原因: {Reason}", orderId, reason);
        
        var order = await _orders.GetByIdAsync(orderId);
        
        if (order == null)
        {
            return new RefundResult
            {
                Success = false,
                Message = "订单不存在"
            };
        }
        
        // 验证退款条件
        if (order.Status == OrderStatus.Delivered)
        {
            var daysSinceDelivery = (DateTime.Now - order.DeliveredAt!.Value).Days;
            if (daysSinceDelivery > 7)
            {
                return new RefundResult
                {
                    Success = false,
                    Message = "已超过7天无理由退货期限"
                };
            }
        }
        
        // 创建退款申请
        var refundId = await _orders.CreateRefundAsync(orderId, reason);
        
        return new RefundResult
        {
            Success = true,
            RefundId = refundId,
            Message = "退款申请已提交,预计3-5个工作日处理完成"
        };
    }
    
    [Description("搜索产品信息")]
    public async Task<List<ProductInfo>> SearchProducts(
        [Description("搜索关键词")] string query,
        [Description("返回数量,默认5")] int limit = 5)
    {
        _logger.LogInformation("搜索产品: {Query}", query);
        
        var products = await _catalog.SearchAsync(query, limit);
        
        return products.Select(p => new ProductInfo
        {
            Id = p.Id,
            Name = p.Name,
            Price = p.Price,
            Description = p.Description,
            InStock = p.Stock > 0
        }).ToList();
    }
}

// 2. 定义数据模型
public record OrderInfo
{
    public bool Found { get; set; }
    public string? OrderId { get; set; }
    public string? ProductName { get; set; }
    public string? Status { get; set; }
    public decimal Amount { get; set; }
    public DateTime OrderDate { get; set; }
    public DateTime? EstimatedDelivery { get; set; }
    public string? Message { get; set; }
}

public record RefundResult
{
    public bool Success { get; set; }
    public string? RefundId { get; set; }
    public string Message { get; set; } = "";
}

public record ProductInfo
{
    public string Id { get; set; } = "";
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
    public string Description { get; set; } = "";
    public bool InStock { get; set; }
}

// 3. 配置依赖注入
var services = new ServiceCollection();

services.AddLogging(builder => builder.AddConsole());

// 注册业务服务
services.AddSingleton<IOrderRepository, OrderRepository>();
services.AddSingleton<IProductCatalog, ProductCatalog>();
services.AddSingleton<CustomerServiceTools>();

// 注册消息存储
services.AddSingleton<IMessageStore>(sp => 
    new SqlMessageStore(connectionString)
);

// 注册 IChatClient
services.AddSingleton<IChatClient>(sp =>
{
    var logger = sp.GetRequiredService<ILoggerFactory>();
    
    return new OpenAIClient(new ApiKeyCredential("your-key"))
        .AsChatClient("gpt-4o")
        .UseLogging(logger)
        .UseFunctionInvocation();  // 自动执行工具调用
});

// 注册 Agent
services.AddSingleton<AIAgent>(sp =>
{
    var chatClient = sp.GetRequiredService<IChatClient>();
    var tools = sp.GetRequiredService<CustomerServiceTools>();
    var messageStore = sp.GetRequiredService<IMessageStore>();
    
    // 注册工具
    var toolCollection = AIFunctionFactory.Create(
        typeof(CustomerServiceTools), 
        tools
    );
    
    return new AIAgent(chatClient, new AIAgentOptions
    {
        Name = "CustomerServiceBot",
        Instructions = @"你是一个专业、友好的客服助手。

职责:
1. 查询订单状态并解答物流问题
2. 处理退款申请(需验证退货政策)
3. 提供产品咨询和推荐
4. 解答常见问题

沟通风格:
- 友好、耐心、专业
- 使用简洁明了的语言
- 主动询问必要信息
- 对无法处理的问题,引导用户联系人工客服

业务规则:
- 退货政策:商品签收后7天内可申请无理由退货
- 订单修改:仅限未发货状态
- 产品推荐:根据用户需求和预算推荐合适的产品",

        Tools = toolCollection,
        MessageStore = messageStore,
        
        // 配置 ChatOptions
        ChatOptions = new ChatOptions
        {
            Temperature = 0.3f,  // 客服需要准确性
            MaxOutputTokens = 1000
        }
    });
});

var provider = services.BuildServiceProvider();

// 4. 使用 Agent
var agent = provider.GetRequiredService<AIAgent>();

// 模拟用户对话
async Task HandleUserQuery(string userId, string userMessage)
{
    Console.WriteLine($"\n用户 ({userId}): {userMessage}");
    
    // 为每个用户维护独立的对话线程
    var threadId = $"user-{userId}";
    
    // 尝试恢复现有对话
    AgentThread thread;
    try
    {
        thread = await agent.GetThreadAsync(threadId);
        Console.WriteLine("  [恢复现有对话]");
    }
    catch
    {
        // 创建新对话
        thread = await agent.CreateThreadAsync(threadId);
        Console.WriteLine("  [创建新对话]");
    }
    
    // 添加用户消息
    await thread.AddMessageAsync(userMessage, role: ChatRole.User);
    
    // 获取 Agent 响应
    var response = await thread.InvokeAsync();
    
    Console.WriteLine($"客服: {response.Text}");
}

// 模拟多轮对话
await HandleUserQuery("user123", "我想查询订单 ORDER-12345 的状态");
await HandleUserQuery("user123", "我对这个产品不满意,能退货吗?");
await HandleUserQuery("user123", "好的,我要申请退款,原因是尺码不合适");

// 输出示例:
// 用户 (user123): 我想查询订单 ORDER-12345 的状态
//   [创建新对话]
// [AI 调用 GetOrderStatus("ORDER-12345")]
// 客服: 您的订单已发货,预计明天送达。商品是 iPhone 15,金额 5999元。

// 用户 (user123): 我对这个产品不满意,能退货吗?
//   [恢复现有对话]
// 客服: 您的订单是昨天发货的,在签收后7天内可以申请无理由退货。请问您想现在申请退款吗?

// 用户 (user123): 好的,我要申请退款,原因是尺码不合适
//   [恢复现有对话]
// [AI 调用 RequestRefund("ORDER-12345", "尺码不合适")]
// 客服: 退款申请已提交成功,申请号为 REFUND-789。预计3-5个工作日处理完成...


实战 2:多 Agent 协作系统

场景:代码生成与审查流程

需要三个专业 Agent 协作:

  1. 需求分析 Agent:理解用户需求,生成技术规格
  2. 代码生成 Agent:根据规格编写代码
  3. 代码审查 Agent:审查代码质量并提出改进

实现方式 1:手动编排

// 1. 定义各个 Agent
var requirementAgent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "RequirementAnalyst",
    Instructions = @"你是一个需求分析专家。
        分析用户需求,生成详细的技术规格,包括:
        - 功能描述
        - 输入输出定义
        - 边界条件
        - 性能要求",
    ChatOptions = new ChatOptions { Temperature = 0.5f }
});

var codeGenAgent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "CodeGenerator",
    Instructions = @"你是一个资深的 C# 开发者。
        根据技术规格编写高质量的代码:
        - 遵循 SOLID 原则
        - 添加必要的注释
        - 包含错误处理
        - 使用现代 C# 特性",
    ChatOptions = new ChatOptions { Temperature = 0.3f }
});

var reviewAgent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "CodeReviewer",
    Instructions = @"你是一个代码审查专家。
        审查代码并提供反馈:
        1. 代码质量(可读性、可维护性)
        2. 潜在的 bug
        3. 性能优化建议
        4. 最佳实践
        
        如果发现严重问题,标记为 'REJECT',否则 'APPROVE'",
    ChatOptions = new ChatOptions { Temperature = 0.2f }
});

// 2. 编排工作流
public async Task<CodeGenerationResult> GenerateCodeAsync(string userRequirement)
{
    // 步骤 1: 需求分析
    Console.WriteLine("=== 步骤 1: 需求分析 ===");
    var reqThread = await requirementAgent.CreateThreadAsync();
    await reqThread.AddMessageAsync($"用户需求:{userRequirement}");
    var specResponse = await reqThread.InvokeAsync();
    var specification = specResponse.Text;
    Console.WriteLine($"技术规格:\n{specification}\n");
    
    // 步骤 2: 代码生成
    Console.WriteLine("=== 步骤 2: 代码生成 ===");
    var codeThread = await codeGenAgent.CreateThreadAsync();
    await codeThread.AddMessageAsync($"技术规格:\n{specification}\n\n请生成代码");
    var codeResponse = await codeThread.InvokeAsync();
    var generatedCode = codeResponse.Text;
    Console.WriteLine($"生成的代码:\n{generatedCode}\n");
    
    // 步骤 3: 代码审查(循环直到通过)
    var reviewCount = 0;
    var maxRetries = 3;
    string reviewResult;
    
    while (reviewCount < maxRetries)
    {
        Console.WriteLine($"=== 步骤 3: 代码审查 (第 {reviewCount + 1} 次) ===");
        var reviewThread = await reviewAgent.CreateThreadAsync();
        await reviewThread.AddMessageAsync($@"请审查以下代码:

规格:
{specification}

代码:
{generatedCode}

请给出审查意见,并在最后一行明确标注 APPROVE 或 REJECT");
        
        var reviewResponse = await reviewThread.InvokeAsync();
        reviewResult = reviewResponse.Text;
        Console.WriteLine($"审查结果:\n{reviewResult}\n");
        
        if (reviewResult.Contains("APPROVE"))
        {
            Console.WriteLine("✅ 代码审查通过");
            return new CodeGenerationResult
            {
                Success = true,
                Specification = specification,
                Code = generatedCode,
                ReviewComments = reviewResult
            };
        }
        
        // 如果审查不通过,让代码生成 Agent 根据反馈改进
        Console.WriteLine("❌ 代码需要改进");
        await codeThread.AddMessageAsync($@"代码审查反馈:
{reviewResult}

请根据反馈改进代码");
        
        var improvedResponse = await codeThread.InvokeAsync();
        generatedCode = improvedResponse.Text;
        Console.WriteLine($"改进后的代码:\n{generatedCode}\n");
        
        reviewCount++;
    }
    
    return new CodeGenerationResult
    {
        Success = false,
        Message = "代码审查未通过,已达最大重试次数"
    };
}

public record CodeGenerationResult
{
    public bool Success { get; set; }
    public string? Specification { get; set; }
    public string? Code { get; set; }
    public string? ReviewComments { get; set; }
    public string? Message { get; set; }
}

// 使用
var result = await GenerateCodeAsync(
    "创建一个用户注册功能,包括邮箱验证和密码强度检查"
);

if (result.Success)
{
    Console.WriteLine("🎉 代码生成成功!");
    Console.WriteLine($"\n最终代码:\n{result.Code}");
}


实战 3:Workflow 编排(高级)

使用 MAF Workflow 声明式编排

using Microsoft.Extensions.AI.Agents.Workflows;

// 1. 定义 Workflow
var workflow = new WorkflowBuilder()
    .AddStep("analyze_requirement", async (context) =>
    {
        // 步骤 1: 需求分析
        var userRequirement = context.Input["requirement"].ToString();
        
        var thread = await requirementAgent.CreateThreadAsync();
        await thread.AddMessageAsync(userRequirement);
        var response = await thread.InvokeAsync();
        
        context.State["specification"] = response.Text;
        
        return WorkflowStepResult.Success();
    })
    .AddStep("generate_code", async (context) =>
    {
        // 步骤 2: 生成代码
        var specification = context.State["specification"].ToString();
        
        var thread = await codeGenAgent.CreateThreadAsync();
        await thread.AddMessageAsync($"根据以下规格生成代码:\n{specification}");
        var response = await thread.InvokeAsync();
        
        context.State["code"] = response.Text;
        context.State["review_count"] = 0;
        
        return WorkflowStepResult.Success();
    })
    .AddStep("review_code", async (context) =>
    {
        // 步骤 3: 审查代码
        var specification = context.State["specification"].ToString();
        var code = context.State["code"].ToString();
        
        var thread = await reviewAgent.CreateThreadAsync();
        await thread.AddMessageAsync($@"
规格:{specification}
代码:{code}

请审查并标注 APPROVE 或 REJECT");
        
        var response = await thread.InvokeAsync();
        context.State["review_result"] = response.Text;
        
        if (response.Text.Contains("APPROVE"))
        {
            return WorkflowStepResult.Success();
        }
        else
        {
            var reviewCount = (int)context.State["review_count"];
            if (reviewCount >= 3)
            {
                return WorkflowStepResult.Failure("审查失败次数过多");
            }
            
            context.State["review_count"] = reviewCount + 1;
            return WorkflowStepResult.Retry("need_improvement");
        }
    })
    .AddStep("improve_code", async (context) =>
    {
        // 步骤 4: 根据反馈改进
        var reviewResult = context.State["review_result"].ToString();
        
        var thread = await codeGenAgent.GetThreadAsync(
            context.State["code_thread_id"].ToString()
        );
        await thread.AddMessageAsync($"审查反馈:\n{reviewResult}\n\n请改进代码");
        var response = await thread.InvokeAsync();
        
        context.State["code"] = response.Text;
        
        // 返回到审查步骤
        return WorkflowStepResult.GoTo("review_code");
    })
    .Build();

// 2. 执行 Workflow
var workflowContext = new WorkflowContext
{
    Input = new Dictionary<string, object>
    {
        ["requirement"] = "创建一个线程安全的缓存管理器"
    }
};

await foreach (var update in workflow.RunStreamingAsync(workflowContext))
{
    Console.WriteLine($"[{update.StepName}] {update.Status}: {update.Message}");
}

if (workflowContext.IsCompleted)
{
    Console.WriteLine("✅ Workflow 完成");
    Console.WriteLine($"最终代码:\n{workflowContext.State["code"]}");
}


Agent 高级特性

1. 上下文管理(AIContextProvider)

为 Agent 提供动态上下文信息:

public class UserContextProvider : IAIContextProvider
{
    private readonly IHttpContextAccessor _httpContext;
    
    public async Task<string> GetContextAsync(AgentThread thread)
    {
        var userId = _httpContext.HttpContext.User.FindFirst("sub")?.Value;
        var userProfile = await _userService.GetProfileAsync(userId);
        
        return $@"当前用户信息:
- 姓名:{userProfile.Name}
- VIP 等级:{userProfile.VipLevel}
- 历史订单数:{userProfile.OrderCount}
- 偏好类别:{string.Join(", ", userProfile.Preferences)}";
    }
}

// 注册
var agent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "PersonalAssistant",
    Instructions = "你是一个个性化助手,根据用户信息提供定制服务",
    ContextProviders = new[]
    {
        new UserContextProvider(httpContextAccessor, userService)
    }
});

2. 中间件(Middleware)

在 Agent 执行前后添加自定义逻辑:

public class AuditMiddleware : IAgentMiddleware
{
    private readonly IAuditLogger _auditLogger;
    
    public async Task<AgentResponse> InvokeAsync(
        AgentThread thread,
        Func<Task<AgentResponse>> next)
    {
        var startTime = DateTime.UtcNow;
        
        // 记录请求
        await _auditLogger.LogAsync(new AuditEntry
        {
            ThreadId = thread.Id,
            Action = "AgentInvoke",
            Timestamp = startTime
        });
        
        try
        {
            // 执行 Agent
            var response = await next();
            
            // 记录响应
            await _auditLogger.LogAsync(new AuditEntry
            {
                ThreadId = thread.Id,
                Action = "AgentResponse",
                Success = true,
                Duration = DateTime.UtcNow - startTime
            });
            
            return response;
        }
        catch (Exception ex)
        {
            // 记录异常
            await _auditLogger.LogAsync(new AuditEntry
            {
                ThreadId = thread.Id,
                Action = "AgentError",
                Success = false,
                Error = ex.Message
            });
            
            throw;
        }
    }
}

// 使用
var agent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "Assistant",
    Middleware = new[]
    {
        new AuditMiddleware(auditLogger),
        new RateLimitMiddleware(),
        new CacheMiddleware()
    }
});

3. 审批流程(Human-in-the-Loop)

敏感操作需要人工审批:

public class ApprovalAgent : AIAgent
{
    private readonly IApprovalService _approvalService;
    
    public ApprovalAgent(
        IChatClient chatClient,
        IApprovalService approvalService,
        AIAgentOptions options)
        : base(chatClient, options)
    {
        _approvalService = approvalService;
    }
    
    protected override async Task<ChatResponse> OnToolCallAsync(
        AgentThread thread,
        FunctionCallContent toolCall)
    {
        // 检查是否需要审批
        if (RequiresApproval(toolCall.Name))
        {
            // 请求人工审批
            var approved = await _approvalService.RequestApprovalAsync(new ApprovalRequest
            {
                ThreadId = thread.Id,
                ToolName = toolCall.Name,
                Arguments = toolCall.Arguments,
                Reason = $"Agent 请求执行敏感操作: {toolCall.Name}"
            });
            
            if (!approved)
            {
                return new ChatResponse(new ChatMessage(
                    ChatRole.Tool,
                    $"操作被拒绝:{toolCall.Name} 未获得审批"
                ));
            }
        }
        
        // 执行工具调用
        return await base.OnToolCallAsync(thread, toolCall);
    }
    
    private bool RequiresApproval(string toolName)
    {
        var sensitiveTools = new[] { "delete_data", "transfer_money", "send_email_blast" };
        return sensitiveTools.Contains(toolName);
    }
}


生产环境最佳实践

1. 性能优化

// 使用缓存减少重复调用
var agent = new AIAgent(chatClient, new AIAgentOptions
{
    Name = "Assistant",
    ChatOptions = new ChatOptions
    {
        // 启用缓存
        CacheOptions = new CacheOptions
        {
            Enabled = true,
            Duration = TimeSpan.FromMinutes(10)
        }
    }
});

// 限制消息历史长度
var thread = await agent.CreateThreadAsync(new AgentThreadOptions
{
    MaxMessages = 20,  // 只保留最近 20 条消息
    MessageReducer = new SlidingWindowReducer(tokenLimit: 4000)
});

2. 错误处理与降级

public async Task<AgentResponse> SafeInvokeAsync(AgentThread thread)
{
    try
    {
        return await thread.InvokeAsync();
    }
    catch (ModelOverloadedException ex)
    {
        _logger.LogWarning("模型过载,切换到备用模型");
        
        // 降级到更轻量的模型
        var fallbackAgent = new AIAgent(fallbackChatClient, options);
        var fallbackThread = await fallbackAgent.GetThreadAsync(thread.Id);
        
        return await fallbackThread.InvokeAsync();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Agent 执行失败");
        
        return new AgentResponse
        {
            Text = "抱歉,系统暂时无法处理您的请求,请稍后重试。",
            IsError = true
        };
    }
}

3. 可观测性

// 添加 OpenTelemetry
var agent = new AIAgent(
    chatClient.UseOpenTelemetry(),
    new AIAgentOptions
    {
        Name = "Assistant",
        // 启用详细日志
        LogLevel = LogLevel.Debug
    }
);

// 自定义指标
var meterProvider = Sdk.CreateMeterProviderBuilder()
    .AddMeter("MyApp.Agents")
    .AddPrometheusExporter()
    .Build();

// 记录 Agent 调用
var meter = new Meter("MyApp.Agents");
var invocationCounter = meter.CreateCounter<long>("agent.invocations");
var responseTimer = meter.CreateHistogram<double>("agent.response_time");

var sw = Stopwatch.StartNew();
var response = await thread.InvokeAsync();
sw.Stop();

invocationCounter.Add(1, new KeyValuePair<string, object>("agent_name", agent.Name));
responseTimer.Record(sw.Elapsed.TotalSeconds);


总结

智能 Agent 系统的核心要点:

状态管理:AgentThread 自动维护对话上下文
身份定义:Instructions 赋予 Agent 专业能力
工具集成:统一管理 Agent 可用的工具
持久化:IMessageStore 支持对话恢复和审计
协作编排:多 Agent 协同完成复杂任务
生产特性:审批流程、错误处理、可观测性

记住:好的 Agent 系统 = 清晰的职责 + 完善的工具 + 灵活的编排 + 可靠的基础设施