
Agno AgentOS Human-in-the-Loop 模式实战与全链路测试验证指南【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno本指南以仓库中 05_human_in_the_loop/TEST_LOG.md 的实机测试记录为骨架结合同目录七个可运行示例与 Agno 源码系统讲解 AgentOS 的三种 HITLHuman-in-the-Loop暂停协议——临时确认/收集输入/外部执行、持久化 required 审批与 audit 审计记录——以及它们在一体化 Agent、Team 与 Workflow 中的差异化序列化与续跑机制。读完本文你将掌握如何通过PAUSED→ 人工决策 → 组件专属/continue的闭环把关键操作从自主执行安全地交回人类审批并用GET/POST /approvals完成持久化审批的落库与审计。背景TEST_LOG 验证了什么TEST_LOG 是 05_human_in_the_loop 目录的回归验证记录。测试日期 2026-07-24针对 Agno 源码提交37496c5ccd3be632cdbb97a9111a4a09999850fb全部 7 个 Python 示例以LIVE 模式真实启动 HTTP 服务并运行客户端通过无任何“构造性冒烟替代”construction-smoke substitutions。测试文件状态被测对象关键观测点basic.pyPASSconfirmation-agentPAUSED→确认工具→COMPLETEDuser_input.pyPASStrip-survey-agent/trip-planning-team两轮 requirement 输入传播external_execution.pyPASSemail-agent/communications-team外部执行结果回填续跑with_approval_record.pyPASSapproval-record-agentpending→approved持久化审批audit_record.pyPASSaudit-record-agent临时暂停落一条audit记录team_approval.pyPASSleader-approval-team/member-approval-team审批工具归属不同产生source_type差异workflow_hitl.pyPASSrelease-review-workflow三次step_requirements暂停按序续跑每组测试的共同基线是/health与/config返回 200且/config正确列出服务注册的组件agent、team 或 workflowID。例如 basic 场景/config列出confirmation-agentteam 场景同时列出trip-survey-agent与trip-planning-team。理解两种暂停契约临时 Requirement 与持久化 ApprovalREADME.md 将 AgentOS 的 HITL 归纳为两条并行的暂停契约契约一临时ephemeral暂停。由tool(requires_confirmationTrue)、tool(requires_user_inputTrue)或tool(external_executionTrue)触发。暂停仅存在于该持久化 runPersisted Run之上不会创建审批记录。调用方需解析返回的 tool 或 requirement然后调用该 run 的/continue路由。契约二持久化审批。由approval(typerequired)触发。除暂停 run 外还会在数据库中创建一条持久化的 approval 记录。管理员通过POST /approvals/{approval_id}/resolve或控制平面AgentOS Studio / 控制面的 Approvals 页面审批后run 才继续。第三种类型approval(typeaudit)则不同它不制造阻塞暂停而是在一次临时 HITL 决策被解析后把结果以audit记录的形式落库。因此它必须装饰在已经带有三种 HITL 标志之一的工具上这正是 audit_record.py 中approval(typeaudit)与tool(requires_confirmationTrue)叠加的原因。源码侧的依据在 agno/tools/decorator.py 中tool的参数表定义了requires_confirmation、requires_user_input、user_input_fields、external_execution与external_execution_silent约 72-76 行。其中user_input_fields声明哪些字段将由人类以用户输入方式提供给函数external_execution_silent在external_executionTrue时抑制冗长的暂停提示消息校验逻辑要求requires_user_input、requires_confirmation、external_execution三者同时最多只有一个为 True约 165-175 行若设置了user_input_fields则会自动把requires_user_input置为 True约 259-260 行。而 agno/approval/decorator.py 定义了ApprovalTyperequired/audit见 types.py以及approval的组合逻辑approval(typerequired)装饰在一个没有任何 HITL 标志的工具上时会自动补设requires_confirmationTrue这正是 with_approval_record.py 中approval(typerequired)叠在tool()之上即可生效的原因而approval(typeaudit)若下方工具缺少任一 HITL 标志则直接抛出ValueError。approval与tool两种书写顺序approval在上/在下均可组合实现通过栈上Function.approval_type或原始 callable 上的哨兵属性两种路径完成decorator.py 约 49-67 行。运行环境与双终端模式所有示例服务都监听7777 端口一次启动一个。仓库根目录下执行README.md 提供的 Setup./scripts/demo_setup.sh export OPENAI_API_KEYyour-key运行采用“服务端 --demo客户端”双终端模式例如 basic.py# 终端 1启动服务默认分支 .venvs/demo/bin/python cookbook/05_agent_os/05_human_in_the_loop/basic.py # 终端 2运行 HTTP 续跑客户端 .venvs/demo/bin/python cookbook/05_agent_os/05_human_in_the_loop/basic.py --demo其它文件沿用相同模式。每个文件内部均自带与其匹配的 HTTP continuation 客户端通过argparse的--demo分支启用服务端则通过agent_os.serve(appapp, port7777)启动 FastAPI 应用。唯一例外是workflow_hitl.py无需凭据credentials-free因为它每个 Workflow 步骤都使用本地 executor 函数不依赖 LLM 调用。三种暂停载荷的序列化差异README 明确定义了暂停决策在不同组件上的序列化字段与续跑路由这是理解全篇的关键表格暂停来源载荷字段续跑方式数据结构Agenttools/agents/{id}/runs/{run_id}/continue待确认的 tool 序列Teamrequirements/teams/{id}/runs/{run_id}/continueRunRequirement对象Workflowstep_requirements/workflows/{id}/runs/{run_id}/continueStepRequirement对象原则是把同样的结构解析填充决策后原样发送回组件专属的嵌套/continue路由。对持久化的 team 审批approval 记录本身始终是“行政决策的记录事实”decision of record而续跑载荷同时把已批准的决策带入被暂停的 team 或 member requirement 中team_approval.py 正是这一点的完整演示。场景一Agent 临时工具确认basic.pybasic.py 是最小闭环Agent 调用带requires_confirmationTrue的工具时 run 进入PAUSED客户端把返回工具中requires_confirmation为真的项置为confirmed: true后通过/continue续跑。核心服务端定义tool(requires_confirmationTrue) def restart_service(service: str) - str: Restart one service after the caller confirms the action. return fRestarted {service} confirmation_agent Agent( idconfirmation-agent, modelOpenAIResponses(idgpt-5.5), dbSqliteDb(idconfirmation-db, db_filetmp/agent_os_hitl_basic.db), tools[restart_service], instructions( When asked to restart a service, call restart_service immediately. Do not ask for confirmation in chat because the tool enforces it. ), )客户端续跑逻辑paused response.json() # POST /agents/{AGENT_ID}/runs assert paused[status] PAUSED pending_tools paused.get(tools) or [] for pending_tool in pending_tools: if pending_tool.get(requires_confirmation): pending_tool[confirmed] True # POST /agents/{AGENT_ID}/runs/{run_id}/continue, data{tools: json.dumps(pending_tools), ...}TEST_LOG 记录的实测结果Agent 在restart_service上返回PAUSED客户端设置confirmedtrue、把序列化后的 tools 提交到/continue后观察到COMPLETED结果文本为Restarted the billing service./health与/config返回 200 且/config列出confirmation-agent。场景二Team 多轮用户输入user_input.pyuser_input.py 演示 member agent 通过两次独立的requires_user_input工具调用分两轮收集旅行者信息——先name再destination与budget。每次调用都会暂停 team run客户端依据返回的 requirement schema 填写value与answeredTrue循环调用 team 的/continue直到完成。工具与 schema 形状tool(requires_user_inputTrue, user_input_fields[name]) def collect_name(name: str ) - str: return fTraveller: {name} tool(requires_user_inputTrue, user_input_fields[destination, budget]) def collect_preferences(destination: str , budget: str ) - str: return fPreferences: destination{destination}, budget{budget}值得注意的填充细节provide_values函数由于返回的RunRequirement载荷中user_input_schema会同时出现在 requirement 顶层与内嵌的tool_execution两个副本中客户端需要双份填充并把tool_execution[answered] True置位续跑才被正确识别。循环终止后断言至少经历两轮暂停。TEST_LOG 实测结果第一轮收集name第二轮按传播的 requirement 形状收集name、destination、budget最终 team 结果返回 Ada、Kyoto、2500 USD 且状态为COMPLETED/config同时列出trip-survey-agent与trip-planning-team。注意这里Team(...)同时注册了members[survey_agent]并设置了store_member_responsesTruemember 响应被保留供后续轮次使用。场景三外部执行副作用回填external_execution.pyexternal_execution.py 解决“副作用必须发生在 AgentOS 进程之外”的场景。send_email工具被标记external_executionTrue其函数体是空返回的描述性占位return ——真正的发送动作由客户端在收到暂停后执行。tool(external_executionTrue) def send_email(to: str, subject: str, body: str) - str: Describe an email operation that must run in the client process. return 客户端流程POST/teams/{TEAM_ID}/runs后读取requirements中每个tool_execution若external_execution_required为真则取出tool_args真实参数如to/subject执行外部动作的替身然后把结果同时写入requirement[external_execution_result]与tool_execution[result]最后续跑。TEST_LOG 实测结果客户端观察到精确的收件人与主题附加结果demo-message-001后续跑收到COMPLETED/config列出email-agent与communications-team。场景四持久化 required 审批with_approval_record.pywith_approval_record.py 引入approval(typerequired)。与临时暂停不同它同时创建数据库审批记录与暂停。客户端不再需要回填工具决策而是通过审批 API 完成行政管理approval(typerequired) tool() def deploy_release(service: str, version: str) - str: Deploy one service version after an administrator approves the record. return fDeployed {service} at version {version} # 数据库必须显式声明审批表 db SqliteDb(idapproval-record-db, db_filetmp/agent_os_required_approval.db, approvals_tableapprovals)审批三连操作GET 查询 → POST 解析 → 续跑GET /approvals参数run_id、statuspending、approval_typerequired期望恰好一条待审记录POST /approvals/{approval_id}/resolveJSON 载荷{status: approved, resolved_by: cookbook-admin}POST /agents/{AGENT_ID}/runs/{run_id}/continue——此时无需重发工具决策。TEST_LOG 实测结果记录行从pending变为approvedresolved_bycookbook-admin部署工具随后真正执行agent 返回COMPLETED/config列出approval-record-agent。场景五审计记录 auditaudit_record.pyaudit_record.py 演示approval(typeaudit)的“事后落账”语义它叠加在一个requires_confirmation工具上本身不额外制造暂停当客户端确认临时工具并续跑后AgentOS 会自动把决策结果以approval_typeaudit行写入审批表。approval(typeaudit) tool(requires_confirmationTrue) def rotate_api_key(service: str) - str: Rotate one service key after an operator confirms the action. return fRotated the API key for {service}续跑完成后客户端以GET /approvals?run_id...approval_typeaudit回读记录并断言恰好一条audit记录statusapproved工具名为rotate_api_key。TEST_LOG 将这一点表述为“审计装饰的临时工具暂停被确认续跑后 Approvals API 恰好返回一条audit行”。场景六审批工具的归属差异team_approval.pyteam_approval.py 对比持久化审批工具放在team leader与member agent两种位置的传播差异leader-approval-teammembers[]直接把approval(typerequired)工具approve_release挂到Team(tools[...])上——审批记录source_typeteammember-approval-team把approve_database_change交给成员database-specialistteam 只负责委派——审批记录source_typeagent。客户端通过递归函数find_approval_id在暂停的requirements载荷中定位嵌套的approval_id找不到时回退到GET /approvals?statuspending兜底然后GET /approvals/{approval_id}查看记录打印source_type与tool_namePOST /approvals/{approval_id}/resolvecookbook-admin批准把已批准决策写回 requirement——若tool_execution.requires_confirmation为真则同时设置requirement[confirmation]True与tool_execution[confirmed]True续跑 team。TEST_LOG 实测结果leader-approval-team产生source_typeteam、工具approve_release的记录member-approval-team产生source_typeagent、工具approve_database_change的记录两者均COMPLETED/config列出两个 team 与database-specialist。这印证了 README 的论断审批记录始终是行政决策的事实来源续跑载荷只是把已批准决策带入被暂停组件。场景七Workflow 三步 HITL 暂停workflow_hitl.pyworkflow_hitl.py 是 AgentOS 对 Workflow HITL 的“传输层视图”其完整原语矩阵见 cookbook/04_workflows/08_human_in_the_loop。该 Workflow 使用纯本地 executor无需 LLM 凭据三个 step 依次制造三类暂停from agno.workflow import HumanReview, OnReject from agno.workflow.types import UserInputField Step( nameInspect Release, executorinspect_release, human_reviewHumanReview(requires_confirmationTrue, confirmation_messageInspect this release now?, on_rejectOnReject.cancel), ), Step( nameChoose Environment, executorchoose_environment, human_reviewHumanReview(requires_user_inputTrue, user_input_schema[UserInputField(nameenvironment, field_typestr, descriptionDeployment environment, requiredTrue, allowed_values[staging, production])]), ), Step( nameDraft Change Record, executordraft_change_record, human_reviewHumanReview(requires_output_reviewTrue, output_review_messageApprove the drafted change record., on_rejectOnReject.cancel), ),客户端把每次返回的step_requirements载荷按类型解析后经/workflows/{id}/runs/{run_id}/continue续跑resolve_step_requirements优先级为未确认的requires_output_review先置confirmedTrue其次未确认的requires_confirmation最后未填的requires_user_input此时同步填充 schema 字段value与requirement[user_input]。TEST_LOG 实测结果三次续跑按序解析了 step confirmation、step user inputenvironmentstaging与 output reviewworkflow 以COMPLETED结束并返回被批准的变更记录/config列出release-review-workflow。验证结论与可复用断言TEST_LOG 末尾的 Validation 汇总了本次回归的工程化保障这些断言也可以直接复用到你自己的 AgentOS HITL 测试中递归模式校验精确检查 7 个 Python 文件0 违规对应仓库 check_cookbook_pattern.py 一类的模式约束应用自检七个应用全部可导入、可构建 OpenAPI并暴露/health、/config以及各自组件专属的 run / continuation 路由agent 的/agents/{id}/runs、team 的/teams/{id}/runs、workflow 的/workflows/{id}/runs各带嵌套/continue代码质量Ruff format 与 lint 定向通过行为正确性七个入库的 server/client 流全部 live 通过未使用构造性冒烟替代。判定一个 HITL 场景是否跑通的通用标尺综合七个场景的实测可以提炼如下验收清单首次调用返回statusPAUSEDagent 检查toolsteam 检查requirementsworkflow 检查step_requirements字段非空按组件类型解析载荷并回填决策确认标志、用户输入 schema 的value/answered、外部执行result调用与组件匹配的嵌套/continue路由若涉及approval(typerequired)先经POST /approvals/{id}/resolve把记录转为approved并记录resolved_by必要时再在载荷中携带approval_id终态为COMPLETED对审计场景额外断言GET /approvals恰好返回一条approval_typeaudit且statusapproved的记录治理面检查/health与/config返回 200/config列出注册的组件 ID。小结三种暂停与两类记录的协同模型将七个示例连起来看AgentOS 的 HITL 是一套清晰的四层模型三触发点requires_confirmation动作确认、requires_user_input数据收集、external_execution副作用外置三者互斥tools/decorator.py 强制校验两种持久化记录approval(typerequired)阻塞式审批记录 approval(typeaudit)事后审计记录approval/decorator.py 保证 audit 必须叠在 HITL 标志之上三类载荷通道Agent 的tools、Team 的requirements、Workflow 的step_requirements各自配对专属/continue路由一套控制面/approvals的查询与resolve路由 /health、/config可观测端点。TEST_LOG 通过 7 组 LIVE 回归证明上述机制无论工具挂在一体化 Agent、Team leader 还是 member agent 上也无论暂停来自临时决策还是持久化审批都能在真实的持久化 run 上完成“暂停—人类决策—续跑—审计”的全生命周期闭环。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考