Skip to content
FunCoding

Search

Search docs, Skills and MCP

提示 Hook 与来源声明

区分 prompt、submitted_prompt、命令展开和记录中的 Hook 上下文。

This page has not been translated into English yet. The original Chinese version is shown below.

UserPromptSubmit 的名字不表示每次都是原始人类输入,也不覆盖所有模型请求。写验证器时应先判断调用路径和字段来源。

触发范围

核心和无头路径覆盖 UserQuery、ToolResult、Hook 发送,跳过 Retry、Steer、Cron、Notification、Teammate。ACP 有独立策略:重试和新派发后台任务仍可能运行旧 Hook,continue、恢复提问与运行时 Goal 轮次不运行它。

字段含义
prompt当前路径的旧式提示投影;核心路径是送往模型的文本,ACP 初始值是展开前文本块以空格连接
submitted_prompt可选、在支持的提交边界捕获或声明的文本

两个字段都不是完整数据泄露防护检查面,ACP prompt 不含全部资源、附件和命令展开结果。需要提交来源时,submitted_prompt 缺失就视为不可用,不回退猜测 prompt 是用户原文。

哪些输入带来源字段

支持的 TUI 提交和无头第一轮 UserQuery 可以带 submitted_prompt。ACP/serve/daemon 的新请求必须显式声明 _meta 中的 qwen.submittedPrompt,值非字符串、空或全空白时不提供。

Web Shell 在提交边界提供原输入;渠道分类轮次,包括渠道转来的真人消息,都不带该字段。实时语音交接来自模型工具参数,也不声明该来源。

SDK 不应在所有传输上自动添加它,否则定时任务、子会话、模型写的跨会话消息也会被错误标记。私有 qwen.daemon.submittedPrompt 只供 daemon 内部跳转,外部提交会被剥除。这些声明仍由调用者提供,不能证明人类身份、租户或操作授权。

TUI 的保守规则

完整来源的延后输入可保留;合并批次只有每项都有来源才保留。历史导航、搜索选中、跨重启 stash、rewind、编辑后来源不完整的输入可能不带该字段。大段粘贴仍保留紧凑占位符,展开内容只在 prompt,不是剪贴板字节级副本。

Vim 模式下存在非空输入时会丢弃来源声明,关闭 Vim 后也不恢复,连开启前已有草稿也受影响;清空输入框才开始新的可声明输入。ACP 客户端没有这些内建编辑历史跟踪,需要自行保证声明语义。

追加上下文与转录

顺序 Hook 可以给 prompt 添加 additionalContext,submitted_prompt 仍代表捕获的提交。最后输出的非空上下文经清洗后,作为独立文本部分包在 <qwen:user-prompt-submit-context> 标记内;尖括号转义防止伪造关闭标签,但标记本身不是授权边界。

相关 UserQuery JSONL 可写 systemPayload.displayText 与 hookContext:前者是加 Hook 之前的显示投影,后者冗余保存 Hook 内容,便于离线识别。不能把通知、cron 或中途消息中任意 displayText 都当成同一种用户投影;兼容读取需要对应上下文标记或元数据证据。

敏感提示遥测与托管自动记忆召回采用加 Hook 之前的 prompt,不包括这里添加的上下文。不过各执行器仍收到原事件字段,HTTP 会传端点,prompt Hook 会传提供商;两个文本字段重叠也可能增加 token,目前没有逐 Hook 字段屏蔽。

UserPromptExpansion

自定义命令、Skills、MCP prompts、/init 等展开为模型提示后触发,纯本地命令不触发。TUI、无头、ACP 和模型调用命令路径都可触发。

matcher 匹配不带斜杠的 command_name;输入还有 command_args 和展开的 prompt,非文本部分以文本表示。无头或 ACP 同时调用多个 Skills 时,command_name 是空格连接的名称,command_args 为剩余文本。

返回 deny/block、continue: false 或退出 2 可阻止展开提示发送。additionalContext 在转义 &、<、> 后截到 10,000 字符,再加到展开提示;command 退出 0 的纯文本 stdout 也按上下文处理。