Day 47:AutoGen 人类介入模式(Human-in-the-Loop)—— 让关键决策有人把关
欢迎来到第四十七天!昨天我们跑通了 AutoGen 的两人对话,理解了AssistantAgent和UserProxyAgent的基本用法。但在真实业务中,完全自动化的 Agent 往往不够安全:它可能生成错误代码、给出高风险建议、或者误解用户意图。Human-in-the-Loop(HITL,人类介入)让人类在关键节点参与对话,对 Agent 的输出进行审核、修正或批准,从而构建更安全、更可控的多智能体系统。今天我们将深入 AutoGen 的人类介入机制。
一、今日学习目标
- 理解 Human-in-the-Loop 的价值:安全审核、纠偏、关键决策把关。
- 掌握
human_input_mode的三种模式:ALWAYS、TERMINATE、NEVER的适用场景。 - 学会自定义
input_func,实现审批、修改、跳过等灵活的人类介入逻辑。 - 通过实战案例“代码生成审批助手”,体验人类在代码执行前的审核流程。
- 了解在多 Agent 群聊中如何嵌入人类参与,为后续 GroupChat 学习打基础。
二、详细实现步骤
步骤 1:理解 Human-in-the-Loop 的核心机制
AutoGen 中,人类介入主要通过UserProxyAgent的以下参数控制:
| 参数 | 作用 |
|---|---|
human_input_mode | 控制何时请求人类输入 |
input_func | 自定义输入函数,替代默认的input() |
max_consecutive_auto_reply | 限制自动回复轮数,避免无限循环 |
default_auto_reply | 人类不输入时的默认回复 |
is_termination_msg | 自定义终止条件 |
三种human_input_mode模式:
| 模式 | 行为 | 适用场景 |
|---|---|---|
"ALWAYS" | 每次 Agent 要回复前都请求人类输入 | 需要逐步审核、教学演示、高风险决策 |
"TERMINATE" | 仅在对话终止时请求人类确认 | 自动化流程 + 最后人工确认 |
"NEVER" | 从不请求人类输入,全自动 | 纯自动化任务、批量处理 |
步骤 2:环境准备
确保已安装pyautogen和python-dotenv。新建autogen_hitl.py,配置 DeepSeek:
importosfromdotenvimportload_dotenvimportautogen load_dotenv()config_list=[{"model":"deepseek-chat","api_key":os.getenv("DEEPSEEK_API_KEY"),"base_url":"https://api.deepseek.com",}]llm_config={"config_list":config_list,"temperature":0.3,}步骤 3:体验human_input_mode="ALWAYS"
这是最直接的人类介入模式:每次用户代理要发言时,都会暂停并等待人类输入。
assistant=autogen.AssistantAgent(name="助手",llm_config=llm_config,system_message="你是一个乐于助人的助手,回答简洁。")user_proxy=autogen.UserProxyAgent(name="人类用户",human_input_mode="ALWAYS",# 每次回复前请求人类输入max_consecutive_auto_reply=5,code_execution_config=False,)user_proxy.initiate_chat(assistant,message="请给我三个学习 Python 的建议。")运行后,控制台会提示你输入。你可以:
- 直接按回车:使用默认回复(通常是空或继续)。
- 输入具体内容:作为人类消息发送给助手。
- 输入
exit:退出对话(AutoGen 默认支持)。
适用场景:教学演示、逐步审核、需要人类频繁干预的对话。
步骤 4:体验human_input_mode="TERMINATE"
该模式只在对话即将终止时请求人类确认,适合“自动化执行 + 最后人工把关”。
assistant=autogen.AssistantAgent(name="助手",llm_config=llm_config,system_message="你是一个助手。完成任务后,请输出 TERMINATE。")user_proxy=autogen.UserProxyAgent(name="人类用户",human_input_mode="TERMINATE",# 仅在终止时请求输入max_consecutive_auto_reply=5,code_execution_config=False,)user_proxy.initiate_chat(assistant,message="请用一句话解释什么是机器学习。")运行后,对话会自动进行,直到助手输出TERMINATE,此时系统会请求你确认是否结束。你可以输入exit或继续对话。
适用场景:自动化流程中,最后一步由人类确认结果。
步骤 5:自定义input_func实现审批逻辑
默认的input()交互比较原始。我们可以自定义input_func,实现更结构化的审批:例如让人类输入approve、reject或modify:xxx。
defapproval_input(prompt:str,default:str="")->str:"""自定义输入函数:提供审批选项"""print("\n"+"="*50)print("需要人类审批:")print(prompt[:500])# 显示待审批内容的前 500 字符print("="*50)print("请输入:")print(" approve - 批准")print(" reject - 拒绝")print(" modify: - 修改(例如 modify:请补充数据来源)")print(" 直接回车 - 使用默认回复")user_input=input("你的选择:").strip()ifnotuser_input:returndefaultreturnuser_input将input_func传给UserProxyAgent:
user_proxy=autogen.UserProxyAgent(name="审批人",human_input_mode="ALWAYS",max_consecutive_auto_reply=5,code_execution_config=False,input_func=approval_input,)注意:AutoGen 的input_func签名可能因版本而异,通常接收prompt和可选的default。请以你安装的版本为准。如果版本不支持,可以使用human_input_mode="ALWAYS"配合默认input(),在人类输入时手动输入指令。
步骤 6:实战案例 —— 代码生成审批助手
场景:助手生成 Python 代码,人类在代码执行前审核。只有人类批准后,代码才会被执行。
# 助手:生成代码assistant=autogen.AssistantAgent(name="代码助手",llm_config=llm_config,system_message="""你是一个 Python 专家。当用户要求计算时,请生成 Python 代码。 代码必须放在 ```python ... ```代码块中。 生成代码后,等待人类审批。不要直接执行。""")# 人类代理:负责审批和执行user_proxy=autogen.UserProxyAgent(name="审批人",human_input_mode="ALWAYS",# 每次执行前请求人类max_consecutive_auto_reply=5,code_execution_config={"work_dir":"coding","use_docker":False,# 演示用,生产建议 True},)user_proxy.initiate_chat(assistant,message="请计算 1 到 100 的所有整数之和。")运行流程:
- 助手生成代码:
sum(range(1, 101))。 - 用户代理请求人类输入。你可以输入
approve或直接回车。 - 人类批准后,用户代理执行代码,将结果返回给助手。
- 助手根据结果给出最终答案。
安全提示:use_docker=False会在本地执行代码,存在安全风险。生产环境务必使用 Docker 沙箱:
code_execution_config={"work_dir":"coding","use_docker":True,}步骤 7:在对话中嵌入人类审核规则
我们可以在system_message中要求助手在关键节点主动请求人类确认。例如:
assistant=autogen.AssistantAgent(name="财务顾问",llm_config=llm_config,system_message="""你是一个财务顾问。在给出投资建议前,必须先向人类确认以下信息: 1. 用户的风险承受能力 2. 投资期限 3. 预期收益 只有人类确认后,才能给出建议。""")配合human_input_mode="ALWAYS",人类可以在每个关键节点介入。
步骤 8:理解多 Agent 群聊中的人类参与
在后续的GroupChat中,人类也可以作为一个参与者加入群聊。UserProxyAgent可以作为群聊成员,在需要时发言。今天先建立概念:
# 伪代码示意# groupchat = autogen.GroupChat(agents=[assistant1, assistant2, user_proxy], messages=[])# manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=llm_config)# user_proxy.initiate_chat(manager, message="...")人类可以在群聊中随时插入意见,影响讨论方向。这将在 Day 48-49 的辩论项目中详细展开。
三、常见问题与调试
Q1:human_input_mode="ALWAYS"导致程序阻塞,无法自动运行。
→ 这是预期行为。如果需要半自动,可以使用"TERMINATE"模式,或设置max_consecutive_auto_reply限制轮数。在脚本中可以通过管道输入模拟人类输入,例如echo "approve" | python script.py。
Q2:input_func参数报错,提示不支持。
→ AutoGen 不同版本 API 有差异。较新版本支持input_func,旧版本可能只支持默认input()。可以升级pyautogen,或改用human_input_mode="ALWAYS"并在输入时手动输入指令。
Q3:人类输入approve后,Agent 没有执行代码。
→ 检查code_execution_config是否正确配置。AutoGen 只有在检测到代码块时才会执行。确保助手生成的代码放在python ...中。也可以在人类输入中明确写“请执行代码”。
Q4:对话无法终止。
→ 设置max_consecutive_auto_reply,并在system_message中要求助手完成任务后输出TERMINATE。也可以自定义is_termination_msg。
Q5:人类输入为空时,对话卡住。
→ 设置default_auto_reply,当人类直接回车时使用默认回复。例如default_auto_reply="请继续。"。
Q6:代码执行报错,提示找不到工作目录。
→ 确保work_dir目录存在。可以在代码中先os.makedirs("coding", exist_ok=True)。
Q7:如何记录人类审批日志?
→ 在input_func中将人类输入写入日志文件,或使用 AutoGen 的logging功能。生产环境建议记录每次审批的内容、时间、审批人。
四、今日总结与作业
今天你完成了:
- ✅ 理解了 Human-in-the-Loop 的价值和适用场景。
- ✅ 掌握了
human_input_mode的三种模式:ALWAYS、TERMINATE、NEVER。 - ✅ 学会了自定义
input_func实现结构化审批。 - ✅ 通过“代码生成审批助手”案例,体验了人类在代码执行前的审核流程。
- ✅ 了解了多 Agent 群聊中人类参与的基本概念。
今日作业(必做):
- 修改“代码生成审批助手”,让人类在审批时可以选择
modify:请改用递归实现,助手根据人类意见修改代码。测试完整流程。 - 将
human_input_mode从"ALWAYS"改为"TERMINATE",运行同一个代码生成任务,观察人类介入时机的变化。 - 设计一个“客服升级”场景:当用户情绪激动或问题复杂时,Agent 主动请求人类客服介入。写出你的
system_message和input_func设计思路(可选写代码)。 - (思考题)在 AutoGen 群聊中,人类作为参与者可能打乱讨论节奏。你会如何设计规则,让人类只在关键时刻介入,而不干扰 Agent 之间的正常讨论?请用 150 字以内描述你的方案。
明日预告:我们将学习 AutoGen 的GroupChat(群聊)机制,创建多个 Agent 加一个人类用户的群聊,并理解GroupChatManager如何管理发言顺序。这是构建“投资辩论赛”项目的基础。
有任何问题欢迎随时评论!