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()
                }
            }, 
        }
    };
    }
}
View Code

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;
            }
        }
    }
}
View Code

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;
        } 
    }
}
View Code

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)
        };
    }
}
View Code

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();
        }
    }
}
View Code

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>

 

posted @ 2026-08-24 15:10  天才卧龙  阅读(10)  评论(0)    收藏  举报