news 2026/3/1 7:34:48

AgentFramework:错误处理策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AgentFramework:错误处理策略

概述

在开发 AI 代理应用时,错误处理是确保应用稳定性和用户体验的关键。本文将介绍完整的错误处理方法、代码示例和优雅处理失败的策略。

为什么错误处理很重要?

想象一下,如果你的 AI 助手在用户提问时突然崩溃,或者显示一堆技术错误信息,用户会有什么感受?

好的错误处理就像给你的应用装上"安全气囊",在出现问题时:

  • 保护应用不崩溃

  • 给用户友好的提示

  • 记录问题以便修复

  • 自动恢复或重试

常见的错误类型

1. 网络错误

  • API 调用超时

  • 网络连接中断

  • DNS 解析失败

2. API 错误

  • API 密钥无效

  • 配额超限

  • 速率限制

  • 模型不可用

3. 输入错误

  • 消息过长

  • 格式不正确

  • 包含非法内容

4. 系统错误

  • 内存不足

  • 磁盘空间不足

  • 依赖服务不可用

错误处理的基本原则

1. 捕获所有异常

❌ 不好的做法:不处理异常

public async Task<string> ProcessMessage(string message) { // 如果出错,整个应用会崩溃 var thread = new AgentThread(); await thread.AddUserMessageAsync(message); var response = await _agent.InvokeAsync(thread); return response.Content; }

✅ 好的做法:捕获并处理异常

public async Task<string> ProcessMessage(string message) { try { var thread = new AgentThread(); await thread.AddUserMessageAsync(message); var response = await _agent.InvokeAsync(thread); return response.Content; } catch (Exception ex) { // 记录错误 Console.WriteLine($"错误: {ex.Message}"); // 返回友好的错误消息 return "抱歉,我遇到了一些问题。请稍后再试。"; } }

2. 区分不同类型的错误

public async Task<string> ProcessMessageWithDetailedErrorHandling(string message) { try { var thread = new AgentThread(); await thread.AddUserMessageAsync(message); var response = await _agent.InvokeAsync(thread); return response.Content; } catch (HttpRequestException ex) { // 网络错误 Console.WriteLine($"网络错误: {ex.Message}"); return "网络连接出现问题,请检查网络后重试。"; } catch (TaskCanceledException ex) { // 超时错误 Console.WriteLine($"请求超时: {ex.Message}"); return "请求超时,请稍后重试。"; } catch (UnauthorizedAccessException ex) { // 认证错误 Console.WriteLine($"认证失败: {ex.Message}"); return "服务认证失败,请联系管理员。"; } catch (ArgumentException ex) { // 输入错误 Console.WriteLine($"输入错误: {ex.Message}"); return $"输入有误: {ex.Message}"; } catch (Exception ex) { // 其他未知错误 Console.WriteLine($"未知错误: {ex.Message}"); return "抱歉,发生了未知错误。我们会尽快修复。"; } }

3. 实现重试机制

对于临时性错误(如网络波动),应该自动重试。

public class RetryPolicy { private readonly int _maxRetries; private readonly TimeSpan _initialDelay; public RetryPolicy(int maxRetries = 3, TimeSpan? initialDelay = null) { _maxRetries = maxRetries; _initialDelay = initialDelay ?? TimeSpan.FromSeconds(1); } // 指数退避重试 public async Task<T> ExecuteWithRetryAsync<T>(Func<Task<T>> action) { int attempt = 0; TimeSpan delay = _initialDelay; while (true) { try { return await action(); } catch (Exception ex) when (IsTransientError(ex) && attempt < _maxRetries) { attempt++; Console.WriteLine($"尝试 {attempt}/{_maxRetries} 失败: {ex.Message}"); Console.WriteLine($"等待 {delay.TotalSeconds} 秒后重试..."); await Task.Delay(delay); // 指数退避:每次延迟时间翻倍 delay = TimeSpan.FromSeconds(delay.TotalSeconds * 2); } catch (Exception ex) { // 非临时性错误或重试次数用尽 Console.WriteLine($"操作失败: {ex.Message}"); throw; } } } // 判断是否为临时性错误 private bool IsTransientError(Exception ex) { return ex is HttpRequestException || ex is TaskCanceledException || ex is TimeoutException || (ex.Message?.Contains("429") ?? false) || // 速率限制 (ex.Message?.Contains("503") ?? false); // 服务不可用 } }

使用重试策略

public class ResilientAgentService { private readonly ChatCompletionAgent _agent; private readonly RetryPolicy _retryPolicy; public ResilientAgentService(ChatCompletionAgent agent) { _agent = agent; _retryPolicy = new RetryPolicy(maxRetries: 3); } public async Task<string> ProcessMessageAsync(string message) { return await _retryPolicy.ExecuteWithRetryAsync(async () => { var thread = new AgentThread(); await thread.AddUserMessageAsync(message); var response = await _agent.InvokeAsync(thread); return response.Content; }); } }

4. 实现断路器模式

当服务持续失败时,应该暂时停止调用,避免雪崩效应。

public class CircuitBreaker { private int _failureCount = 0; private DateTime _lastFailureTime = DateTime.MinValue; private CircuitState _state = CircuitState.Closed; private readonly int _failureThreshold; private readonly TimeSpan _timeout; public CircuitBreaker(int failureThreshold = 5, TimeSpan? timeout = null) { _failureThreshold = failureThreshold; _timeout = timeout ?? TimeSpan.FromMinutes(1); } public async Task<T> ExecuteAsync<T>(Func<Task<T>> action) { // 检查断路器状态 if (_state == CircuitState.Open) { // 检查是否可以尝试恢复 if (DateTime.UtcNow - _lastFailureTime > _timeout) { _state = CircuitState.HalfOpen; Console.WriteLine("断路器进入半开状态,尝试恢复..."); } else { throw new InvalidOperationException("服务暂时不可用,请稍后重试"); } } try { var result = await action(); // 成功,重置计数器 if (_state == CircuitState.HalfOpen) { _state = CircuitState.Closed; Console.WriteLine("断路器已关闭,服务恢复正常"); } _failureCount = 0; return result; } catch (Exception ex) { _failureCount++; _lastFailureTime = DateTime.UtcNow; Console.WriteLine($"操作失败 ({_failureCount}/{_failureThreshold}): {ex.Message}"); // 达到阈值,打开断路器 if (_failureCount >= _failureThreshold) { _state = CircuitState.Open; Console.WriteLine($"断路器已打开,将在 {_timeout.TotalSeconds} 秒后尝试恢复"); } throw; } } public CircuitState State => _state; } public enum CircuitState { Closed, // 正常状态 Open, // 断开状态(停止调用) HalfOpen // 半开状态(尝试恢复) }

使用断路器

public class ProtectedAgentService { private readonly ChatCompletionAgent _agent; private readonly CircuitBreaker _circuitBreaker; public ProtectedAgentService(ChatCompletionAgent agent) { _agent = agent; _circuitBreaker = new CircuitBreaker(failureThreshold: 5); } public async Task<string> ProcessMessageAsync(string message) { try { return await _circuitBreaker.ExecuteAsync(async () => { var thread = new AgentThread(); await thread.AddUserMessageAsync(message); var response = await _agent.InvokeAsync(thread); return response.Content; }); } catch (InvalidOperationException ex) when (ex.Message.Contains("服务暂时不可用")) { return "服务正在维护中,请稍后再试。"; } } }

完整的错误处理框架

1. 自定义异常类型

// 基础异常类 public class AgentException : Exception { public AgentException(string message) : base(message) { } public AgentException(string message, Exception innerException) : base(message, innerException) { } } // API 相关异常 public class ApiException : AgentException { public int? StatusCode { get; } public ApiException(string message, int? statusCode = null) : base(message) { StatusCode = statusCode; } } // 配额超限异常 public class QuotaExceededException : ApiException { public QuotaExceededException(string message) : base(message, 429) { } } // 输入验证异常 public class ValidationException : AgentException { public ValidationException(string message) : base(message) { } } // 配置异常 public class ConfigurationException : AgentException { public ConfigurationException(string message) : base(message) { } }

2. 错误处理中间件

public class ErrorHandlingMiddleware { private readonly ILogger _logger; public ErrorHandlingMiddleware(ILogger logger) { _logger = logger; } public async Task<Result<T>> ExecuteAsync<T>(Func<Task<T>> action) { try { var result = await action(); return Result<T>.Success(result); } catch (ValidationException ex) { _logger.LogWarning(ex, "输入验证失败"); return Result<T>.Failure("输入验证失败: " + ex.Message); } catch (QuotaExceededException ex) { _logger.LogWarning(ex, "配额超限"); return Result<T>.Failure("请求过于频繁,请稍后再试"); } catch (ApiException ex) { _logger.LogError(ex, "API 调用失败"); return Result<T>.Failure($"服务调用失败 (状态码: {ex.StatusCode})"); } catch (ConfigurationException ex) { _logger.LogError(ex, "配置错误"); return Result<T>.Failure("服务配置错误,请联系管理员"); } catch (Exception ex) { _logger.LogError(ex, "未知错误"); return Result<T>.Failure("发生未知错误,请稍后重试"); } } } // 结果类型 public class Result<T> { public bool IsSuccess { get; } public T Value { get; } public string Error { get; } private Result(bool isSuccess, T value, string error) { IsSuccess = isSuccess; Value = value; Error = error; } public static Result<T> Success(T value) => new(true, value, null); public static Result<T> Failure(string error) => new(false, default, error); }

3. 日志记录

public interface ILogger { void LogInfo(string message); void LogWarning(Exception ex, string message); void LogError(Exception ex, string message); } public class ConsoleLogger : ILogger { public void LogInfo(string message) { Console.WriteLine($"[INFO] {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"); } public void LogWarning(Exception ex, string message) { Console.WriteLine($"[WARN] {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"); Console.WriteLine($" 异常: {ex.Message}"); } public void LogError(Exception ex, string message) { Console.WriteLine($"[ERROR] {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"); Console.WriteLine($" 异常: {ex.Message}"); Console.WriteLine($" 堆栈: {ex.StackTrace}"); } }

4. 完整的错误处理服务

public class RobustAgentService { private readonly ChatCompletionAgent _agent; private readonly RetryPolicy _retryPolicy; private readonly CircuitBreaker _circuitBreaker; private readonly ErrorHandlingMiddleware _errorHandler; private readonly ILogger _logger; public RobustAgentService(ChatCompletionAgent agent) { _agent = agent; _retryPolicy = new RetryPolicy(maxRetries: 3); _circuitBreaker = new CircuitBreaker(failureThreshold: 5); _logger = new ConsoleLogger(); _errorHandler = new ErrorHandlingMiddleware(_logger); } public async Task<Result<string>> ProcessMessageAsync(string message) { return await _errorHandler.ExecuteAsync(async () => { // 输入验证 ValidateInput(message); // 使用断路器和重试策略 return await _circuitBreaker.ExecuteAsync(async () => { return await _retryPolicy.ExecuteWithRetryAsync(async () => { _logger.LogInfo($"处理消息: {message.Substring(0, Math.Min(50, message.Length))}..."); var thread = new AgentThread(); await thread.AddUserMessageAsync(message); var response = await _agent.InvokeAsync(thread); _logger.LogInfo("消息处理成功"); return response.Content; }); }); }); } private void ValidateInput(string message) { if (string.IsNullOrWhiteSpace(message)) throw new ValidationException("消息不能为空"); if (message.Length > 4000) throw new ValidationException("消息长度不能超过 4000 字符"); } }

使用示例

基本使用

public class Program { public static async Task Main(string[] args) { // 初始化代理 var chatClient = new AzureOpenAIClient( new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")), new ApiKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")) ).GetChatClient("gpt-35-turbo"); var agent = new ChatCompletionAgent( chatClient: chatClient, name: "RobustAgent", instructions: "你是一个可靠的助手" ); var service = new RobustAgentService(agent); // 处理用户消息 Console.WriteLine("请输入消息(输入 'exit' 退出):"); while (true) { Console.Write("\n用户: "); var input = Console.ReadLine(); if (input?.ToLower() == "exit") break; // 处理消息 var result = await service.ProcessMessageAsync(input); if (result.IsSuccess) { Console.WriteLine($"AI: {result.Value}"); } else { Console.WriteLine($"错误: {result.Error}"); } } } }

高级使用:带监控和告警

public class MonitoredAgentService { private readonly RobustAgentService _service; private int _totalRequests = 0; private int _successfulRequests = 0; private int _failedRequests = 0; public MonitoredAgentService(RobustAgentService service) { _service = service; } public async Task<Result<string>> ProcessMessageAsync(string message) { _totalRequests++; var startTime = DateTime.UtcNow; var result = await _service.ProcessMessageAsync(message); var duration = DateTime.UtcNow - startTime; if (result.IsSuccess) { _successfulRequests++; } else { _failedRequests++; // 如果失败率过高,发送告警 if (GetFailureRate() > 0.5) // 失败率超过 50% { SendAlert($"警告:失败率过高 ({GetFailureRate():P})"); } } // 记录指标 Console.WriteLine($"[指标] 总请求: {_totalRequests}, " + $"成功: {_successfulRequests}, " + $"失败: {_failedRequests}, " + $"成功率: {GetSuccessRate():P}, " + $"耗时: {duration.TotalSeconds:F2}秒"); return result; } private double GetSuccessRate() => _totalRequests > 0 ? (double)_successfulRequests / _totalRequests : 0; private double GetFailureRate() => _totalRequests > 0 ? (double)_failedRequests / _totalRequests : 0; private void SendAlert(string message) { Console.WriteLine($"\n🚨 告警: {message}\n"); // 实际实现:发送邮件、短信或推送通知 } }

错误处理检查清单

在部署应用之前,使用这个清单检查错误处理:

  • [ ]异常捕获

    • [ ] 所有 API 调用都有 try-catch

    • [ ] 区分不同类型的异常

    • [ ] 记录所有异常信息

  • [ ]重试机制

    • [ ] 实现了指数退避重试

    • [ ] 设置了合理的重试次数

    • [ ] 只对临时性错误重试

  • [ ]断路器

    • [ ] 实现了断路器模式

    • [ ] 设置了合理的失败阈值

    • [ ] 配置了恢复超时时间

  • [ ]用户体验

    • [ ] 错误消息友好易懂

    • [ ] 不暴露技术细节

    • [ ] 提供解决建议

  • [ ]日志记录

    • [ ] 记录所有错误

    • [ ] 包含足够的上下文信息

    • [ ] 不记录敏感信息

  • [ ]监控告警

    • [ ] 监控错误率

    • [ ] 配置告警阈值

    • [ ] 及时响应告警

小结

错误处理是构建可靠应用的基础,关键要点:

  1. 捕获所有异常:不要让应用崩溃

  2. 区分错误类型:不同错误不同处理

  3. 实现重试机制:自动恢复临时性错误

  4. 使用断路器:防止雪崩效应

  5. 友好的错误消息:让用户知道发生了什么

  6. 完善的日志:帮助快速定位问题

  7. 持续监控:及时发现和解决问题

记住:好的错误处理不是避免错误,而是优雅地处理错误

更多AIGC文章

RAG技术全解:从原理到实战的简明指南

更多VibeCoding文章

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/1 5:22:35

SLAM中的漂移是什么意思呢?请给出通俗的解释。

问题描述&#xff1a;SLAM中的漂移是什么意思呢&#xff1f;请给出通俗的解释。问题解答&#xff1a;一句话最通俗解释漂移 一步一步的小错误&#xff0c;走久了&#xff0c;位置就慢慢“偏走样了”。一、用人走路来理解“漂移”想象你在完全黑暗的房间里&#xff1a;每一步你…

作者头像 李华
网站建设 2026/2/21 21:55:32

【零信任架构落地难点突破】:Open-AutoGLM日志查询权限动态管控实战

第一章&#xff1a;Open-AutoGLM日志查询权限管控概述在分布式系统与自动化运维平台中&#xff0c;Open-AutoGLM 作为日志智能分析引擎&#xff0c;承担着关键的操作审计与故障追踪职责。为确保日志数据的安全性与合规性&#xff0c;必须对日志查询行为实施严格的权限管控机制。…

作者头像 李华
网站建设 2026/2/25 23:23:24

为什么顶级公司都在用Open-AutoGLM做日志加密?真相终于曝光

第一章&#xff1a;为什么顶级公司都在用Open-AutoGLM做日志加密&#xff1f;真相终于曝光在当今数据驱动的商业环境中&#xff0c;日志安全已成为企业信息安全体系的核心环节。越来越多的科技巨头悄然采用 Open-AutoGLM 进行日志加密处理&#xff0c;其背后不仅关乎合规性&…

作者头像 李华
网站建设 2026/2/27 9:23:40

JC/T 2726-2022玻璃纤维增强水泥GRC复合外墙板检测

GRC复合外墙板是指以GRC背附钢框架板为外侧面板&#xff0c;与中间保温材料层、内侧面板通过粘接与机械锚固方式复合制成的、用于建筑围护结构的非承重外墙板。JC/T 2726-2022玻璃纤维增强水泥GRC复合外墙板检测&#xff1a;测试项目测试标准热阻GB/T 13475空气声计权隔声量GB/…

作者头像 李华
网站建设 2026/2/24 7:36:55

Open-AutoGLM日志安全加固路径(4步打造零信任存储架构)

第一章&#xff1a;Open-AutoGLM 日志数据加密存储在 Open-AutoGLM 系统中&#xff0c;日志数据的安全性至关重要。为防止敏感信息泄露&#xff0c;所有日志在持久化前均需经过加密处理。系统采用 AES-256-GCM 模式对日志内容进行对称加密&#xff0c;确保数据的机密性与完整性…

作者头像 李华