人在环与治理

一句话总结
在 agent 自主行动的关键节点插入人的审批/干预,并施加策略约束与审计:审批门、权限/策略 enforcement、签名审计轨迹。是把自主 agent 安全投入生产的刹车与方向盘。

它解决什么问题

完全自主的 agent 在高风险动作(付款、删除、对外发布)上不可控。HITL 与治理提供可控性、合规与可审计,平衡自主与安全(见 design-tradeoffs 的可控-自由轴)。

设计维度 / 实现谱系

  • 干预点:动作前审批 ↔ 关键节点暂停 ↔ 事后审查
  • 机制:中断-恢复(依赖 state-persistence)↔ 审批回调 ↔ 策略引擎
  • 治理位置:进程内 ↔ 进程外控制面(Cordum 的 pre-dispatch 策略 + 审批门 + 签名审计)
  • 策略:白/黑名单工具、权限范围、速率限制
  • 审计:结构化事件、不可篡改轨迹

关键要点

  • HITL 在工程上常落地为:可中断的循环 + 持久化状态 + 审批回调。
  • 进程外治理控制面是企业级生产的趋势(与具体框架解耦)。
  • 治理是自主性光谱(见 what-is-an-agent)向生产落地的必经环节。

关联

各框架实现对比

下表汇总 41 个实现了「人在环 / 治理」的框架(源码级阅读结论)。网站上以可展开 + 源码节选呈现。

框架实现方式
Aeon设计上 no approval loop(卖点:不打扰人)。可选治理层:Fleet Watcher——每技能跑前向自托管控制面问 ALLOW/BLOCK(fail-closed),跑后回报用于污点链分析;通知通道(Telegram/Discord/Slack)双向可让用户发指令;./onboard 校验配置
AG2human_input_mode 取 ALWAYS/NEVER/TERMINATE;check_termination_and_human_reply 作为最先执行的 reply func 拦截并征询人类(默认经控制台 IOStream,get_human_input);UserProxyAgent 是代表人类的预设 Agent;group/guardrails.py 与 safeguards/ 提供护栏
Agency Swarm治理=SDK 的 input/output guardrails(tripwire 触发→raise_input_guardrail_error 决定抛错还是回灌引导文本,可重试 validation_attempts 次,execution_helpers.py:86);通信流的有向授权本身即一种”谁能找谁”的访问控制。无内置 tool-approval 审批闸门
Agent-LLM (AGiXT)多租户 + RBAC:MagicalAuth.py 做认证/OAuth/角色,endpoints/Roles.py;extension 自动派生 ext::read/execute/configure 权限作用域;CriticalEndpointProtectionMiddleware/middleware.py 端点保护;可经聊天渠道由人审批/介入。无内置逐工具调用审批 UI(待确认)
AgentField双重:①执行级 app.pause() 把执行转 “waiting”,注册 future 后等审批 webhook 回调或超时恢复,crash-safe 可持久(execute_pause.go/webhook_approval.go);②访问治理 = 类 Okta IAM:tag-based ALLOW/DENY 访问策略(按 priority 降序求值)+ tag VC 校验 + 跨 agent 调用 Ed25519 签名
Agentic Context Engine (ACE)learn_from_feedback()/learn_from_traces() 让人提供纠错反馈或历史 trace 作为学习信号;Skillbook 可读(get_strategies)、可导出 markdown、可人工编辑后回载;CLAUDE.md 规定核心模块改动需人工批准。无运行时审批拦截
AgentScope规则化 PermissionEngine:5 种 mode(DEFAULT/ACCEPT_EDITS/EXPLORE/BYPASS/DONT_ASK) × 4 种 behavior(ALLOW/DENY/ASK/PASSTHROUGH),工具自报 is_read_only 与 check_permissions,危险路径/命令拦截;ASK→agent 产出 RequireUserConfirmEvent 暂停等外部确认,reply() 可喂回 UserConfirmResultEvent 续跑;外部执行经 RequireExternalExecutionEvent
Agentset治理=多租户 + API key + 配额:withNamespaceApiHandler 校验 org/namespace 归属(handler/namespace.ts:50),x-tenant-id 头解析租户(tenant.ts:6),Stripe 计费/isFreePlan 限额、Webhook 通知;无 LLM 动作审批/打断式 HITL
AgentVerse大部分自动化运行无内建审批;human-in-the-loop 主要见于:① Pokemon demo 玩家可作为一个 agent 实时介入对话(README);② task-solving Evaluator 有被注释掉的 human_eval 交互式打分分支(tasksolving_env/rules/base.py:148,默认走 LLM 评估)。无系统化治理/权限框架
Astron Agentworkflow 的 question_answer 节点做人在环:中断工作流等待用户,靠 EventRegistry 注册中断事件,支持 resume / ignore / abort 三种恢复事件;治理侧有 core/common/audit_system(审计)+ tenant 服务(多租户/空间隔离/配额)+ Casdoor 鉴权
AutoGenUserProxyAgent 把人类作为 agent 接入:on_messages 时调用可注入的 input_func(同步/异步均可)向人取输入,并发 UserInputRequestedEvent;group chat 中作为普通 participant 参与轮转;Handoff/HandoffTermination 可把控制权交回人
Botpress多重钩子做 guardrail:onExit 校验/拦截退出(如转账超额 throw)、onBeforeExecution 审查/改写生成代码(封禁危险操作)、onBeforeTool/onAfterTool 改 IO;Chat 模式 ListenExit 让位用户;平台侧有 HITL 插件(plugins/hitl)
ConnectOniontool_approval/shell_approval 插件在 before_each_tool 拦截危险操作请求审批(bashlex 解析命令);ask_user 工具+agent.io 与前端交互;plan_mode 工具
Cordum核心重点。① Safety Kernel 返回 5 类裁决 ALLOW/DENY/REQUIRE_HUMAN/THROTTLE/ALLOW_WITH_CONSTRAINTS(safety_client.go:235),Scheduler 在 dispatch 前据此分流:REQUIRE_APPROVAL→置 JobStateApproval 阻塞等待人审(engine.go:1596)、DENY→入 DLQ(engine.go:1608)、THROTTLE→延迟重排(engine.go:1549);② DENY-uncrossable 优先级(Global 不可被 Workflow 放宽)safetykernel/global_policy_tiers.go:92;③ 服务端 risk-tag 派生防客户端伪造低危标签(kernel.go:741);④ Edge 审批生命周期 pending/approved/rejected/expired/invalidated(core/edge/approval.go);⑤ ProvenanceGate:销毁性动作/requires_provenance 标签必须有已解析的审批记录+匹配审计事件,“approved by CFO” 之类纯文本声明一律 DENY(core/policy/actiongates/provenance_gate.go:68);⑥ Velocity/速率治理 safetykernel/velocity.go;⑦ fail-open 旁路会发专门审计事件 engine.go:1580
Cortex Memory多租户隔离(—tenant/X-Tenant-ID,tenant 后缀 collection)做数据边界;本地优先、零云依赖(MemClaw 主打隐私)。无审批/权限审查流
CrewAITask human_input=True:agent 出终答后请求人工反馈并据此再迭代;Flow 侧 human_feedback DSL 做流程级审批;before/after_kickoff 钩子
Dust工具按 stake 等级(never_ask/low/high,front/lib/actions/constants.ts:40)决定是否需审批;需审批时 step 循环中断等待 validateAction 用户批准后恢复(launchAgentLoopWorkflow);外加 RBAC、space/group 权限、publishing 限制、WorkOS 审计日志
HaystackAgent 支持 confirmation_strategies:按 tool 名映射 ConfirmationStrategy,工具执行前可拦截要求用户确认(BlockingConfirmationStrategy 等),含 ConfirmationPolicy/ConfirmationUI 协议,支持 web 场景注入 request-scoped 上下文(WebSocket 等);ToolExecutionDecision 记录决策
hcom人始终在环:每个 agent 跑在可见、可滚动、可打断的真实终端。安全命令白名单免审批、危险命令(stop/kill/run/reset)需显式批准(hooks/common.rs:51)。relay 跨设备为”全有或全无”信任域:enroll 即等于给该设备 shell 权限,无分级角色/只读 peer(README:147,165)
Hermes Agent危险命令审批:DANGEROUS_PATTERNS 检测→CLI 交互/gateway 异步提示→可选辅助 LLM 智能自动批低风险→永久 allowlist 落 config.yaml;HERMES_YOLO_MODE 导入期冻结防 prompt-injection 提权;clarify 工具向用户提问;gateway DM 配对/容器隔离
HiveHITL=节点 client_facing=True 暂停问人(开放问答/多选/是非/表单),状态存盘可挂起数天后恢复(新版收敛为仅 Queen 直面用户,见 edge.py:542 弃用告警);hard/soft constraint 治理(违反 hard→escalate);budget/cost 限额由 runtime 强制
LangChainHumanInTheLoopMiddleware 用 langgraph interrupt() 在工具执行前暂停征求批准/编辑/拒绝(InterruptOnConfig);create_agent(interrupt_before/after=…) 节点级中断;ShellToolMiddleware 带 Docker/Codex 沙箱执行策略;PII 中间件
Llama Agentic System (llama-stack-apps)治理核心=Llama Guard Shields:input_shields/output_shields 在推理前后做安全过滤(ShieldCallStep),含 code/cybersec shield 拦截工具调用代码;client.shields.list() 发现。无审批/打断式 HITL,但有人工反馈(“Ingest into Memory Bank”点赞写回)
LlamaIndex经 Workflow 的 InputRequiredEvent/HumanResponseEvent:工具内 ctx.write_event_to_stream(InputRequiredEvent) 暂停并 wait_for_event(HumanResponseEvent) 等人工输入再继续;无内置审批/权限沙箱,工具默认本进程执行
llm-agents唯一”人在环”是 run_agent.py 启动时 input() 收集一次问题;无审批/拦截/危险操作治理——PythonREPL 直接 exec() 任意代码,无沙箱(安全风险)
LoongFlow主要是 中断治理 而非审批:AgentBase.interrupt() 取消 asyncio task,PESAgent 经 _stop_event 优雅停机并终止全部评测子进程(SIGTERM→SIGKILL,evaluator.py:427);ReAct 可注册自定义 interrupt 处理器(react_agent.py:184);ClaudeCodeAgent 有 permission_mode(prompt/acceptEdits/acceptAll)但默认自动接受;无内置工具审批/危险命令拦截层
Maestro仅启动时 CLI 交互(目标/是否加文件/是否搜索);运行中全自动,无审批/中断/护栏;写文件无确认
Mastrasuspend/resume:workflow step 与 tool 均可声明 suspendSchema/resumeSchema,执行中 suspend() 暂停并把状态落 storage,之后 resume() 携用户输入恢复(可无限期暂停);requireToolApproval 工具审批;DurableAgent 把整次 agent 运行包成可持久/可恢复的 workflow
MetaGPTHumanProvider 把 is_human=True 的角色 LLM 调用替换成 input() 终端交互;Planner.ask_review(非 auto_run 时)让人审核/改计划;ActionNode.human_review 人工评审结构化产物;RoleZero.ask_human/reply_to_human 工具经 env.ask_human 向人提问
nanobotask_user 工具(支持 choices)向渠道发问;DM 发送者 pairing 审批(每渠道持久配对码,pairing/store.py);渠道 allow-list / 安全默认拒绝;SSRF 硬边界(私网 URL 不可绕过,runner.py:1043);shell allow-list;/stop 中途取消 turn 并保留部分上下文
Open Multi-AgentonPlanReady(tasks) 在任何 agent 执行前审批整份计划(返 false 中止);onApproval(completed,next) 在每轮任务之间审批;planOnly 只看不跑;AbortSignal 运行中取消;beforeRun/afterRun 钩子改写 prompt / 后处理结果;maxTokenBudget 硬性封顶花费
OpenClawDM pairing:未知发信人默认收到配对码、消息不被处理,openclaw pairing approve 后加入 allowlist(dmPolicy/allowFrom);沙箱:agents.defaults.sandbox.mode:“non-main” 让非 main 会话跑在 Docker/SSH/OpenShell 沙箱,默认 deny browser/canvas/nodes/cron/discord/gateway;beforeToolCall 钩子+ACP approval-classifier 对危险工具审批;openclaw doctor 体检风险配置
Pilot Protocol互信即治理:节点默认私有,必须双向 handshake 才能被解析/连接(“no mutual trust”会拒绝 find);—trust-auto-approve 可自动批准(demo 用),否则人工 pilotctl trust 审批;policy 插件用 expr-lang 表达式对 connect/dial/datagram/join/leave 等事件做策略判定
Pipecat实时交互而非审批治理:打断/barge-in——InterruptionFrame(携 asyncio.Event,到 sink 时 set)由用户轮次开始策略触发;轮次管理——UserTurnStrategies(start: VAD+转写; stop)判定用户起止说话;RTVIProcessor 作为客户端↔管道协议桥接收文本/音频/函数结果
PraisonAI@require_approval(risk_level=…) 标记高危工具→执行前 request_approval 走审批后端(console/自定义 callback);Guardrails(LLMGuardrail 或函数式)对输入/输出做校验+重试;Policy Engine 声明式行为控制;doom-loop 检测自动恢复
Semantic Kernel① IAutoFunctionInvocationFilter 在工具自动调用前后拦截,可设 context.Terminate=true 中止循环、把结果交还用户审批(FunctionCallsProcessor.cs:205/225/366 消费);② 编排层 OrchestrationInteractiveCallback / GroupChatManager ShouldRequestUserInput 请求人工输入;③ FunctionChoiceBehavior.None 让模型只建议不执行
Strands AgentsInterrupt/InterruptException 暂停 agent 等人类输入,经 session 持久化后 resume(agent.py:878);AfterInvocationEvent.resume 钩子可注入新输入续跑;experimental/steering 提供 LLM/ledger 引导;guardrail 触发 redactContent 自动脱敏(agent.py:1310)
SwarmClaw审批门:requestApproval/submitDecision,危险工具走 durable_wait 终端边界挂起等人审,审批后 wake 续跑;E-Stop 急停(estop);learned-skill 上线需人工审查;capability/tool 策略与权限预设(OpenClaw permission-presets);mission budget 上限(USD/token/turn/wallclock)
Swarmsinteractive=True 进入 REPL,每轮经 formatter.console.input 收用户输入(agent.py:1871);AgentRearrange flow DSL 支持插入 -> H -> 人审步骤 + custom_human_in_the_loop 回调;无细粒度工具审批/沙箱
UpsonicHITL 经异常驱动暂停/恢复:ConfirmationPause/UserInputPause/ExternalExecutionPause(tools/hitl.py:92,100,108),由 ToolConfig.requires_confirmation 等触发,agent.continue_run()(agent.py:4946) 恢复;治理经 safety engine 策略(user/agent/tool_pre/tool_post policy + feedback loop) + PII 匿名化
VoltAgent两条线:①Guardrails(input/output 方向,可设 severity/action 拦截校验 IO);②工具 needsApproval + Workflow suspend()/resume()(带 resumeSchema) 做审批挂起恢复(README 报销审批示例)

各框架实现对比 · 源码级

41 个框架实现该组件 · 39 个附源码节选 · 点击任意框架展开看实现要点与代码

Aeon yaml 设计上 no approval loop(卖点:不打扰人)。可选治理层:Fleet Watcher——每技能跑前向自托管控制面问 ALLOW/BLOCK(fail-closed),跑后回报用于污点链分析;通知通道(Telegram/Discord/Slack)双向可让用户发指令;./onboard 校验配置

设计上 no approval loop(卖点:不打扰人)。可选治理层:Fleet Watcher——每技能跑前向自托管控制面问 ALLOW/BLOCK(fail-closed),跑后回报用于污点链分析;通知通道(Telegram/Discord/Slack)双向可让用户发指令;./onboard 校验配置

github/workflows/aeon.yml:204github/workflows/aeon.yml:521github/workflows/messages.yml:468
.github/workflows/aeon.yml:204 yaml
      # If the secrets are not set, this step no-ops — backward compatible
      # with every existing AEON fork.
      # ──────────────────────────────────────────────────────────────────────
      - name: Fleet Watcher preflight
        id: fleet_preflight
        if: steps.work.outputs.mode != '' && env.FLEET_ENDPOINT != '' && env.FLEET_TOKEN != ''
        env:
          SKILL:     ${{ steps.skill.outputs.name }}
          SKILL_VAR: ${{ inputs.var }}
        run: |
          set -euo pipefail
          OP_ID="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-pre"
          BODY=$(jq -n \
查看 Aeon 完整笔记 →
AG2 python human_input_mode 取 ALWAYS/NEVER/TERMINATE;check_termination_and_human_reply 作为最先执行的 reply func 拦截并征询人类(默认经控制台 IOStream,get_human_input);UserProxyAgent 是代表人类的预设 Agent;group/guardrails.py 与 safeguards/ 提供护栏

human_input_mode 取 ALWAYS/NEVER/TERMINATE;check_termination_and_human_reply 作为最先执行的 reply func 拦截并征询人类(默认经控制台 IOStream,get_human_input);UserProxyAgent 是代表人类的预设 Agent;group/guardrails.py 与 safeguards/ 提供护栏

conversable_agent.py:189
autogen/agentchat/conversable_agent.py:189 python
        system_message: str | list | None = "You are a helpful AI Assistant.",
        is_termination_msg: Callable[[dict[str, Any]], bool] | None = None,
        max_consecutive_auto_reply: int | None = None,
        human_input_mode: Literal["ALWAYS", "NEVER", "TERMINATE"] = "TERMINATE",
        function_map: dict[str, Callable[..., Any]] | None = None,
        code_execution_config: dict[str, Any] | Literal[False] = False,
        llm_config: LLMConfig | dict[str, Any] | Literal[False] | None = None,
        default_auto_reply: str | dict[str, Any] = "",
        description: str | None = None,
        chat_messages: dict[Agent, list[dict[str, Any]]] | None = None,
        silent: bool | None = None,
        context_variables: Optional["ContextVariables"] = None,
        functions: list[Callable[..., Any]] | Callable[..., Any] = None,
查看 AG2 完整笔记 →
Agency Swarm python 治理=SDK 的 input/output guardrails(tripwire 触发→raise_input_guardrail_error 决定抛错还是回灌引导文本,可重试 validation_attempts 次,execution_helpers.py:86);通信流的有向授权本身即一种"谁能找谁"的访问控制。无内置 tool-approval 审批闸门

治理=SDK 的 input/output guardrails(tripwire 触发→raise_input_guardrail_error 决定抛错还是回灌引导文本,可重试 validation_attempts 次,execution_helpers.py:86);通信流的有向授权本身即一种"谁能找谁"的访问控制。无内置 tool-approval 审批闸门

agent/execution_helpers.py:115agency/core.py:83
src/agency_swarm/agent/execution_helpers.py:115 python
                kwargs=kwargs,
            )
            return run_result, master_context_for_run
        except OutputGuardrailTripwireTriggered as e:
            history_for_runner = append_guardrail_feedback(
                agent=agent,
                agency_context=agency_context,
                sender_name=sender_name,
                parent_run_id=parent_run_id,
                run_trace_id=run_trace_id,
                current_agent_run_id=current_agent_run_id,
                exception=e,
                include_assistant=True,
查看 Agency Swarm 完整笔记 →
Agent-LLM (AGiXT) python 多租户 + RBAC:MagicalAuth.py 做认证/OAuth/角色,endpoints/Roles.py;extension 自动派生 ext:<name>:read/execute/configure 权限作用域;CriticalEndpointProtectionMiddleware/middleware.py 端点保护;可经聊天渠道由人审批/介入。无内置逐工具调用审批 UI(待确认)

多租户 + RBAC:MagicalAuth.py 做认证/OAuth/角色,endpoints/Roles.py;extension 自动派生 ext:<name>:read/execute/configure 权限作用域;CriticalEndpointProtectionMiddleware/middleware.py 端点保护;可经聊天渠道由人审批/介入。无内置逐工具调用审批 UI(待确认)

middleware.py:258
agixt/middleware.py:258 python
                    "color": 15158332,  # Red color
                    "timestamp": datetime.utcnow().isoformat(),
                    "fields": [
                        {
                            "name": "Traceback",
                            "value": f"```python\n{tb_str[:1000]}{'...' if len(tb_str) > 1000 else ''}\n```",
                            "inline": False,
                        }
                    ],
                    "footer": {"text": f"{app_name} @ {agixt_server} | {timestamp}"},
                }
            ]
        }
查看 Agent-LLM (AGiXT) 完整笔记 →
AgentField go 双重:①执行级 app.pause() 把执行转 "waiting",注册 future 后等审批 webhook 回调或超时恢复,crash-safe 可持久(execute_pause.go/webhook_approval.go);②访问治理 = 类 Okta IAM:tag-based ALLOW/DENY 访问策略(按 priority 降序求值)+ tag VC 校验 + 跨 agent 调用 Ed25519 签名

双重:①执行级 app.pause() 把执行转 "waiting",注册 future 后等审批 webhook 回调或超时恢复,crash-safe 可持久(execute_pause.go/webhook_approval.go);②访问治理 = 类 Okta IAM:tag-based ALLOW/DENY 访问策略(按 priority 降序求值)+ tag VC 校验 + 跨 agent 调用 Ed25519 签名

agent.py:4369control-plane/internal/services/access_policy_service.go:68
sdk/python/agentfield/agent.py:4369 python
            thread.daemon = True
            thread.start()

    async def pause(
        self,
        approval_request_id: str,
        approval_request_url: str = "",
        expires_in_hours: int = 72,
        timeout: Optional[float] = None,
        execution_id: Optional[str] = None,
    ) -> ApprovalResult:
        """Pause the current execution for external approval.
查看 AgentField 完整笔记 →
Agentic Context Engine (ACE) python learn_from_feedback()/learn_from_traces() 让人提供纠错反馈或历史 trace 作为学习信号;Skillbook 可读(get_strategies)、可导出 markdown、可人工编辑后回载;CLAUDE.md 规定核心模块改动需人工批准。无运行时审批拦截

learn_from_feedback()/learn_from_traces() 让人提供纠错反馈或历史 trace 作为学习信号;Skillbook 可读(get_strategies)、可导出 markdown、可人工编辑后回载;CLAUDE.md 规定核心模块改动需人工批准。无运行时审批拦截

ace/runners/litellm.py:424
ace/runners/litellm.py:424 python
            raise RuntimeError("Learning is disabled. Call enable_learning() first.")
        return self._get_analyser().run(traces, epochs=epochs, wait=wait)

    def learn_from_feedback(
        self,
        feedback: str,
        ground_truth: str | None = None,
    ) -> bool:
        """Learn from the last :meth:`ask` interaction.

        Runs the standard ``learning_tail`` pipeline (ReflectStep,
        UpdateStep) on the most recent ``ask()`` call with the provided
        feedback. The agentic SkillManager mutates the skillbook directly
查看 Agentic Context Engine (ACE) 完整笔记 →
AgentScope python 规则化 PermissionEngine:5 种 mode(DEFAULT/ACCEPT_EDITS/EXPLORE/BYPASS/DONT_ASK) × 4 种 behavior(ALLOW/DENY/ASK/PASSTHROUGH),工具自报 is_read_only 与 check_permissions,危险路径/命令拦截;ASK→agent 产出 RequireUserConfirmEvent 暂停等外部确认,reply() 可喂回 UserConfirmResultEvent 续跑;外部执行经 RequireExternalExecutionEvent

规则化 PermissionEngine:5 种 mode(DEFAULT/ACCEPT_EDITS/EXPLORE/BYPASS/DONT_ASK) × 4 种 behavior(ALLOW/DENY/ASK/PASSTHROUGH),工具自报 is_read_only 与 check_permissions,危险路径/命令拦截;ASK→agent 产出 RequireUserConfirmEvent 暂停等外部确认,reply() 可喂回 UserConfirmResultEvent 续跑;外部执行经 RequireExternalExecutionEvent

permission/_engine.py:16permission/_types.py:18agent/_agent.py:882event/_event.py:46
src/agentscope/permission/_engine.py:16 python
    ToolBase = "ToolBase"


class PermissionEngine:
    """Engine for checking and enforcing permission rules.

    Evaluates tool execution requests against configured permission rules.
    Matching strategy is delegated to each tool's :meth:`ToolBase.match_rule`:

    - Bash tools: substring / prefix wildcard matching against the command
    - Write/Read/Edit tools: glob matching against file paths
    - Other tools: generic pattern matching (or tool-name-level only)
查看 AgentScope 完整笔记 →
Agentset typescript 治理=多租户 + API key + 配额:withNamespaceApiHandler 校验 org/namespace 归属(handler/namespace.ts:50),x-tenant-id 头解析租户(tenant.ts:6),Stripe 计费/isFreePlan 限额、Webhook 通知;无 LLM 动作审批/打断式 HITL

治理=多租户 + API key + 配额:withNamespaceApiHandler 校验 org/namespace 归属(handler/namespace.ts:50),x-tenant-id 头解析租户(tenant.ts:6),Stripe 计费/isFreePlan 限额、Webhook 通知;无 LLM 动作审批/打断式 HITL

apps/web/src/lib/api/handler/namespace.ts:50api/tenant.ts:6process-document.ts:394
apps/web/src/lib/api/handler/namespace.ts:50 typescript
  )();
};

export const withNamespaceApiHandler = (
  handler: NamespaceHandler,
  { logging }: { logging: false | { routeName: string } },
) => {
  return withApiHandler(
    async (params) => {
      const namespaceId = normalizeId(params.params.namespaceId ?? "", "ns_");
      if (!namespaceId) {
        throw new AgentsetApiError({
          code: "bad_request",
查看 Agentset 完整笔记 →
AgentVerse python 大部分自动化运行无内建审批;human-in-the-loop 主要见于:① Pokemon demo 玩家可作为一个 agent 实时介入对话(README);② task-solving Evaluator 有被注释掉的 human_eval 交互式打分分支(tasksolving_env/rules/base.py:148,默认走 LLM 评估)。无系统化治理/权限框架

大部分自动化运行无内建审批;human-in-the-loop 主要见于:① Pokemon demo 玩家可作为一个 agent 实时介入对话(README);② task-solving Evaluator 有被注释掉的 human_eval 交互式打分分支(tasksolving_env/rules/base.py:148,默认走 LLM 评估)。无系统化治理/权限框架

environments/tasksolving_env/rules/base.py:148
agentverse/environments/tasksolving_env/rules/base.py:148 python
        result: List[ExecutorMessage],
    ) -> Tuple[List[int], str]:
        """evaluation stage."""
        # if self.human_eval:
        #     print("This round, LLM gave the following result:")
        #     print(result)
        #     comprehensiveness = input("Please evaluate the comprehensiveness>> ")
        #     detailedness = input("Please evaluate the detailedness>> ")
        #     feasibility = input("Please evaluate the feasibility>> ")
        #     novelty = input("Please evaluate the novelty>> ")
        #     advice = input("Please give some advice>>")
        #     try:
        #         comprehensiveness = int(comprehensiveness)
查看 AgentVerse 完整笔记 →
Astron Agent python workflow 的 question_answer 节点做人在环:中断工作流等待用户,靠 EventRegistry 注册中断事件,支持 resume / ignore / abort 三种恢复事件;治理侧有 core/common/audit_system(审计)+ tenant 服务(多租户/空间隔离/配额)+ Casdoor 鉴权

workflow 的 question_answer 节点做人在环:中断工作流等待用户,靠 EventRegistry 注册中断事件,支持 resume / ignore / abort 三种恢复事件;治理侧有 core/common/audit_system(审计)+ tenant 服务(多租户/空间隔离/配额)+ Casdoor 鉴权

core/workflow/engine/nodes/question_answer/question_answer_node.py:174
core/workflow/engine/nodes/question_answer/question_answer_node.py:174 python
    incomplete_data: dict


class QuestionAnswerNode(BaseLLMNode):
    """
    Question-Answer node implementation for interactive workflows

    This node handles both option-based and direct answer types,
    supporting user interaction through interrupts and resume mechanisms.
    """

    _private_config: PrivateConfig = PrivateAttr(
        default_factory=lambda: PrivateConfig(timeout=None)
查看 Astron Agent 完整笔记 →
AutoGen python UserProxyAgent 把人类作为 agent 接入:on_messages 时调用可注入的 input_func(同步/异步均可)向人取输入,并发 UserInputRequestedEvent;group chat 中作为普通 participant 参与轮转;Handoff/HandoffTermination 可把控制权交回人

UserProxyAgent 把人类作为 agent 接入:on_messages 时调用可注入的 input_func(同步/异步均可)向人取输入,并发 UserInputRequestedEvent;group chat 中作为普通 participant 参与轮转;Handoff/HandoffTermination 可把控制权交回人

autogen-agentchat/src/autogen_agentchat/agents/_user_proxy_agent.py:37conditions/_terminations.py:313
python/packages/autogen-agentchat/src/autogen_agentchat/agents/_user_proxy_agent.py:37 python
    input_func: str | None = None


class UserProxyAgent(BaseChatAgent, Component[UserProxyAgentConfig]):
    """An agent that can represent a human user through an input function.

    This agent can be used to represent a human user in a chat system by providing a custom input function.

    .. note::

        Using :class:`UserProxyAgent` puts a running team in a temporary blocked
        state until the user responds. So it is important to time out the user input
        function and cancel using the :class:`~autogen_core.CancellationToken` if the user does not respond.
查看 AutoGen 完整笔记 →
Botpress typescript 多重钩子做 guardrail:onExit 校验/拦截退出(如转账超额 throw)、onBeforeExecution 审查/改写生成代码(封禁危险操作)、onBeforeTool/onAfterTool 改 IO;Chat 模式 ListenExit 让位用户;平台侧有 HITL 插件(plugins/hitl)

多重钩子做 guardrail:onExit 校验/拦截退出(如转账超额 throw)、onBeforeExecution 审查/改写生成代码(封禁危险操作)、onBeforeTool/onAfterTool 改 IO;Chat 模式 ListenExit 让位用户;平台侧有 HITL 插件(plugins/hitl)

packages/llmz/README.md:358packages/llmz/src/llmz.ts:280
packages/llmz/README.md:358 markdown

### Hooks: Custom Logic Injection

```typescript
const result = await execute({
  client,
  tools,
  hooks: {
    onTrace: (trace) => {
      // Non-blocking: log tool calls, errors, outputs
      logger.info(trace)
    },
    onExit: (exit) => {
查看 Botpress 完整笔记 →
ConnectOnion python tool_approval/shell_approval 插件在 before_each_tool 拦截危险操作请求审批(bashlex 解析命令);ask_user 工具+agent.io 与前端交互;plan_mode 工具

tool_approval/shell_approval 插件在 before_each_tool 拦截危险操作请求审批(bashlex 解析命令);ask_user 工具+agent.io 与前端交互;plan_mode 工具

查看 ConnectOnion 完整笔记 →
Cordum go 核心重点。① Safety Kernel 返回 5 类裁决 ALLOW/DENY/REQUIRE_HUMAN/THROTTLE/ALLOW_WITH_CONSTRAINTS(safety_client.go:235),Scheduler 在 dispatch 前据此分流:REQUIRE_APPROVAL→置 JobStateApproval 阻塞等待人审(engine.go:1596)、DENY→入 DLQ(engine.go:1608)、THROTTLE→延迟重排(engine.go:1549);② DENY-uncrossable 优先级(Global 不可被 Workflow 放宽)safetykernel/global_policy_tiers.go:92;③ 服务端 risk-tag 派生防客户端伪造低危标签(kernel.go:741);④ Edge 审批生命周期 pending/approved/rejected/expired/invalidated(core/edge/approval.go);⑤ ProvenanceGate:销毁性动作/requires_provenance 标签必须有已解析的审批记录+匹配审计事件,"approved by CFO" 之类纯文本声明一律 DENY(core/policy/actiongates/provenance_gate.go:68);⑥ Velocity/速率治理 safetykernel/velocity.go;⑦ fail-open 旁路会发专门审计事件 engine.go:1580

核心重点。① Safety Kernel 返回 5 类裁决 ALLOW/DENY/REQUIRE_HUMAN/THROTTLE/ALLOW_WITH_CONSTRAINTS(safety_client.go:235),Scheduler 在 dispatch 前据此分流:REQUIRE_APPROVAL→置 JobStateApproval 阻塞等待人审(engine.go:1596)、DENY→入 DLQ(engine.go:1608)、THROTTLE→延迟重排(engine.go:1549);② DENY-uncrossable 优先级(Global 不可被 Workflow 放宽)safetykernel/global_policy_tiers.go:92;③ 服务端 risk-tag 派生防客户端伪造低危标签(kernel.go:741);④ Edge 审批生命周期 pending/approved/rejected/expired/invalidated(core/edge/approval.go);⑤ ProvenanceGate:销毁性动作/requires_provenance 标签必须有已解析的审批记录+匹配审计事件,"approved by CFO" 之类纯文本声明一律 DENY(core/policy/actiongates/provenance_gate.go:68);⑥ Velocity/速率治理 safetykernel/velocity.go;⑦ fail-open 旁路会发专门审计事件 engine.go:1580

engine.go:1596safetykernel/kernel.go:706actiongates/provenance_gate.go:68
core/controlplane/safetykernel/kernel.go:706 go

	// Fail-closed: when no policy is loaded, deny all requests.
	// This prevents a misconfigured deployment from silently allowing everything.
	if policy == nil {
		return &pb.PolicyCheckResponse{
			Decision:       pb.DecisionType_DECISION_TYPE_DENY,
			Reason:         "no policy loaded — fail-closed",
			PolicySnapshot: snapshot,
		}, nil
	}

	if tenant == "" {
		tenant = defaultTenant
查看 Cordum 完整笔记 →
Cortex Memory rust 多租户隔离(--tenant/X-Tenant-ID,tenant 后缀 collection)做数据边界;本地优先、零云依赖(MemClaw 主打隐私)。无审批/权限审查流

多租户隔离(--tenant/X-Tenant-ID,tenant 后缀 collection)做数据边界;本地优先、零云依赖(MemClaw 主打隐私)。无审批/权限审查流

查看 Cortex Memory 完整笔记 →
CrewAI python Task human_input=True:agent 出终答后请求人工反馈并据此再迭代;Flow 侧 human_feedback DSL 做流程级审批;before/after_kickoff 钩子

Task human_input=True:agent 出终答后请求人工反馈并据此再迭代;Flow 侧 human_feedback DSL 做流程级审批;before/after_kickoff 钩子

crewai/task.py:227crewai/agents/crew_agent_executor.py:1596crewai/project/annotations.py:42
lib/crewai/src/crewai/task.py:227 python
        frozen=True,
        description="Unique identifier for the object, not set by user.",
    )
    human_input: bool | None = Field(
        description="Whether the task should have a human review the final answer of the agent",
        default=False,
    )
    markdown: bool | None = Field(
        description="Whether the task should instruct the agent to return the final answer formatted in Markdown",
        default=False,
    )
    converter_cls: Annotated[
        type[Converter] | None,
查看 CrewAI 完整笔记 →
Dust typescript 工具按 stake 等级(never_ask/low/high,front/lib/actions/constants.ts:40)决定是否需审批;需审批时 step 循环中断等待 validateAction 用户批准后恢复(launchAgentLoopWorkflow);外加 RBAC、space/group 权限、publishing 限制、WorkOS 审计日志

工具按 stake 等级(never_ask/low/high,front/lib/actions/constants.ts:40)决定是否需审批;需审批时 step 循环中断等待 validateAction 用户批准后恢复(launchAgentLoopWorkflow);外加 RBAC、space/group 权限、publishing 限制、WorkOS 审计日志

front/lib/api/assistant/conversation/validate_actions.ts:27front/temporal/agent_loop/workflows.ts:430front/lib/actions/constants.ts:45
front/lib/api/assistant/conversation/validate_actions.ts:27 typescript
import type { Result } from "@app/types/shared/result";
import { Err, Ok } from "@app/types/shared/result";

export async function validateAction(
  auth: Authenticator,
  conversation: ConversationResource,
  {
    actionId,
    approvalState,
    messageId,
    resumeAncestorConversations = false,
  }: {
    actionId: string;
查看 Dust 完整笔记 →
Haystack python Agent 支持 confirmation_strategies:按 tool 名映射 ConfirmationStrategy,工具执行前可拦截要求用户确认(BlockingConfirmationStrategy 等),含 ConfirmationPolicy/ConfirmationUI 协议,支持 web 场景注入 request-scoped 上下文(WebSocket 等);ToolExecutionDecision 记录决策

Agent 支持 confirmation_strategies:按 tool 名映射 ConfirmationStrategy,工具执行前可拦截要求用户确认(BlockingConfirmationStrategy 等),含 ConfirmationPolicy/ConfirmationUI 协议,支持 web 场景注入 request-scoped 上下文(WebSocket 等);ToolExecutionDecision 记录决策

human_in_the_loop/strategies.py:28human_in_the_loop/types/protocol.py:30agent.py:225
haystack/human_in_the_loop/strategies.py:28 python
USER_FEEDBACK_TEMPLATE = "With user feedback: {feedback}"


class BlockingConfirmationStrategy:
    """
    Confirmation strategy that blocks execution to gather user feedback.
    """

    def __init__(
        self,
        *,
        confirmation_policy: ConfirmationPolicy,
        confirmation_ui: ConfirmationUI,
查看 Haystack 完整笔记 →
hcom rust 人始终在环:每个 agent 跑在可见、可滚动、可打断的真实终端。安全命令白名单免审批、危险命令(stop/kill/run/reset)需显式批准(hooks/common.rs:51)。relay 跨设备为"全有或全无"信任域:enroll 即等于给该设备 shell 权限,无分级角色/只读 peer(README:147,165)

人始终在环:每个 agent 跑在可见、可滚动、可打断的真实终端。安全命令白名单免审批、危险命令(stop/kill/run/reset)需显式批准(hooks/common.rs:51)。relay 跨设备为"全有或全无"信任域:enroll 即等于给该设备 shell 权限,无分级角色/只读 peer(README:147,165)

hooks/common.rs:51
src/hooks/common.rs:51 rust
/// agents need to run without user approval prompts.
/// Excluded: `stop`, `kill`, `run`, `reset` — these are destructive or
/// admin-level and require explicit user approval.
pub(crate) const SAFE_HCOM_COMMANDS: &[&str] = &[
    "send",
    "start",
    "help",
    "--help",
    "-h",
    "list",
    "events",
    "listen",
    "relay",
查看 hcom 完整笔记 →
Hermes Agent python 危险命令审批:DANGEROUS_PATTERNS 检测→CLI 交互/gateway 异步提示→可选辅助 LLM 智能自动批低风险→永久 allowlist 落 config.yaml;HERMES_YOLO_MODE 导入期冻结防 prompt-injection 提权;clarify 工具向用户提问;gateway DM 配对/容器隔离

危险命令审批:DANGEROUS_PATTERNS 检测→CLI 交互/gateway 异步提示→可选辅助 LLM 智能自动批低风险→永久 allowlist 落 config.yaml;HERMES_YOLO_MODE 导入期冻结防 prompt-injection 提权;clarify 工具向用户提问;gateway DM 配对/容器隔离

tools/approval.py:1
tools/approval.py:1 python
"""Dangerous command approval -- detection, prompting, and per-session state.

This module is the single source of truth for the dangerous command system:
- Pattern detection (DANGEROUS_PATTERNS, detect_dangerous_command)
- Per-session approval state (thread-safe, keyed by session_key)
- Approval prompting (CLI interactive + gateway async)
- Smart approval via auxiliary LLM (auto-approve low-risk commands)
- Permanent allowlist persistence (config.yaml)
"""
查看 Hermes Agent 完整笔记 →
Hive python HITL=节点 client_facing=True 暂停问人(开放问答/多选/是非/表单),状态存盘可挂起数天后恢复(新版收敛为仅 Queen 直面用户,见 edge.py:542 弃用告警);hard/soft constraint 治理(违反 hard→escalate);budget/cost 限额由 runtime 强制

HITL=节点 client_facing=True 暂停问人(开放问答/多选/是非/表单),状态存盘可挂起数天后恢复(新版收敛为仅 Queen 直面用户,见 edge.py:542 弃用告警);hard/soft constraint 治理(违反 hard→escalate);budget/cost 限额由 runtime 强制

schemas/goal.py:37
core/framework/schemas/goal.py:37 python
    model_config = {"extra": "allow"}


class Constraint(BaseModel):
    id: str
    description: str
    constraint_type: str = Field(description="Type: 'hard' (must not violate) or 'soft' (prefer not to violate)")
    category: str = Field(default="general", description="Category: 'time', 'cost', 'safety', 'scope', 'quality'")
    check: str = Field(default="", description="How to check: expression, function name, or 'llm_judge'")

    model_config = {"extra": "allow"}

查看 Hive 完整笔记 →
LangChain python HumanInTheLoopMiddleware 用 langgraph interrupt() 在工具执行前暂停征求批准/编辑/拒绝(InterruptOnConfig);create_agent(interrupt_before/after=...) 节点级中断;ShellToolMiddleware 带 Docker/Codex 沙箱执行策略;PII 中间件

HumanInTheLoopMiddleware 用 langgraph interrupt() 在工具执行前暂停征求批准/编辑/拒绝(InterruptOnConfig);create_agent(interrupt_before/after=...) 节点级中断;ShellToolMiddleware 带 Docker/Codex 沙箱执行策略;PII 中间件

agents/middleware/human_in_the_loop.py:1factory.py:708middleware/shell_tool.py:1
libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py:1 python
"""Human in the loop middleware."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Literal, Protocol

from langchain_core.messages import AIMessage, ToolCall, ToolMessage
from langgraph.config import get_config
from langgraph.prebuilt.tool_node import ToolRuntime
from langgraph.types import interrupt
查看 LangChain 完整笔记 →
Llama Agentic System (llama-stack-apps) python 治理核心=Llama Guard Shields:input_shields/output_shields 在推理前后做安全过滤(ShieldCallStep),含 code/cybersec shield 拦截工具调用代码;client.shields.list() 发现。无审批/打断式 HITL,但有人工反馈("Ingest into Memory Bank"点赞写回)

治理核心=Llama Guard Shields:input_shields/output_shields 在推理前后做安全过滤(ShieldCallStep),含 code/cybersec shield 拦截工具调用代码;client.shields.list() 发现。无审批/打断式 HITL,但有人工反馈("Ingest into Memory Bank"点赞写回)

examples/agents/simple_chat.py:30docs/sequence-diagram.md:14examples/agent_store/app.py:66
examples/agents/simple_chat.py:30 python
        provider_data={"tavily_search_api_key": os.getenv("TAVILY_SEARCH_API_KEY")},
    )

    available_shields = [shield.identifier for shield in client.shields.list()]
    if not available_shields:
        print(colored("No available shields. Disabling safety.", "yellow"))
    else:
        print(f"Available shields found: {available_shields}")

    if model_id is None:
        model_id = get_any_available_model(client)
        if model_id is None:
            return
查看 Llama Agentic System (llama-stack-apps) 完整笔记 →
LlamaIndex python 经 Workflow 的 InputRequiredEvent/HumanResponseEvent:工具内 ctx.write_event_to_stream(InputRequiredEvent) 暂停并 wait_for_event(HumanResponseEvent) 等人工输入再继续;无内置审批/权限沙箱,工具默认本进程执行

经 Workflow 的 InputRequiredEvent/HumanResponseEvent:工具内 ctx.write_event_to_stream(InputRequiredEvent) 暂停并 wait_for_event(HumanResponseEvent) 等人工输入再继续;无内置审批/权限沙箱,工具默认本进程执行

workflow/events.py:1agent/workflow/base_agent.py:817
llama-index-core/llama_index/core/workflow/events.py:1 python
from workflows.events import (
    Event,  # noqa
    EventType,  # noqa
    HumanResponseEvent,  # noqa
    InputRequiredEvent,  # noqa
    StartEvent,  # noqa
    StopEvent,  # noqa
)
查看 LlamaIndex 完整笔记 →
llm-agents python 唯一"人在环"是 run_agent.py 启动时 input() 收集一次问题;无审批/拦截/危险操作治理——PythonREPL 直接 exec() 任意代码,无沙箱(安全风险)

唯一"人在环"是 run_agent.py 启动时 input() 收集一次问题;无审批/拦截/危险操作治理——PythonREPL 直接 exec() 任意代码,无沙箱(安全风险)

run_agent.py:4tools/python_repl.py:21
run_agent.py:4 python
from llm_agents import Agent, ChatLLM, PythonREPLTool, HackerNewsSearchTool, SerpAPITool

if __name__ == '__main__':
    prompt = input("Enter a question / task for the agent: ")
    agent = Agent(llm=ChatLLM(), tools=[PythonREPLTool(), SerpAPITool(), HackerNewsSearchTool()])
    result = agent.run(prompt)

    print(f"Final answer is {result}")
查看 llm-agents 完整笔记 →
LoongFlow python 主要是 中断治理 而非审批:AgentBase.interrupt() 取消 asyncio task,PESAgent 经 _stop_event 优雅停机并终止全部评测子进程(SIGTERM→SIGKILL,evaluator.py:427);ReAct 可注册自定义 interrupt 处理器(react_agent.py:184);ClaudeCodeAgent 有 permission_mode(prompt/acceptEdits/acceptAll)但默认自动接受;无内置工具审批/危险命令拦截层

主要是 中断治理 而非审批:AgentBase.interrupt() 取消 asyncio task,PESAgent 经 _stop_event 优雅停机并终止全部评测子进程(SIGTERM→SIGKILL,evaluator.py:427);ReAct 可注册自定义 interrupt 处理器(react_agent.py:184);ClaudeCodeAgent 有 permission_mode(prompt/acceptEdits/acceptAll)但默认自动接受;无内置工具审批/危险命令拦截层

framework/base/agent_base.py:90framework/pes/pes_agent.py:589framework/react/react_agent.py:184
src/loongflow/framework/base/agent_base.py:90 python
        """Main agent logic (must be implemented by subclasses)."""
        pass

    async def interrupt(self):
        """Trigger agent interruption."""
        if self._interrupted:
            return

        self._interrupted = True

        if self._task and not self._task.done():
            self._task.cancel()
            try:
查看 LoongFlow 完整笔记 →
Maestro python 仅启动时 CLI 交互(目标/是否加文件/是否搜索);运行中全自动,无审批/中断/护栏;写文件无确认

仅启动时 CLI 交互(目标/是否加文件/是否搜索);运行中全自动,无审批/中断/护栏;写文件无确认

maestro.py:203
maestro.py:203 python
                console.print(Panel(f"Code content not found for file: [bold]{key}[/bold]", title="[bold yellow]Missing Code Content[/bold yellow]", title_align="left", border_style="yellow"))

# Get the objective from user input
objective = input("Please enter your objective: ")

# Ask if the user wants to add a file
add_file = input("Do you want to add a text file? (y/n): ").lower() == 'y'

file_content = None
if add_file:
    file_path = input("Please enter the file path: ")
    try:
        with open(file_path, 'r') as file:
查看 Maestro 完整笔记 →
Mastra typescript suspend/resume:workflow step 与 tool 均可声明 suspendSchema/resumeSchema,执行中 suspend() 暂停并把状态落 storage,之后 resume() 携用户输入恢复(可无限期暂停);requireToolApproval 工具审批;DurableAgent 把整次 agent 运行包成可持久/可恢复的 workflow

suspend/resume:workflow step 与 tool 均可声明 suspendSchema/resumeSchema,执行中 suspend() 暂停并把状态落 storage,之后 resume() 携用户输入恢复(可无限期暂停);requireToolApproval 工具审批;DurableAgent 把整次 agent 运行包成可持久/可恢复的 workflow

workflows/workflow.ts:389loop/loop.ts:24agent/durable/durable-agent.ts:158
packages/core/src/workflows/workflow.ts:389 typescript
    inputSchema: params.inputSchema ? toStandardSchema(params.inputSchema) : params.inputSchema,
    stateSchema: params.stateSchema ? toStandardSchema(params.stateSchema) : undefined,
    outputSchema: params.outputSchema ? toStandardSchema(params.outputSchema) : params.outputSchema,
    resumeSchema: params.resumeSchema ? toStandardSchema(params.resumeSchema) : undefined,
    suspendSchema: params.suspendSchema ? toStandardSchema(params.suspendSchema) : undefined,
    requestContextSchema: params.requestContextSchema ? toStandardSchema(params.requestContextSchema) : undefined,
    scorers: params.scorers,
    retries: params.retries,
    metadata: params.metadata,
    execute: params.execute.bind(params) as Step<
      TStepId,
      TStateSchema extends PublicSchema<any> ? InferPublicSchema<TStateSchema> : unknown,
      InferPublicSchema<TInputSchema>,
查看 Mastra 完整笔记 →
MetaGPT python HumanProvider 把 is_human=True 的角色 LLM 调用替换成 input() 终端交互;Planner.ask_review(非 auto_run 时)让人审核/改计划;ActionNode.human_review 人工评审结构化产物;RoleZero.ask_human/reply_to_human 工具经 env.ask_human 向人提问

HumanProvider 把 is_human=True 的角色 LLM 调用替换成 input() 终端交互;Planner.ask_review(非 auto_run 时)让人审核/改计划;ActionNode.human_review 人工评审结构化产物;RoleZero.ask_human/reply_to_human 工具经 env.ask_human 向人提问

metagpt/provider/human_provider.py:14metagpt/strategy/planner.py:119metagpt/actions/action_node.py:665metagpt/roles/di/role_zero.py:456
metagpt/provider/human_provider.py:14 python
from metagpt.provider.base_llm import BaseLLM


class HumanProvider(BaseLLM):
    """Humans provide themselves as a 'model', which actually takes in human input as its response.
    This enables replacing LLM anywhere in the framework with a human, thus introducing human interaction
    """

    def __init__(self, config: LLMConfig):
        self.config = config
        self.model = config.model

    def ask(self, msg: str, timeout=USE_CONFIG_TIMEOUT) -> str:
查看 MetaGPT 完整笔记 →
nanobot python ask_user 工具(支持 choices)向渠道发问;DM 发送者 pairing 审批(每渠道持久配对码,pairing/store.py);渠道 allow-list / 安全默认拒绝;SSRF 硬边界(私网 URL 不可绕过,runner.py:1043);shell allow-list;/stop 中途取消 turn 并保留部分上下文

ask_user 工具(支持 choices)向渠道发问;DM 发送者 pairing 审批(每渠道持久配对码,pairing/store.py);渠道 allow-list / 安全默认拒绝;SSRF 硬边界(私网 URL 不可绕过,runner.py:1043);shell allow-list;/stop 中途取消 turn 并保留部分上下文

channels/base.py:13agent/runner.py:1043agent/loop.py:990
nanobot/channels/base.py:13 python

from nanobot.bus.events import InboundMessage, OutboundMessage
from nanobot.bus.queue import MessageBus
from nanobot.pairing import (
    PAIRING_CODE_META_KEY,
    format_pairing_reply,
    generate_code,
    is_approved,
)


class BaseChannel(ABC):
    """
查看 nanobot 完整笔记 →
Open Multi-Agent typescript onPlanReady(tasks) 在任何 agent 执行前审批整份计划(返 false 中止);onApproval(completed,next) 在每轮任务之间审批;planOnly 只看不跑;AbortSignal 运行中取消;beforeRun/afterRun 钩子改写 prompt / 后处理结果;maxTokenBudget 硬性封顶花费

onPlanReady(tasks) 在任何 agent 执行前审批整份计划(返 false 中止);onApproval(completed,next) 在每轮任务之间审批;planOnly 只看不跑;AbortSignal 运行中取消;beforeRun/afterRun 钩子改写 prompt / 后处理结果;maxTokenBudget 硬性封顶花费

src/orchestrator/orchestrator.ts:1290src/orchestrator/orchestrator.ts:800src/agent/agent.ts:328src/agent/agent.ts:391
src/orchestrator/orchestrator.ts:1290 typescript
    const planTasks = queue.list()
    const planReadyStartMs = Date.now()
    let approved = true
    if (this.config.onPlanReady) {
      try {
        approved = await this.config.onPlanReady(planTasks)
      } catch {
        approved = false
      }
    }
    if (this.config.onTrace) {
      const planReadyEndMs = Date.now()
      emitTrace(this.config.onTrace, {
查看 Open Multi-Agent 完整笔记 →
OpenClaw typescript DM pairing:未知发信人默认收到配对码、消息不被处理,openclaw pairing approve 后加入 allowlist(dmPolicy/allowFrom);沙箱:agents.defaults.sandbox.mode:"non-main" 让非 main 会话跑在 Docker/SSH/OpenShell 沙箱,默认 deny browser/canvas/nodes/cron/discord/gateway;beforeToolCall 钩子+ACP approval-classifier 对危险工具审批;openclaw doctor 体检风险配置

DM pairing:未知发信人默认收到配对码、消息不被处理,openclaw pairing approve 后加入 allowlist(dmPolicy/allowFrom);沙箱:agents.defaults.sandbox.mode:"non-main" 让非 main 会话跑在 Docker/SSH/OpenShell 沙箱,默认 deny browser/canvas/nodes/cron/discord/gateway;beforeToolCall 钩子+ACP approval-classifier 对危险工具审批;openclaw doctor 体检风险配置

README.md:145src/acp/approval-classifier.ts:27agent-loop.ts:684
README.md:145 markdown

Models config + CLI: [Models](https://docs.openclaw.ai/concepts/models). Auth profile rotation + fallbacks: [Model failover](https://docs.openclaw.ai/concepts/model-failover).

## Security defaults (DM access)

OpenClaw connects to real messaging surfaces. Treat inbound DMs as **untrusted input**.

Full security guide: [Security](https://docs.openclaw.ai/gateway/security).
Before remote exposure, use the [Gateway exposure runbook](https://docs.openclaw.ai/gateway/security/exposure-runbook).

Default behavior on Telegram/WhatsApp/Signal/iMessage/Microsoft Teams/Discord/Google Chat/Slack:

- **DM pairing** (`dmPolicy="pairing"` / `channels.discord.dmPolicy="pairing"` / `channels.slack.dmPolicy="pairing"`; legacy: `channels.discord.dm.policy`, `channels.slack.dm.policy`): unknown senders receive a short pairing code and the bot does not process their message.
查看 OpenClaw 完整笔记 →
Pilot Protocol go 互信即治理:节点默认私有,必须双向 handshake 才能被解析/连接("no mutual trust"会拒绝 find);--trust-auto-approve 可自动批准(demo 用),否则人工 pilotctl trust 审批;policy 插件用 expr-lang 表达式对 connect/dial/datagram/join/leave 等事件做策略判定

互信即治理:节点默认私有,必须双向 handshake 才能被解析/连接("no mutual trust"会拒绝 find);--trust-auto-approve 可自动批准(demo 用),否则人工 pilotctl trust 审批;policy 插件用 expr-lang 表达式对 connect/dial/datagram/join/leave 等事件做策略判定

cmd/daemon/main.go:81pkg/daemon/contract.go:38README.md:121
cmd/daemon/main.go:81 go
	webhookURL := flag.String("webhook", "", "HTTP(S) endpoint for event notifications (empty = disabled)")
	adminToken := flag.String("admin-token", "", "admin token for network operations")
	networks := flag.String("networks", "", "comma-separated network IDs to auto-join at startup")
	trustAutoApprove := flag.Bool("trust-auto-approve", false, "automatically approve all incoming trust handshakes")
	beaconRTTProbe := flag.Bool("beacon-rtt-probe", false, "probe beacon RTT before selection; override hash pick when >2× slower than best (ablation test, default off)")
	transportMode := flag.String("transport", "udp", "tunnel transport: 'udp' (default) or 'compat' (WSS to beacon, opt-in, for UDP-blocked environments)")
	compatBeacon := flag.String("compat-beacon", "wss://beacon.pilotprotocol.network/v1/compat", "beacon WSS URL for -transport=compat")
	tlsTrust := flag.String("tls-trust", "system", "TLS trust store for -transport=compat: 'system' (OS trust store; current default while compat mode uses Let's Encrypt certs on beacon.pilotprotocol.network) or 'pinned' (Pilot CA root embedded in the daemon binary; will become the default in a future release once production root ships)")
	showVersion := flag.Bool("version", false, "print version and exit")
	logLevel := flag.String("log-level", "info", "log level (debug, info, warn, error)")
	logFormat := flag.String("log-format", "text", "log format (text, json)")
	flag.Parse()
查看 Pilot Protocol 完整笔记 →
Pipecat python 实时交互而非审批治理:打断/barge-in——InterruptionFrame(携 asyncio.Event,到 sink 时 set)由用户轮次开始策略触发;轮次管理——UserTurnStrategies(start: VAD+转写; stop)判定用户起止说话;RTVIProcessor 作为客户端↔管道协议桥接收文本/音频/函数结果

实时交互而非审批治理:打断/barge-in——InterruptionFrame(携 asyncio.Event,到 sink 时 set)由用户轮次开始策略触发;轮次管理——UserTurnStrategies(start: VAD+转写; stop)判定用户起止说话;RTVIProcessor 作为客户端↔管道协议桥接收文本/音频/函数结果

turns/user_turn_strategies.py:55processors/frameworks/rtvi/processor.py:49
src/pipecat/turns/user_turn_strategies.py:55 python


@dataclass
class UserTurnStrategies:
    """Container for user turn start and stop strategies.

    If no strategies are specified, the following defaults are used:

        start: [VADUserTurnStartStrategy, TranscriptionUserTurnStartStrategy]
         stop: [TurnAnalyzerUserTurnStopStrategy(LocalSmartTurnAnalyzerV3)]

    Parameters:
        start: A list of user turn start strategies used to detect when
查看 Pipecat 完整笔记 →
PraisonAI python @require_approval(risk_level=...) 标记高危工具→执行前 request_approval 走审批后端(console/自定义 callback);Guardrails(LLMGuardrail 或函数式)对输入/输出做校验+重试;Policy Engine 声明式行为控制;doom-loop 检测自动恢复

@require_approval(risk_level=...) 标记高危工具→执行前 request_approval 走审批后端(console/自定义 callback);Guardrails(LLMGuardrail 或函数式)对输入/输出做校验+重试;Policy Engine 声明式行为控制;doom-loop 检测自动恢复

approval/__init__.py:166guardrails/llm_guardrail.py:15
src/praisonai-agents/praisonaiagents/guardrails/llm_guardrail.py:15 python
from ..output.models import TaskOutput
from .protocols import GuardrailProtocol

class LLMGuardrail:
    """
    An LLM-powered guardrail that validates task outputs using natural language.
    
    Implements GuardrailProtocol to provide input, output, and tool call validation
    using LLM reasoning. Defaults to fail-closed behavior for production safety.
    """
    
    def __init__(self, description: str, llm: Any = None):
        """Initialize the LLM guardrail.
查看 PraisonAI 完整笔记 →
Semantic Kernel csharp ① IAutoFunctionInvocationFilter 在工具自动调用前后拦截,可设 context.Terminate=true 中止循环、把结果交还用户审批(FunctionCallsProcessor.cs:205/225/366 消费);② 编排层 OrchestrationInteractiveCallback / GroupChatManager ShouldRequestUserInput 请求人工输入;③ FunctionChoiceBehavior.None 让模型只建议不执行

① IAutoFunctionInvocationFilter 在工具自动调用前后拦截,可设 context.Terminate=true 中止循环、把结果交还用户审批(FunctionCallsProcessor.cs:205/225/366 消费);② 编排层 OrchestrationInteractiveCallback / GroupChatManager ShouldRequestUserInput 请求人工输入;③ FunctionChoiceBehavior.None 让模型只建议不执行

dotnet/src/SemanticKernel.Abstractions/Filters/AutoFunctionInvocation/AutoFunctionInvocationContext.cs:16dotnet/src/Agents/Orchestration/GroupChat/GroupChatManager.cs:77
dotnet/src/SemanticKernel.Abstractions/Filters/AutoFunctionInvocation/AutoFunctionInvocationContext.cs:16 csharp
/// <summary>
/// Class with data related to automatic function invocation.
/// </summary>
public class AutoFunctionInvocationContext : Microsoft.Extensions.AI.FunctionInvocationContext
{
    private ChatHistory? _chatHistory;

    /// <summary>
    /// Initializes a new instance of the <see cref="AutoFunctionInvocationContext"/> class from an existing <see cref="Microsoft.Extensions.AI.FunctionInvocationContext"/>.
    /// </summary>
    internal AutoFunctionInvocationContext(KernelChatOptions autoInvocationChatOptions, AIFunction aiFunction)
    {
        Verify.NotNull(autoInvocationChatOptions);
查看 Semantic Kernel 完整笔记 →
Strands Agents python Interrupt/InterruptException 暂停 agent 等人类输入,经 session 持久化后 resume(agent.py:878);AfterInvocationEvent.resume 钩子可注入新输入续跑;experimental/steering 提供 LLM/ledger 引导;guardrail 触发 redactContent 自动脱敏(agent.py:1310)

Interrupt/InterruptException 暂停 agent 等人类输入,经 session 持久化后 resume(agent.py:878);AfterInvocationEvent.resume 钩子可注入新输入续跑;experimental/steering 提供 LLM/ledger 引导;guardrail 触发 redactContent 自动脱敏(agent.py:1310)

interrupt.py:11agent.py:1004agent.py:1310
strands-py/src/strands/interrupt.py:11 python
    from .types.interrupt import InterruptResponseContent


@dataclass
class Interrupt:
    """Represents an interrupt that can pause agent execution for human-in-the-loop workflows.

    Attributes:
        id: Unique identifier.
        name: User defined name.
        reason: User provided reason for raising the interrupt.
        response: Human response provided when resuming the agent after an interrupt.
    """
查看 Strands Agents 完整笔记 →
SwarmClaw typescript 审批门:requestApproval/submitDecision,危险工具走 durable_wait 终端边界挂起等人审,审批后 wake 续跑;E-Stop 急停(estop);learned-skill 上线需人工审查;capability/tool 策略与权限预设(OpenClaw permission-presets);mission budget 上限(USD/token/turn/wallclock)

审批门:requestApproval/submitDecision,危险工具走 durable_wait 终端边界挂起等人审,审批后 wake 续跑;E-Stop 急停(estop);learned-skill 上线需人工审查;capability/tool 策略与权限预设(OpenClaw permission-presets);mission budget 上限(USD/token/turn/wallclock)

approvals.ts:83
src/lib/server/approvals.ts:83 typescript
  }
}

export function requestApproval(params: {
  category: ApprovalCategory
  title: string
  description?: string
  data: Record<string, unknown>
  agentId?: string | null
  sessionId?: string | null
  taskId?: string | null
}): ApprovalRequest {
  const id = genId(8)
查看 SwarmClaw 完整笔记 →
Swarms python interactive=True 进入 REPL,每轮经 formatter.console.input 收用户输入(agent.py:1871);AgentRearrange flow DSL 支持插入 -> H -> 人审步骤 + custom_human_in_the_loop 回调;无细粒度工具审批/沙箱

interactive=True 进入 REPL,每轮经 formatter.console.input 收用户输入(agent.py:1871);AgentRearrange flow DSL 支持插入 -> H -> 人审步骤 + custom_human_in_the_loop 回调;无细粒度工具审批/沙箱

agent.py:433structs/agent_rearrange.py:34
swarms/structs/agent.py:433 python
        self.retry_interval = retry_interval
        self.task = None
        self.stopping_token = stopping_token
        self.interactive = interactive
        self.dashboard = dashboard
        self.saved_state_path = saved_state_path
        self.dynamic_temperature_enabled = dynamic_temperature_enabled
        self.dynamic_loops = dynamic_loops
        self.user_name = user_name
        self.context_length = context_length
        self.sop = sop
        self.sop_list = sop_list
        self.tools = tools
查看 Swarms 完整笔记 →
Upsonic python HITL 经异常驱动暂停/恢复:ConfirmationPause/UserInputPause/ExternalExecutionPause(tools/hitl.py:92,100,108),由 ToolConfig.requires_confirmation 等触发,agent.continue_run()(agent.py:4946) 恢复;治理经 safety engine 策略(user/agent/tool_pre/tool_post policy + feedback loop) + PII 匿名化

HITL 经异常驱动暂停/恢复:ConfirmationPause/UserInputPause/ExternalExecutionPause(tools/hitl.py:92,100,108),由 ToolConfig.requires_confirmation 等触发,agent.continue_run()(agent.py:4946) 恢复;治理经 safety engine 策略(user/agent/tool_pre/tool_post policy + feedback loop) + PII 匿名化

src/upsonic/tools/hitl.py:23agent.py:4946pipeline/steps.py:292
src/upsonic/tools/hitl.py:23 python


@dataclass
class PausedToolCall:
    """Represents a tool call paused for HITL handling (external execution, confirmation, or user input)."""

    tool_name: str
    """Name of the tool to execute."""

    tool_args: Dict[str, Any]
    """Arguments for the tool."""

    tool_call_id: str
查看 Upsonic 完整笔记 →
VoltAgent typescript 两条线:①Guardrails(input/output 方向,可设 severity/action 拦截校验 IO);②工具 needsApproval + Workflow suspend()/resume()(带 resumeSchema) 做审批挂起恢复(README 报销审批示例)

两条线:①Guardrails(input/output 方向,可设 severity/action 拦截校验 IO);②工具 needsApproval + Workflow suspend()/resume()(带 resumeSchema) 做审批挂起恢复(README 报销审批示例)

agent/guardrail.ts:28tool/index.ts:138
packages/core/src/agent/guardrail.ts:28 typescript
  OutputGuardrailStreamHandler,
} from "./types";

export type GuardrailDirection = "input" | "output";

export interface NormalizedGuardrail<TArgs, TResult> {
  id?: string;
  name: string;
  description?: string;
  tags?: string[];
  severity?: GuardrailSeverity;
  metadata?: Record<string, unknown>;
  handler: GuardrailFunction<TArgs, TResult>;
查看 VoltAgent 完整笔记 →