AutoGen 通过反射为Agent注册FuntionCall - Agent 的配置化注册
1、传统的Function注册方式
1.1、相关Function
/// <summary> /// (供 Agent 调用) /// </summary> public class Tools { public Tools() { } [Function(functionName: "GetWeatherByDate", description: "获取指定日期某城市的天气预报")] public async Task<string> GetWeatherByDate([Description("城市名称")] string City, [Description("日期(YYYY-MM-DD)")] string Date) { return $"{City}:天气晴朗,温度28度,偏北风2级!"; } /// <summary> /// 回复用户投诉(支持多次回复) /// </summary> [Function(functionName: "GetWeatherList", description: "获取某城市指定日期范围内的天气预报列表")] public async Task<List<string>> GetWeatherList( [Description("城市名称")] string City, [Description("开始日期(YYYY-MM-DD)")] string StartDate, [Description("结束日期(YYYY-MM-DD)")] string EndDate) { List<string> results = new List<string>(); for(int i = 0; i < 7; i++) { results.Add($"{City}:天气晴朗,温度{35-i}度,偏北风{7-i}级!"); } return results; } }
商户两个简单的funciton ,均包含多个参数
1.2、传统注册模式(针对GetWeatherList)
// ① 创建 FunctionContract var functionContract = new FunctionContract { Name = "GetWeatherList", Description = "获取某城市指定日期范围内的天气预报列表", Parameters = new List<FunctionParameterContract> { new FunctionParameterContract { Name = "City", Description = "城市名称", IsRequired = true, ParameterType = typeof(string) }, new FunctionParameterContract { Name = "StartDate", Description = "开始日期(YYYY-MM-DD)", IsRequired = true, ParameterType = typeof(string) }, new FunctionParameterContract { Name = "EndDate", Description = "结束日期(YYYY-MM-DD)", IsRequired = true, ParameterType = typeof(string) } } }; // ② 创建 functionMap(函数执行逻辑) var functionMap = new Dictionary<string, Func<string, Task<string>>> { { functionContract.Name, async (args) => { var json = JsonDocument.Parse(args); var City = json.RootElement.GetProperty("City").GetString(); var StartDate = json.RootElement.GetProperty("StartDate").GetString(); var EndDate = json.RootElement.GetProperty("EndDate").GetString(); var result = await weatherTools.GetWeatherList(City!, StartDate!, EndDate!); return JsonSerializer.Serialize(result); } } }; // ③ 创建 FunctionCallMiddleware var functionCallMiddleware = new FunctionCallMiddleware( functions: new[] { functionContract }, functionMap: functionMap); var agentWithConnector = agent.RegisterMessageConnector(); var agentWithMiddleware = agentWithConnector.RegisterMiddleware(functionCallMiddleware); var finalAgent = agentWithMiddleware.RegisterPrintMessage(); return finalAgent;
函数有三个参数,在注册时,需要针对每个参数进行注册,如果后期修改为4个参数,则代码需要响应修改,可维护性极差!
1.3、新的注册方式(反射)
1.3.1、引入帮助类
using AutoGen.Core; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace CoordinatorS { /// <summary> /// Function 辅助工具(自动扫描 + 注册) /// </summary> public static class FunctionHelper { /// <summary> /// 从工具类自动扫描所有带 [Function] 特性的方法,创建 FunctionCallMiddleware /// </summary> /// <param name="toolsInstance">工具类实例(如 ComplaintTools)</param> /// <param name="functionNames">要注册的函数名列表(为空则注册全部)</param> public static FunctionCallMiddleware CreateMiddleware(object toolsInstance, params string[] functionNames) { var contracts = new List<FunctionContract>(); var functionMap = new Dictionary<string, Func<string, Task<string>>>(); var methods = toolsInstance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.GetCustomAttribute<FunctionAttribute>() != null); foreach (var method in methods) { var functionAttr = method.GetCustomAttribute<FunctionAttribute>(); var functionName = functionAttr?.FunctionName ?? method.Name; if (functionNames.Any() && !functionNames.Contains(functionName)) continue; var contract = new FunctionContract { Name = functionName, Description = functionAttr?.Description ?? method.GetCustomAttribute<DescriptionAttribute>()?.Description ?? "", Parameters = method.GetParameters() .Select(p => new FunctionParameterContract { Name = p.Name, Description = p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? "", IsRequired = !p.IsOptional, ParameterType = p.ParameterType, DefaultValue = p.DefaultValue }) .ToArray() }; contracts.Add(contract); // ✅ 支持任意返回类型的 functionMap functionMap[functionName] = async (args) => { try { var json = JsonDocument.Parse(args); var parameters = new List<object?>(); foreach (var param in contract.Parameters) { if (json.RootElement.TryGetProperty(param.Name, out var elem)) { var value = elem.Deserialize(param.ParameterType); parameters.Add(value); } else if (param.DefaultValue != null) { parameters.Add(param.DefaultValue); } else { parameters.Add(null); } } // ✅ 调用方法(不强制转 Task<string>) var result = method.Invoke(toolsInstance, parameters.ToArray()) as Task; if (result == null) { return "❌ 方法返回 null"; } await result; // ✅ 获取 Task.Result var resultProperty = result.GetType().GetProperty("Result"); if (resultProperty == null) { return "❌ 找不到 Result 属性"; } var resultValue = resultProperty.GetValue(result); // ✅ 已经是 string 直接返回 if (resultValue is string stringValue) { return stringValue; } // ✅ 否则序列化(支持任意类型) if (resultValue == null) { return "[]"; } return JsonSerializer.Serialize(resultValue, JsonOptions); // ← 用配置好的 options } catch (Exception ex) { return $"❌ 执行失败:{ex.Message}"; } }; } return new FunctionCallMiddleware( functions: contracts, functionMap: functionMap); } /// <summary> /// 从工具类自动扫描所有带 [Function] 特性的方法,返回函数名列表 /// </summary> public static string[] GetAvailableFunctions<T>() { return typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.GetCustomAttribute<FunctionAttribute>() != null) .Select(m => m.GetCustomAttribute<FunctionAttribute>()?.FunctionName ?? m.Name) .ToArray(); } private static readonly JsonSerializerOptions JsonOptions = new() { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = false // 不格式化(节省 Token) }; } }
1.3.2、注册方式
var middleware = FunctionHelper.CreateMiddleware( weatherTools, "GetWeatherList"); var agentWithConnector = agent.RegisterMessageConnector(); var agentWithMiddleware = agentWithConnector.RegisterMiddleware(middleware); var finalAgent = agentWithMiddleware.RegisterPrintMessage(); return finalAgent;
2、Agent 配置化-完整项目代码
1、AgentConfig
using AutoGen.Core; using AutoGen.OpenAI; using AutoGen.OpenAI.Extension; using Microsoft.Extensions.AI; using OpenAI; using System; using System.ClientModel; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CoordinatorS { /// <summary> /// Agent Code 枚举(全大写) /// </summary> public enum AgentCodeEnum { /// <summary> /// 查询指定日期某城市天气预报智能体的 Code /// </summary> WEATHER, /// <summary> /// 查询指定日期范围内某城市天气列表智能体的 Code /// </summary> WEATHER_LIST } /// <summary> /// Agent 配置 /// </summary> public class AgentConfig { /// <summary> /// Agent 代码(必须是大写字母,用于 JSON Schema enum) /// </summary> public string Code { get; set; } = ""; /// <summary> /// Agent 名称(人类可读,可以和 Code 不同) /// </summary> public string Name { get; set; } = ""; /// <summary> /// 职责描述 /// </summary> public string Description { get; set; } = ""; /// <summary> /// Agent 的 SystemMessage /// </summary> public string SystemMessage { get; set; } = ""; public FunctionCallExample[] Examples { get; set; } = Array.Empty<FunctionCallExample>(); } /// <summary> /// Function Calling 示例 /// </summary> public class FunctionCallExample { /// <summary> /// 用户输入 /// </summary> public string UserInput { get; set; } = ""; /// <summary> /// 期望的路由 Agent 代码 /// </summary> public string TargetAgent { get; set; } = ""; } /// <summary> /// 所有 Agent 配置(加新 Agent 在这里改) /// </summary> public static class AgentConfigs { public static readonly List<AgentConfig> All = new() { new AgentConfig { Code = AgentCodeEnum.WEATHER.ToString(), Name = "天气查询助手", // ✅ 人类友好的名称 Description = "查询某城市指定日期的天气情况", SystemMessage = @"你是天气查询助手,负责查询某城市指定日期的天气情况。 【职责】 1. 调用 GetWeatherByDate 查询单个日期的天气 2. 日期格式:YYYY-MM-DD 3. 返回:温度、湿度、风力等详细信息", Examples = new[] { new FunctionCallExample { UserInput = "帮我查一下昨天北京的天气情况", TargetAgent = AgentCodeEnum.WEATHER.ToString() }, new FunctionCallExample { UserInput = "帮我查一下北京的天气情况,默认查今天的天气", TargetAgent = AgentCodeEnum.WEATHER.ToString() } }, }, new AgentConfig { Code = AgentCodeEnum.WEATHER_LIST.ToString(), Name = "天气列表查询助手", // ✅ 和 Weather 区分开 Description = "获取某城市指定日期范围内的天气预报列表", SystemMessage = @"你是天气列表查询助手,负责查询某城市指定日期范围内的天气预报。 【职责】 1. 调用 GetWeatherList 查询日期范围内的天气列表 2. 日期格式:YYYY-MM-DD,范围最大 7 天 3. 返回:多日天气概览(最高温、最低温、天气状况)", // ✅ 修复拼写错误 Examples = new[] { new FunctionCallExample { UserInput = "帮我查询下北京这一周的天气情况", TargetAgent = AgentCodeEnum.WEATHER_LIST.ToString() }, new FunctionCallExample { UserInput = "帮我查询下苏州 2026-08-08 到 2026-08-13 日期范围的天气情况", TargetAgent = AgentCodeEnum.WEATHER_LIST.ToString() } }, } }; } }
2、Agent
using AutoGen.Core; using AutoGen.OpenAI; using AutoGen.OpenAI.Extension; using CoordinatorS; using OpenAI.Chat; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace ConsoleApp3 { /// <summary> /// 分支 Agent 创建器(使用 FunctionHelper 自动注册) /// </summary> public static class BranchAgents { /// <summary> /// 根据 Code 创建对应的 Agent /// </summary> public static IAgent Create(string code, ChatClient chatClient, Tools weatherTools) { var config = AgentConfigs.All.FirstOrDefault(a => a.Code == code); if (config == null) { throw new ArgumentException($"未知的 Agent 代码:{code}"); } Console.WriteLine($"🔧 创建分支 Agent: {code} ({config.Name})..."); // 创建基础 Agent var agent = new OpenAIChatAgent( name: config.Name, systemMessage: config.SystemMessage, chatClient: chatClient); // ✅ 根据 Code 注册对应的 Function(用 FunctionHelper 自动扫描) if (code == AgentCodeEnum.WEATHER.ToString()) { var middleware = FunctionHelper.CreateMiddleware( weatherTools, "GetWeatherByDate"); var agentWithConnector = agent.RegisterMessageConnector(); var agentWithMiddleware = agentWithConnector.RegisterMiddleware(middleware); var finalAgent = agentWithMiddleware.RegisterPrintMessage(); return finalAgent; } else if (code == AgentCodeEnum.WEATHER_LIST.ToString()) { var middleware = FunctionHelper.CreateMiddleware( weatherTools, "GetWeatherList"); var agentWithConnector = agent.RegisterMessageConnector(); var agentWithMiddleware = agentWithConnector.RegisterMiddleware(middleware); var finalAgent = agentWithMiddleware.RegisterPrintMessage(); return finalAgent; } else { var agentWithConnector = agent.RegisterMessageConnector(); var finalAgent = agentWithConnector.RegisterPrintMessage(); return finalAgent; } } } /// <summary> /// 分支 Agent 创建器(使用 FunctionHelper 自动注册) /// </summary> public static class BranchAgentsTest { /// <summary> /// 根据 Code 创建对应的 Agent /// </summary> public static IAgent Create(string code, ChatClient chatClient, Tools weatherTools) { var config = AgentConfigs.All.FirstOrDefault(a => a.Code == code); if (config == null) { throw new ArgumentException($"未知的 Agent 代码:{code}"); } Console.WriteLine($"🔧 创建分支 Agent: {code} ({config.Name})..."); // 创建基础 Agent var agent = new OpenAIChatAgent( name: config.Name, systemMessage: config.SystemMessage, chatClient: chatClient); // ✅ 根据 Code 注册对应的 Function(用 FunctionHelper 自动扫描) if (code == AgentCodeEnum.WEATHER.ToString()) { // ① 创建 FunctionContract var functionContract = new FunctionContract { Name = "GetWeatherByDate", Description = "获取指定日期某城市的天气预报", Parameters = new List<FunctionParameterContract> { new FunctionParameterContract { Name = "City", Description = "城市名称", IsRequired = true, ParameterType = typeof(string) }, new FunctionParameterContract { Name = "Date", Description = "查询日期(YYYY-MM-DD)", IsRequired = true, ParameterType = typeof(string) } } }; // ② 创建 functionMap(函数执行逻辑) var functionMap = new Dictionary<string, Func<string, Task<string>>> { { functionContract.Name, async (args) => { var json = JsonDocument.Parse(args); var City = json.RootElement.GetProperty("City").GetString(); var Date = json.RootElement.GetProperty("Date").GetString(); return await weatherTools.GetWeatherByDate(City!, Date!); } } }; // ③ 创建 FunctionCallMiddleware var functionCallMiddleware = new FunctionCallMiddleware( functions: new[] { functionContract }, functionMap: functionMap); var agentWithConnector = agent.RegisterMessageConnector(); var agentWithMiddleware = agentWithConnector.RegisterMiddleware(functionCallMiddleware); var finalAgent = agentWithMiddleware.RegisterPrintMessage(); return finalAgent; } else if (code == AgentCodeEnum.WEATHER_LIST.ToString()) { // ① 创建 FunctionContract var functionContract = new FunctionContract { Name = "GetWeatherList", Description = "获取某城市指定日期范围内的天气预报列表", Parameters = new List<FunctionParameterContract> { new FunctionParameterContract { Name = "City", Description = "城市名称", IsRequired = true, ParameterType = typeof(string) }, new FunctionParameterContract { Name = "StartDate", Description = "开始日期(YYYY-MM-DD)", IsRequired = true, ParameterType = typeof(string) }, new FunctionParameterContract { Name = "EndDate", Description = "结束日期(YYYY-MM-DD)", IsRequired = true, ParameterType = typeof(string) } } }; // ② 创建 functionMap(函数执行逻辑) var functionMap = new Dictionary<string, Func<string, Task<string>>> { { functionContract.Name, async (args) => { var json = JsonDocument.Parse(args); var City = json.RootElement.GetProperty("City").GetString(); var StartDate = json.RootElement.GetProperty("StartDate").GetString(); var EndDate = json.RootElement.GetProperty("EndDate").GetString(); var result = await weatherTools.GetWeatherList(City!, StartDate!, EndDate!); return JsonSerializer.Serialize(result); } } }; // ③ 创建 FunctionCallMiddleware var functionCallMiddleware = new FunctionCallMiddleware( functions: new[] { functionContract }, functionMap: functionMap); var agentWithConnector = agent.RegisterMessageConnector(); var agentWithMiddleware = agentWithConnector.RegisterMiddleware(functionCallMiddleware); var finalAgent = agentWithMiddleware.RegisterPrintMessage(); return finalAgent; } else { var agentWithConnector = agent.RegisterMessageConnector(); var finalAgent = agentWithConnector.RegisterPrintMessage(); return finalAgent; } } } }
3、Agent-Function
using AutoGen.Core; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp3 { /// <summary> /// (供 Agent 调用) /// </summary> public class Tools { public Tools() { } [Function(functionName: "GetWeatherByDate", description: "获取指定日期某城市的天气预报")] public async Task<string> GetWeatherByDate([Description("城市名称")] string City, [Description("日期(YYYY-MM-DD)")] string Date) { return $"{City}:天气晴朗,温度28度,偏北风2级!"; } /// <summary> /// 回复用户投诉(支持多次回复) /// </summary> [Function(functionName: "GetWeatherList", description: "获取某城市指定日期范围内的天气预报列表")] public async Task<List<string>> GetWeatherList( [Description("城市名称")] string City, [Description("开始日期(YYYY-MM-DD)")] string StartDate, [Description("结束日期(YYYY-MM-DD)")] string EndDate) { List<string> results = new List<string>(); for(int i = 0; i < 7; i++) { results.Add($"{City}:天气晴朗,温度{35-i}度,偏北风{7-i}级!"); } return results; } } }
4、FunctionHelper
using AutoGen.Core; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace CoordinatorS { /// <summary> /// Function 辅助工具(自动扫描 + 注册) /// </summary> public static class FunctionHelper { /// <summary> /// 从工具类自动扫描所有带 [Function] 特性的方法,创建 FunctionCallMiddleware /// </summary> /// <param name="toolsInstance">工具类实例(如 ComplaintTools)</param> /// <param name="functionNames">要注册的函数名列表(为空则注册全部)</param> public static FunctionCallMiddleware CreateMiddleware(object toolsInstance, params string[] functionNames) { var contracts = new List<FunctionContract>(); var functionMap = new Dictionary<string, Func<string, Task<string>>>(); var methods = toolsInstance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.GetCustomAttribute<FunctionAttribute>() != null); foreach (var method in methods) { var functionAttr = method.GetCustomAttribute<FunctionAttribute>(); var functionName = functionAttr?.FunctionName ?? method.Name; if (functionNames.Any() && !functionNames.Contains(functionName)) continue; var contract = new FunctionContract { Name = functionName, Description = functionAttr?.Description ?? method.GetCustomAttribute<DescriptionAttribute>()?.Description ?? "", Parameters = method.GetParameters() .Select(p => new FunctionParameterContract { Name = p.Name, Description = p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? "", IsRequired = !p.IsOptional, ParameterType = p.ParameterType, DefaultValue = p.DefaultValue }) .ToArray() }; contracts.Add(contract); // ✅ 支持任意返回类型的 functionMap functionMap[functionName] = async (args) => { try { var json = JsonDocument.Parse(args); var parameters = new List<object?>(); foreach (var param in contract.Parameters) { if (json.RootElement.TryGetProperty(param.Name, out var elem)) { var value = elem.Deserialize(param.ParameterType); parameters.Add(value); } else if (param.DefaultValue != null) { parameters.Add(param.DefaultValue); } else { parameters.Add(null); } } // ✅ 调用方法(不强制转 Task<string>) var result = method.Invoke(toolsInstance, parameters.ToArray()) as Task; if (result == null) { return "❌ 方法返回 null"; } await result; // ✅ 获取 Task.Result var resultProperty = result.GetType().GetProperty("Result"); if (resultProperty == null) { return "❌ 找不到 Result 属性"; } var resultValue = resultProperty.GetValue(result); // ✅ 已经是 string 直接返回 if (resultValue is string stringValue) { return stringValue; } // ✅ 否则序列化(支持任意类型) if (resultValue == null) { return "[]"; } return JsonSerializer.Serialize(resultValue, JsonOptions); // ← 用配置好的 options } catch (Exception ex) { return $"❌ 执行失败:{ex.Message}"; } }; } return new FunctionCallMiddleware( functions: contracts, functionMap: functionMap); } /// <summary> /// 从工具类自动扫描所有带 [Function] 特性的方法,返回函数名列表 /// </summary> public static string[] GetAvailableFunctions<T>() { return typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.GetCustomAttribute<FunctionAttribute>() != null) .Select(m => m.GetCustomAttribute<FunctionAttribute>()?.FunctionName ?? m.Name) .ToArray(); } private static readonly JsonSerializerOptions JsonOptions = new() { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = false // 不格式化(节省 Token) }; } }
5、main
using Applier; using AutoGen.Core; using CoordinatorS; using OpenAI; using System.ClientModel; namespace ConsoleApp3 { internal class Program { static async Task Main(string[] args) { Console.WriteLine("╔════════════════════════════════════╗"); Console.WriteLine("║ 天气查询 Agent 测试 ║"); Console.WriteLine("╚════════════════════════════════════╝"); Console.WriteLine(); try { // ① 初始化 OpenAI 客户端 Console.WriteLine("🔌 正在连接 OpenAI..."); var client = new OpenAIClient( new ApiKeyCredential(ConstParm.apiKey), new OpenAIClientOptions { Endpoint = new Uri("https://dashscope.aliyuncs.com/compatible-mode/v1") }); var chatClient = client.GetChatClient("qwen-plus"); // 通义千问 Console.WriteLine("✅ OpenAI 连接成功"); Console.WriteLine(); // ② 创建工具类实例 var weatherTools = new Tools(); // ③ 创建两个分支 Agent Console.WriteLine("🔧 创建 WEATHER Agent..."); var weatherAgent = BranchAgents.Create( AgentCodeEnum.WEATHER.ToString(), chatClient, weatherTools); Console.WriteLine("🔧 创建 WEATHER_LIST Agent..."); var weatherListAgent = BranchAgents.Create( AgentCodeEnum.WEATHER_LIST.ToString(), chatClient, weatherTools); Console.WriteLine(); // ④ 测试用例 1:查询北京今天天气 Console.WriteLine("════════════════════════════════════"); Console.WriteLine("📍 测试 1:北京天气怎么样?"); Console.WriteLine("════════════════════════════════════"); try { var message1 = new TextMessage(Role.User, "北京天气怎么样?", from: "User"); Console.WriteLine("⏳ 正在调用 AI..."); using var cts1 = new CancellationTokenSource(TimeSpan.FromSeconds(30)); var result1 = await weatherAgent.GenerateReplyAsync(new[] { message1 }, cancellationToken: cts1.Token); Console.WriteLine($"✅ 响应类型:{result1.GetType().Name}"); Console.WriteLine($"✅ 响应内容:{result1.GetContent()}"); } catch (OperationCanceledException) { Console.WriteLine("❌ 超时:30 秒无响应,请检查网络和 API Key"); } catch (Exception ex) { Console.WriteLine($"❌ 异常:{ex.Message}"); Console.WriteLine($" 类型:{ex.GetType().Name}"); Console.WriteLine($" 堆栈:{ex.StackTrace}"); if (ex.InnerException != null) { Console.WriteLine($" 内部异常:{ex.InnerException.Message}"); } } Console.WriteLine(); // ⑤ 测试用例 2:查询北京一周天气 Console.WriteLine("════════════════════════════════════"); Console.WriteLine("📍 测试 2:查询下北京这一周的天气"); Console.WriteLine("════════════════════════════════════"); try { var message2 = new TextMessage(Role.User, "查询下北京这一周的天气", from: "User"); Console.WriteLine("⏳ 正在调用 AI..."); using var cts2 = new CancellationTokenSource(TimeSpan.FromSeconds(30)); var result2 = await weatherListAgent.GenerateReplyAsync(new[] { message2 }, cancellationToken: cts2.Token); Console.WriteLine($"✅ 响应类型:{result2.GetType().Name}"); Console.WriteLine($"✅ 响应内容:{result2.GetContent()}"); } catch (OperationCanceledException) { Console.WriteLine("❌ 超时:30 秒无响应,请检查网络和 API Key"); } catch (Exception ex) { Console.WriteLine($"❌ 异常:{ex.Message}"); Console.WriteLine($" 类型:{ex.GetType().Name}"); Console.WriteLine($" 堆栈:{ex.StackTrace}"); if (ex.InnerException != null) { Console.WriteLine($" 内部异常:{ex.InnerException.Message}"); } } Console.WriteLine(); Console.WriteLine("════════════════════════════════════"); Console.WriteLine("✅ 测试完成!"); Console.WriteLine("════════════════════════════════════"); } catch (Exception ex) { Console.WriteLine($"❌ 主程序异常:{ex.Message}"); Console.WriteLine($" 类型:{ex.GetType().Name}"); Console.WriteLine($" 堆栈:{ex.StackTrace}"); } Console.WriteLine(); Console.WriteLine("按任意键退出..."); Console.ReadLine(); } } }
6/引用
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <Compile Remove="ConversationHistory.cs" /> </ItemGroup> <ItemGroup> <Compile Include="..\..\openClawTest\ConsoleApp1\ConstParm.cs" Link="ConstParm.cs" /> </ItemGroup> <ItemGroup> <PackageReference Include="AutoGen" Version="0.2.3" /> <PackageReference Include="AutoGen.OpenAI" Version="0.2.3" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" /> </ItemGroup> </Project>

浙公网安备 33010602011771号