子Agent没有可请求用户输入的可达路径 #163

Closed
opened 2026-08-12 15:06:05 +08:00 by lhk229 · 1 comment
Owner
No description provided.
lhk229 reopened this issue 2026-08-12 16:00:19 +08:00
Author
Owner

为什么工作流节点问不了用户

四道锁,分布在三个不同层,任意一道都足以致命。

锁 1 — 血统:挡住节点自己问

[validate_user_input_action_owner](https://claude.ai/epitaxy/apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367) 三路 OR,第一条就是 task.parent_agent_id / parent_run_id / delegation_id 任一 Some 即拒。

而 autonomous 的 ready-task 调度器在 [task_start.rs:905-907](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:905) 显式给每个 DAG 子节点写 parent_agent_id / parent_run_id

→ 工作流节点必然命中,无一例外。

锁 2 — profile 广告层:挡住父代问

[tool_policy_snapshot.rs:198-215](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_policy_snapshot.rs:198):只要 run_profile == autonomous-game-builduser.input_requestauto_tools / confirm_tools 移除并推进 denied_tools

判据只看 profile,不看 agent_id —— 所以 root Supervisor 自己也在禁令内。中转需要的"父能问、子不能问"这个不对称,根本不存在

锁 3 — profile 执行层:挡住伪造

[main_loop.rs:2608-2616](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs:2608):即使绕过广告层伪造 action call,autonomous run 直接判 NeedsReconciliation

锁 4 — profile 不可切换:挡住"换个 profile 绕开"

[run_configuration.rs:264-266](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/run_configuration.rs:264) 明写 "子 Run 不能切换父 Run 的 Run Profile",且 run_profile 是 run 绑定时 CAS 锁死的终身属性。

→ 不可能让策划节点在 autonomous DAG 里跑 standard。


硬闯的后果不是失败,是瘫痪

一旦真的触发锁 3:

NeedsReconciliation
  → pending_execution.rs:1157   runtime.status = "failed"
  → autonomous_game_build_root_task_is_active (task_start.rs:685-693)
     只认 status ∈ {pending, running, waiting-for-confirmation, waiting-for-user-input}
  → "父 Run 已不再活跃"
  → 后续 15 个节点一个都起不来,需人工核对

一次提问尝试 = 整条流水线永久停摆。


这是设计,不是没实现

三处独立佐证,且都在 master:

  • 我们文档 §19 不变量第 1 条:「不放松 autonomous-game-builduser.input_request 的现行禁等待防线
  • pitfalls「自主模式不能保留任何 RequiresConfirmation 漏口」——同类故障真踩过:请求被拒但整批仍进入等待态,重启还忠实恢复,形成永久阻塞
  • master 技术方案 V1.1 §V1.28:project-supervisor 是唯一可以向正式用户提交最终回复的 Agent

根本原因是语义的:autonomous-game-build 这个 profile 的定义就是"无人值守、跑完为止"。它不是"恰好还没做提问功能",而是"提问与它存在的意义直接相反"——所以禁令写在 profile 这一层,对该 profile 下的所有 agent 一视同仁。


一句话

问用户这件事绑在 run profile 上,不绑在 agent 身份上。只要跑在 autonomous-game-build 里,无论你是根 Supervisor 还是 DAG 节点,都不能问;而 DAG 节点又不能脱离父的 profile。所以"工作流节点 + 用户问询"在当前仓库状态下是一个定义上矛盾的组合,不是工程缺口。

要问用户,就必须在 standard profile 的 run 里问——那正是原方案 D6 的形态。

## 为什么工作流节点问不了用户 四道锁,分布在三个不同层,任意一道都足以致命。 ### 锁 1 — 血统:挡住节点自己问 [`[validate_user_input_action_owner](https://claude.ai/epitaxy/apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367)`](apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367) 三路 OR,第一条就是 `task.parent_agent_id / parent_run_id / delegation_id` 任一 `Some` 即拒。 而 autonomous 的 ready-task 调度器在 [[task_start.rs:905-907](https://claude.ai/epitaxy/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:905)](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:905) **显式**给每个 DAG 子节点写 `parent_agent_id` / `parent_run_id`。 → 工作流节点必然命中,无一例外。 ### 锁 2 — profile 广告层:挡住父代问 [[tool_policy_snapshot.rs:198-215](https://claude.ai/epitaxy/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_policy_snapshot.rs:198)](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_policy_snapshot.rs:198):只要 `run_profile == autonomous-game-build`,`user.input_request` 从 `auto_tools` / `confirm_tools` 移除并推进 `denied_tools`。 **判据只看 profile,不看 agent_id** —— 所以 root Supervisor 自己也在禁令内。中转需要的"父能问、子不能问"这个不对称,**根本不存在**。 ### 锁 3 — profile 执行层:挡住伪造 [[main_loop.rs:2608-2616](https://claude.ai/epitaxy/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs:2608)](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs:2608):即使绕过广告层伪造 action call,autonomous run 直接判 `NeedsReconciliation`。 ### 锁 4 — profile 不可切换:挡住"换个 profile 绕开" [[run_configuration.rs:264-266](https://claude.ai/epitaxy/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/run_configuration.rs:264)](apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/run_configuration.rs:264) 明写 `"子 Run 不能切换父 Run 的 Run Profile"`,且 `run_profile` 是 run 绑定时 CAS 锁死的终身属性。 → 不可能让策划节点在 autonomous DAG 里跑 standard。 --- ## 硬闯的后果不是失败,是瘫痪 一旦真的触发锁 3: ``` NeedsReconciliation → pending_execution.rs:1157 runtime.status = "failed" → autonomous_game_build_root_task_is_active (task_start.rs:685-693) 只认 status ∈ {pending, running, waiting-for-confirmation, waiting-for-user-input} → "父 Run 已不再活跃" → 后续 15 个节点一个都起不来,需人工核对 ``` **一次提问尝试 = 整条流水线永久停摆。** --- ## 这是设计,不是没实现 三处独立佐证,且都在 master: - 我们文档 §19 不变量第 1 条:「不放松 `autonomous-game-build` 对 `user.input_request` 的现行**禁等待防线**」 - pitfalls「自主模式不能保留任何 RequiresConfirmation 漏口」——**同类故障真踩过**:请求被拒但整批仍进入等待态,重启还忠实恢复,形成永久阻塞 - master 技术方案 V1.1 §V1.28:`project-supervisor` 是唯一可以向正式用户提交最终回复的 Agent 根本原因是语义的:**`autonomous-game-build` 这个 profile 的定义就是"无人值守、跑完为止"**。它不是"恰好还没做提问功能",而是"提问与它存在的意义直接相反"——所以禁令写在 profile 这一层,对该 profile 下的所有 agent 一视同仁。 --- ## 一句话 **问用户这件事绑在 run profile 上,不绑在 agent 身份上。**只要跑在 `autonomous-game-build` 里,无论你是根 Supervisor 还是 DAG 节点,都不能问;而 DAG 节点又不能脱离父的 profile。所以"工作流节点 + 用户问询"在当前仓库状态下是一个**定义上矛盾**的组合,不是工程缺口。 要问用户,就必须在 `standard` profile 的 run 里问——那正是原方案 D6 的形态。
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GenarrativeAI/Genarrative#163