ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Ekko Studio Coding Agent MCP 用户澄清机制:`ekko-studio-interaction` 交互工具的原理与实战

Ekko Studio Coding Agent MCP 用户澄清机制:`ekko-studio-interaction` 交互工具的原理与实战 AI 应用人工智能AI Agent本地部署前端后端工作流自动化【免费下载链接】hermes-studioEkko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.项目地址https://gitcode.com/gh_mirrors/he/hermes-studio点击查看免费下载导读在 Ekko Studio本地优先的多智能体 AI 工作空间同时支持桌面端与 Web中Claude Code、Codex、Pi、Grok、OpenCode 与 DSH 等无头headless编码代理运行时不具备终端交互能力当任务遇到缺失的用户决策时往往只能猜测或卡死。本文基于仓库内变更记录 docs/chat-chain-changes/2026-09-17-coding-agent-mcp-clarification.md 并结合服务端与 MCP 网关源码系统讲解ekko-studio-interactionMCP 服务器如何通过ekko_studio_clarify与ekko_studio_update_plan两个工具让编码代理在 Studio/App 既有界面中向用户提问并等待回答、继续执行。读完本文你将掌握该交互工具的传输范围与客户端分发矩阵、context_id绑定与指令注入机制、服务端澄清会话的生命周期与超时规则、四种显式reason语义以及对应的测试覆盖与升级注意事项。一、为什么需要用户澄清无头编码代理的交互缺口编码代理Coding Agent在被 Studio 托管运行时通常以无头方式启动没有自己的交互式终端可供用户输入。传统上这类工具遇到缺少关键决策的场景例如选择部署环境、确认删除路径、挑选实现方案时要么用默认值代替可能产生错误结果要么停在原地等待一个永远不会出现的输入。该特性的核心思路是复用 Studio/App 中已经存在的提问/任务卡片界面把向用户提问封装为一个 MCP 工具编码代理通过既有的 managed MCP 通道调用它问题以clarify.requested事件呈现在界面中用户在既有界面上回答后答案以clarify.respond事件回流ekko_studio_clarify的 HTTP 请求随之返回真实答案并显式给出reason。原文档将其影响概括为无头编码代理可以在现有 Studio/App 界面中提出问题并在拿到用户回答后继续执行。二、传输与范围一个重命名的共享 MCP 服务器2.1ekko-studio-interaction两个工具、一个服务器原ekko-studio-plan任务卡片MCP 条目被重命名为ekko-studio-interaction但不注册第二个服务器改名而非新增避免同一个启动命令被重复注册。改名后的服务器同时暴露两个直接工具ekko_studio_update_plan创建或更新当前轮次的任务计划卡片原ekko-studio-plan的能力内部planlaunch 参数被保留以兼容既有配置ekko_studio_clarify向用户提出一个必要的澄清问题并等待回答。从 packages/server/src/modules/hermes/services/mcp/studio-autoinject.ts 的MANAGED_SERVERS列表可以看到ekko-studio-interaction的 toolset 为plan与api、browser、devices、use并列其旧名ekko-studio-plan出现在LEGACY_SERVER_NAMES中用于识别并迁移存量配置L10-L33。在 packages/server/src/modules/coding-agents/services/mcp-manager.ts 的readServers()中有一行servers.delete(ekko-studio-plan)L299明确把旧条目从读取结果中剔除再统一注入新名ekko-studio-interaction。MCP 服务器本体实现于 bin/ekko-studio-mcp.mjsstdio 协议TOOLSETS api/browser/devices/use/plan按首个位置参数或HERMES_MCP_TOOLSET决定暴露哪个工具集。plan工具集下同时注册ekko_studio_update_plan与ekko_studio_clarify其中ekko_studio_clarify内部 POST 到/api/studio/clarifications/requestekko_studio_update_plan内部 POST 到/api/studio/task-plans/updateL1959-L1966。2.2 客户端分发矩阵谁拿到什么原文档明确了各客户端的接收范围这是一张值得完整保留的对照表客户端接收ekko-studio-interaction可用工具说明Claude Code / Codex / Pi / Grok / OpenCode / DSH是ekko_studio_update_planekko_studio_clarify通过既有 managed 配置路径注入无需新增客户端组件Hermes是仅ekko_studio_update_plan澄清工具从 discovery 中隐藏、从指令中省略、直接调用被拒绝Ekko否—保留其原生工具native tools不接收该服务器Pi是两个工具同时保留其原生 RPC UI 支持2.3 开关环境变量HERMES_MCP_USER_CLARIFICATION工具是否可见由一个环境变量控制默认关闭默认值off未设置即不启用澄清只有 Coding Agent 注入路径显式设置HERMES_MCP_USER_CLARIFICATION1Hermes 的自动注入路径显式设置为0。在 packages/server/src/modules/coding-agents/services/index.ts 中hermesMcpServerConfig()的 env 固定写入HERMES_MCP_USER_CLARIFICATION: 1L1194而managedHermesMcpServerConfig()在 toolset 为plan时进一步确保该变量为1L1213。反观 Hermes 侧的 studio-autoinject.ts 的managedConfig()env 中写入的是HERMES_MCP_USER_CLARIFICATION: 0L189——从源码可以确认这就是只有 Coding Agent 注入开启、Hermes 显式关闭的实现落点。MCP 服务器侧在 bin/ekko-studio-mcp.mjs 用如下表达式计算开关L70-L71const SHARED_TASK_PLAN_ENABLED process.env.HERMES_MCP_NATIVE_TASK_PLAN ! 1 const USER_CLARIFICATION_ENABLED SHARED_TASK_PLAN_ENABLED process.env.HERMES_MCP_USER_CLARIFICATION 1并在activeToolsetTools()中过滤(USER_CLARIFICATION_ENABLED || tool.name ! ekko_studio_clarify)L1804-L1808。也就是说即使进程以plantoolset 启动只要该变量不是1tools/list就不会暴露ekko_studio_clarifytools/call也会拒绝调用——这正是Hermes 端澄清被隐藏、被省略、被拒绝的三重防护。serverInstructions()L1822-L1826在plantoolset 下只把澄清指令拼进系统提示当且仅当USER_CLARIFICATION_ENABLED为真对应从指令中省略。三、ekko_studio_clarify工具契约与参数校验3.1 参数定义工具接受context_id、question和可选的字符串数组choices即使提供了choices也仍然允许用户以自由文本回答。以下是 bin/ekko-studio-mcp.mjs 中ekko_studio_clarify的完整 input schemaL1013-L1021{ context_id: { type: string, description: Current turn interaction context supplied by Studio. }, question: { type: string, minLength: 1, maxLength: 4000 }, choices: { type: array, maxItems: 20, items: { type: string, minLength: 1, maxLength: 500 } } }context_id与question为必填choices可选。工具描述明确要求只使用最新的 interaction context_id并强调超时、取消、关闭不等于同意consent先检查 reason 再继续。3.2 服务端校验边界服务端 packages/server/src/modules/studio/services/clarification-runs.ts 的parseQuestion()L14-L23在显示任何问题之前做严格校验任一不满足即抛ClarificationErrorHTTP 400且不会发出clarify.requestedquestion必须是去空白后长度 14000 的字符串choices若提供必须是数组、最多 20 项、每项为去空白后长度 1500 的非空字符串重复项会被去重[...new Set(...)]。测试 tests/server/clarification-runs.test.ts 的validates input before displaying a prompt用例覆盖了空问题、超长问题、非字符串选项、纯空白选项、超长选项、21 个选项等非法输入并断言这些输入全部抛错且不产生clarify.requested事件。四、交互绑定context_id、studio_interaction_context与作用范围4.1 capability id 与独立 interaction binding每个交互式 coding-agent turn 的最新输入会附带一段studio_interaction_context指令。该指令使用的context_id与任务卡片task card共用同一个 capability id但使用独立的 interaction binding互不干扰。从 packages/server/src/modules/studio/services/clarification-runs.ts 的clarificationTurnInstruction()L113-L114可以看到注入文本的完整内容要点包括当缺失的用户决策实质性影响任务时从同一个ekko-studio-interactionMCP 服务器调用ekko_studio_clarify与任务卡片同源问题要简洁并可选提供选项该工具会显示既有 Studio/App 提问界面并等待用户响应用于替代无头模式下不可用的终端输入或原生交互工具若工具被延迟deferred应搜索ekko-studio-interaction / clarify并使用发现到的工具名超时、关闭、取消不是用户批准禁止在委托子代理delegated subagents或后台任务中使用指令末尾给出Current turn context_id...并要求只使用这个交互上下文绝不要使用更早消息里的 id。4.2 注入时机与作用范围在 packages/server/src/modules/studio/services/chat-run/handle-coding-agent-run.ts 中interactionContext mcpCapabilities.interaction ? data.interaction_context_id : undefinedL74随后运行时输入被拼接为const runtimeInput interactionContext ? ${plannedInput}\n\n${clarificationTurnInstruction(interactionContext)} : plannedInput即指令只附加到该轮次最新输入上而不是写进稳定的系统提示context_id也不会出现在存储/展示的用户输入里。从 packages/server/src/modules/studio/sockets/chat-run.ts 的编排逻辑L1709-L1714可以确认作用范围const planContext isCommand || !mcpCapabilities.interaction ? undefined : this.beginTaskPlanRun(data.session_id, profile) const interactionContext planContext source ! workflow data.session_source ! workflow source ! global_agent data.session_source ! global_agent ? planContext : undefined if (interactionContext data.session_id) { this.clarificationRuns.begin(interactionContext, data.session_id, profile, () this.sessionMap.get(data.session_id!)) }据此可以总结出清晰的绑定范围场景是否获得 interaction binding直接聊天direct chat是群聊group chat是经既有 manager relay 回答工作流workflow否全局后台代理global background agent否独立终端standalone terminal否无 binding委托子代理被指令明确禁止使用父级交互工具4.3 会话与轮次解析不信任调用方提供的 idekko_studio_clarify的 HTTP 请求体里只带context_id、question、choices不携带 session/run id。Studio 从 binding内存映射解析出 session 与 history turn marker而不是接受调用方提供的 session/run ids——这从根本上防止了跨会话、跨轮次的伪造或越权。绑定校验发生在 clarification-runs.ts 的active()L37-L47binding 不存在或 profile 不匹配返回 409Interaction context is unavailable or has expired轮次状态不是 working、处于 aborting、没有活动 run marker、或 run id 与 binding 记录的 run id 不一致均返回 409Interaction context has no active turn。以下情况都会被拒绝其他 profilebinding 绑定到启动轮次时的 profileactive()会比对binding.profile ! profile过期 contextbinding 不存在或已被清除idle/aborting 轮次isWorking为假或isAborting为真无效输入见 3.2 节校验规则同一 session 内并发问题request()会检查 pending 表中是否已有同 session 的问题存在则抛 409Another clarification is already pending for this session。五、澄清会话的生命周期与事件流5.1 状态机begin → request → respond / 结算ClarificationRuns维护两个内存 MapbindingscontextId →{ sessionId, profile, resolve }与pendingclarifyId →{ contextId, sessionId, finish }。核心流程如下begin(contextId, sessionId, profile, resolve)为新轮次注册绑定同时调用finishSession(sessionId)结算该 session 之前的旧等待request(contextId, profile, input, signal?)校验绑定与输入生成clarifyId randomUUID()注册 pending发布clarify.requested然后阻塞等待CLARIFICATION_TIMEOUT_MS 300_0005 分钟L8定时器到期自动以timeout结算AbortSignal触发时以cancelled结算respond(sessionId, clarifyId, response?)仅当 pending 存在且 session 匹配时结算——有回答文本 →reason: response空回答 →reason: dismissedbinding 失效 →reason: cancelledfinishSession(sessionId, contextId?)清除该 session 的 bindings并以cancelled结算所有 pending。5.2 事件与 reason 语义clarify.requested沿用现有 question、choices、requested-at、timeout、remaining-time 字段payload 含run_id、clarify_id、question、choices、timeout_ms、remaining_timeout_ms、requested_atclarify.respond直接聊天由客户端通过 socket 事件回答群聊复用既有 manager relayclarify.resolved结算时向 session 广播payload 含run_id、clarify_id、resolved: true、reason并清除 pending replay 状态即使答案来自另一个客户端也要同步清理HTTP 返回值{ clarify_id, response, reason }其中reason为四值枚举response|dismissed|timeout|cancelledclarification-runs.tsL5。一个必须强调的安全语义缺席的响应绝不等于批准。超时、关闭、取消都会以非response的 reason 返回Agent 若把这三种情况当成用户同意继续执行将违反工具与指令的明确约束。5.3 边界条件哪些事件会使绑定失效、等待结算原文档列出了完整的失效条件对应源码中finishSession的调用点chat-run.ts的beginTaskPlanRun、finishTaskPlanRun、以及各 socket 处理分支轮次完成run.completed、失败run.failed、停止abort.completed被新轮次替换begin()会先finishSession旧 sessionsession 处置disposal服务器关闭MCP 取消notifications/cancelled通知会 abort 对应请求bin/ekko-studio-mcp.mjsL2199-L2201stdio 关闭stdin close 时遍历 abort 所有 pending interactionsL2243HTTP 断开controller 中ctx.res.once(close, ...)触发 abortpackages/server/src/modules/studio/controllers/clarifications.tsL13-L15。例外单独的客户端 UI 断开不会取消问题——binding 保留客户端重连/恢复后仍可继续回答。由于 bindings 与 pending 都是内存态服务器重启后不保留有意设计重启意味着所有等待以取消告终这是可预期的、安全的默认行为。六、超时预算与 HTTP 传输细节澄清问题最长等待 5 分钟因此整条链路的超时预算都必须覆盖这个业务期限MCP 工具级预算所有受管 CLI 的 tool-call 预算至少 6 分钟360 秒。各 CLI 家族的字段名不同从 packages/server/src/modules/coding-agents/services/index.tsL1215-L1216与测试 tests/server/coding-agent-mcp-manager.test.tsL86-L89可看到映射CLI 家族预算字段下限claude-code / opencodetimeout≥ 360_000 mscodex / groktool_timeout_sec≥ 360 spirequestTimeoutMs≥ 360_000 msdshtoolCallTimeoutMs≥ 360_000 msHTTP 传输级/api/studio/clarifications/request走的是自定义fetchMobileConsentbin/ekko-studio-mcp.mjsL188-L213使用330 秒330_000 ms的 deadline而不是 fetch 默认的 300 秒 response-header deadline——因为用户交互可能在产生响应头之前就等待 5 分钟330 秒给业务期限留了 30 秒缓冲避免业务未超时、传输先超时的竞态。七、升级与启用注意事项原文档给出的运维要点在部署时缺一不可升级后必须重启 Studio 与所有既有 coding-agent 进程让它们重新加载更新后的 interaction MCP 工具目录否则进程仍持有旧的ekko-studio-plan工具集工具是否真正被使用取决于两个条件Agent 是否遵循注入的studio_interaction_context指令模型需自行决定调用该工具系统不保证每个模型都会调用managed interaction 服务器是否被启用用户可通过 managed MCP 开关/override 禁用例如测试coding-agent-mcp-manager.test.ts中disabled: { codex: { default: [ekko-studio-plan] } }的用例展示了禁用 override 会跟随新名生效。此外存量用户对ekko-studio-plan的 override 与禁用设置会自动跟随新名ekko-studio-interactionmcp-overrides 与 grok 配置中的MANAGED_MCP_NAMES同时收录两个名字packages/server/src/modules/coding-agents/services/grok/config.tsL8-L23不需要用户手动迁移内部planlaunch 参数继续保留兼容旧配置。八、验证体系测试如何证明这条链路可靠原文档列出了五类测试仓库中均有对应实现Service/controller 测试tests/server/clarification-runs.test.ts 覆盖选项/自由文本回答、关闭dismissal、输入校验、超时、取消、profile/session 隔离、陈旧轮次stale turn被拒绝tests/server/clarifications-controller.test.ts 覆盖 HTTP controller 路径Socket 测试tests/server/chat-run-bridge-readiness.test.ts 覆盖直接聊天与群聊两种clarify.respond入口、pending replay 清理、abort 清理MCP 子进程测试验证直接 discovery、阻塞直到 HTTP 回答返回、响应转发、取消通知对应 bin/ekko-studio-mcp.mjs 中notifications/cancelled→ abort →reason: cancelled的闭环配置测试tests/server/coding-agent-mcp-manager.test.ts 用it.each([claude-code, codex, pi, grok, opencode, dsh])逐一断言六个 CLI family 都拿到ekko-studio-interaction、旧名ekko-studio-plan不再出现、managed为 true、预算字段 ≥ 360、HERMES_MCP_USER_CLARIFICATION为1既有浏览器澄清测试复用既有的提问界面组件无需新增客户端组件。需要明确的是这些测试模拟 Agent 调用与用户回答不依赖真实模型账号也不会断言每个模型都一定会调用该工具——模型是否调用属于推理行为不在服务端测试的承诺范围内。九、总结ekko-studio-interaction是 Ekko Studio 把编码代理向用户提问产品化的关键桥梁通过一个重命名的共享 MCP 服务器、一个受环境变量严格控制的工具开关、一套以context_id为核心的内存绑定机制以及5 分钟业务超时 6 分钟工具预算 330 秒传输 deadline的三级超时设计让 Claude Code、Codex、Pi、Grok、OpenCode、DSH 在无头模式下也能安全地与用户在既有界面上交互。其设计中最值得借鉴的三点binding 而非调用方自报 session/run id杜绝跨会话越权、显式reason而非布尔结果让缺席 ≠ 批准成为可编程语义、客户端 UI 断开与传输断开分离支持重连恢复。无论是排查澄清不生效、评估超时配置还是为其他 Agent 家族接入同类交互能力本文梳理的源码路径与测试用例都可以作为直接的入手点。赞分享AI 应用人工智能AI Agent本地部署前端后端工作流自动化【免费下载链接】hermes-studioEkko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.项目地址https://gitcode.com/gh_mirrors/he/hermes-studio点击查看免费下载相关推荐EEZ Studio 的 Agent 原生 CLI 工具链cli-anything-eez-studio 实战指南EEZ Studio 的 Agent 原生 CLI 工具链cli anything eez studio 实战指南 cli anything eez stud人工智能AI AgentAI 技能工具调用CLIMetabase SQL Agent 的澄清机制ask_for_sql_clarification 工具的使用边界与底层实现Metabase SQL Agent 的澄清机制 ask_for_sql_clarification 工具的使用边界与底层实现 Metabase 内置的 SQ数据分析数据可视化后端数据库客户端企业应用mcp-agent Elicitation 实战指南借助用户确认机制构建可交互的 MCP Servermcp agent Elicitation 实战指南借助用户确认机制构建可交互的 MCP Server 本文以仓库内示例 src/mcp_agent/data人工智能AI AgentAgent 框架MCP ClientsAgent 工作流上一篇5分钟快速上手ItemSlide.js从零构建第一个触屏轮播图下一篇BiliPai Material You设计揭秘液态玻璃与iOS风格底栏的视觉革命创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表