ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AutoGen(.NET) UserProxyAgent 详解:用 ALWAYS / NEVER / AUTO 三种模式构建人类输入代理 Agent

AutoGen(.NET) UserProxyAgent 详解:用 ALWAYS / NEVER / AUTO 三种模式构建人类输入代理 Agent AutoGen(.NET) UserProxyAgent 详解用 ALWAYS / NEVER / AUTO 三种模式构建人类输入代理 Agent【免费下载链接】autogenA programming framework for agentic AI项目地址: https://gitcode.com/GitHub_Trending/au/autogen本文围绕 AutoGen(.NET) 框架中的UserProxyAgent展开。它是一类特殊的 Agent负责把终端用户的真实输入代理给另一个 Agent 或一组 Agent群聊使用是人机协作Human-in-the-Loop场景的核心组件。读完本文你将掌握如何以三种HumanInputMode模式创建和使用UserProxyAgent、它与AssistantAgent的等价关系以及底层HumanInputMiddleware的完整源码实现——包括退出关键字、终止消息[GROUPCHAT_TERMINATE]和可定制输入管道等细节。一、UserProxyAgent 是什么UserProxyAgent是一个用于代理用户输入的特殊 Agent在两个 Agent 对话时由它代表人类出场将用户敲入的文本作为回复消息发给接收方另一个 Agent 或群聊管理器。其定义位于 UserProxyAgent.cs它直接继承自ConversableAgent本身没有额外的实例逻辑全部行为由基类构造参数驱动。它支持三种人类输入模式HumanInputMode枚举定义于 ConversableAgent.cs模式取值行为ALWAYS1永远向用户询问输入把输入作为回复NEVER0从不询问用户使用默认回复defaultReply如果设置或回退到底层 LLM 模型生成回复如果提供了llmConfigAUTO2仅当对话被对方 Agent 以终止消息结束时才询问用户其余情况使用默认回复或底层 LLM 生成回复提示创建AssistantAgent时同样可以通过humanInputMode参数启停人类输入。UserProxyAgent等价于humanInputMode设为ALWAYS的AssistantAgent反过来AssistantAgent等价于humanInputMode设为NEVER的UserProxyAgent详见第四节源码对照。构造函数完整参数UserProxyAgent.cs 的构造函数签名如下所有参数透传给基类ConversableAgentpublic UserProxyAgent( string name, // Agent 名称用于消息的 From 字段 string systemMessage You are a helpful AI assistant, // 系统提示词 ConversableAgentConfig? llmConfig null, // 底层 LLM 配置AUTO/NEVER 模式下作为回退生成器 FuncIEnumerableIMessage, CancellationToken, Taskbool? isTermination null, // AUTO 模式的终止判定函数 HumanInputMode humanInputMode HumanInputMode.ALWAYS, // 人类输入模式默认 ALWAYS IDictionarystring, Funcstring, Taskstring? functionMap null, // 函数调用映射表 string? defaultReply null) // 默认回复文本注意两个默认值的差异UserProxyAgent的humanInputMode默认为ALWAYS天然代表人类而未显式提供llmConfig时它在NEVER/AUTO回退路径上会落到DefaultReplyAgent若连defaultReply也未设置则回复固定为Default reply is not set. Please pass a default reply to assistant agent见 ConversableAgent.cs。二、创建并使用 UserProxyAgent1. 最小示例ALWAYS 模式 SendAsync这是官方文档给出的最小可用片段源码位于 UserProxyAgentCodeSnippet.cscode_snippet_1区域// create a user proxy agent which always ask user for input var agent new UserProxyAgent( name: user, humanInputMode: HumanInputMode.ALWAYS); await agent.SendAsync(hello);运行后用户代理 Agent 会向控制台打印输入提示、读取用户输入并把该输入作为对hello这条消息的回复返回。对应的控制台交互效果如开头的截图所示。SendAsync(string)是AutoGen.Core提供的扩展方法AgentExtension.cs它会把字符串包装成TextMessage(Role.User, message)再调用GenerateReplyAsync完成一次收消息 → 出回复的往返。2. 实战示例UserProxyAgent 与 OpenAIChatAgent 对话更贴近真实场景的示例见 Example06_UserProxyAgent.csvar gpt4o LLMConfiguration.GetOpenAIGPT4o_mini(); var assistantAgent new OpenAIChatAgent( chatClient: gpt4o, name: assistant, systemMessage: You are an assistant that help user to do some tasks.) .RegisterMessageConnector() .RegisterPrintMessage(); // set human input mode to ALWAYS so that user always provide input var userProxyAgent new UserProxyAgent( name: user, humanInputMode: HumanInputMode.ALWAYS) .RegisterPrintMessage(); // start the conversation await userProxyAgent.InitiateChatAsync( receiver: assistantAgent, message: Hey assistant, please help me to do some tasks., maxRound: 10);要点说明RegisterPrintMessage()是打印中间件用于在控制台可视化每条消息示例中给双方 Agent 都挂上了InitiateChatAsyncAgentExtension.cs会创建一条以From agent.Name的初始Role.User消息然后把调用方和接收方组成一个RoundRobinGroupChat进行多轮往返maxRound控制最大轮数默认 10返回完整聊天历史在ALWAYS模式下每一轮到user发言时都会阻塞等待用户输入用户输入exit即结束整个群聊循环原理见下节运行该示例需要配置 OpenAI 凭据示例中的LLMConfiguration从环境变量读取并运行dotnet/samples/AgentChat/AutoGen.Basic.Sample项目。三、源码级原理HumanInputMiddleware 的三种模式分支三种输入模式的实际执行逻辑集中在 HumanInputMiddleware.cs 的InvokeAsyncL41-L85ConversableAgent.GenerateReplyAsync在每次生成回复前都会把它注册进中间件链// process order: function_call - human_input - inner_agent - default_reply - self_execute // first in, last out ... // process human input var humanInputMiddleware new HumanInputMiddleware(mode: this.humanInputMode, isTermination: this.IsTermination); agent.Use(humanInputMiddleware);NEVER直接透传给底层 Agentif (mode HumanInputMode.NEVER) { return await agent.GenerateReplyAsync(context.Messages, context.Options, cancellationToken); }不产生任何交互。此时回复由链条上更内层的 Agent 生成如果构造时传入了llmConfig则是底层 LLM AgentOpenAIChatAgent等否则是DefaultReplyAgent返回defaultReply。ALWAYS无条件询问用户if (mode HumanInputMode.ALWAYS) { this.writeLine(prompt); var input getInput(); if (input exitKeyword) { return new TextMessage(Role.Assistant, GroupChatExtension.TERMINATE, agent.Name); } input ?? string.Empty; return new TextMessage(Role.Assistant, input, agent.Name); }默认提示语为Please give feedback: Press enter or type exit to stop the conversation.退出关键字为exit输入exit时返回一条内容为GroupChatExtension.TERMINATE即常量字符串[GROUPCHAT_TERMINATE]定义于 GroupChatExtension.cs的助手消息群聊循环在 GroupChatExtension.SendAsync 中检测到终止消息后会yield break这正是用户输入exit能结束整段对话的原因直接回车input为 null会被归一化为空字符串string.Empty作为回复。AUTO对话未终止时走底层回复终止时才找人if (mode HumanInputMode.AUTO) { if (await isTermination(context.Messages, cancellationToken) is false) { return await agent.GenerateReplyAsync(context.Messages, context.Options, cancellationToken); } // ... 与 ALWAYS 相同的询问逻辑 }终止判定默认实现HumanInputMiddleware.cs是检查聊天历史最后一条消息是否包含群聊终止标记private async Taskbool DefaultIsTermination(IEnumerableIMessage messages, CancellationToken _) { return messages?.Last().IsGroupChatTerminateMessage() is true; }这意味着 AUTO 模式的典型用法是让 Agent 先自主跑完整个任务直到对方发出[GROUPCHAT_TERMINATE]人类才介入做总结性反馈。也可以传入自定义isTermination函数改写这一判定。可定制的输入/输出管道HumanInputMiddleware构造函数L25-L39暴露了五个可注入项这是文档之外的一个实用扩展点参数默认值说明promptPlease give feedback: Press enter or type exit to stop the conversation.询问用户的提示语exitKeywordexit触发终止消息的关键字modeHumanInputMode.AUTO输入模式getInputConsole.ReadLine读取输入的委托可替换为 Web 请求、数据库轮询等任意实现writeLineConsole.WriteLine打印提示的委托可重定向到日志或前端getInput是Funcstring?类型非阻塞场景下可替换为异步轮询外部输入源后再同步返回——从源码结构看这是把UserProxyAgent从控制台 Agent改造为服务化人机接口的关键注入点。四、UserProxyAgent 与 AssistantAgent同一个基类的两个默认值对照两个子类源码可以看到等价关系的实质AssistantAgent.cshumanInputMode默认参数为HumanInputMode.NEVER即默认永不询问用户UserProxyAgent.cshumanInputMode默认参数为HumanInputMode.ALWAYS即默认永远询问用户。两者构造函数参数列表完全一致都转发给ConversableAgent的 LLM 配置构造函数。因此官方文档的结论成立显式指定humanInputMode后两个类可以互相替代——new AssistantAgent(name, humanInputMode: HumanInputMode.ALWAYS)与new UserProxyAgent(name)行为相同。命名差异只是语义提示UserProxyAgent暗示我代表人AssistantAgent暗示我代表模型。五、消息处理管线与回复生成顺序理解UserProxyAgent何时问人、何时用模型需要看 ConversableAgent.GenerateReplyAsync 的组装逻辑系统消息补齐若历史中没有Role.System消息会把构造时的systemMessage插到消息头内层 Agent 选择有llmConfig时根据配置类型AzureOpenAIConfig/OpenAIConfig/LMStudioConfig创建对应的OpenAIChatAgent无配置时用DefaultReplyAgent(this.Name, defaultReply ?? Default reply is not set...)兜底L173-L176中间件注册顺序注释明确写出处理顺序为function_call - human_input - inner_agent - default_reply - self_execute且遵循 first in, last out——FunctionCallMiddleware在外、HumanInputMiddleware居中、内层 AgentLLM 或默认回复在最内。由此可以推断出一条清晰的优先级链先尝试函数调用再按模式决定是否交给人类最后才轮到 LLM / 默认回复兜底。UserProxyAgent因为默认ALWAYS在中间件阶段就把回复权交给了用户内层默认回复实际上只在用户直接回车返回空串时才显得无关紧要。六、小结与适用建议需要逐轮人工确认/纠偏的交互式任务使用UserProxyAgentHumanInputMode.ALWAYS配合InitiateChatAsync(maxRound: ...)控制上限输入exit随时终止需要Agent 自主跑完、人工只参与收尾的批处理式任务使用HumanInputMode.AUTO可结合自定义isTermination精确控制介入时机需要完全无交互、以模型或固定文本回复使用AssistantAgentNEVER并设置defaultReply或为UserProxyAgent传入llmConfig让模型接管。所有相关实现与示例均可在当前仓库中验证核心实现在 dotnet/src/AutoGen 目录Agent/UserProxyAgent.cs、Agent/ConversableAgent.cs、Middleware/HumanInputMiddleware.cs可复制运行的演示在 dotnet/samples/AgentChat/AutoGen.Basic.Sample 的Example06_UserProxyAgent.cs与CodeSnippet/UserProxyAgentCodeSnippet.cs。【免费下载链接】autogenA programming framework for agentic AI项目地址: https://gitcode.com/GitHub_Trending/au/autogen创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表