Cues — 预测用户的下一组词汇
你坐在一位通过对话探索领域的用户身旁。
他们正在起草、构建或创作某些内容。
你的副作用是一个文件 — .cues/CUES.md — OpenCues 运行时
在下次重新加载时会加载该文件,并在用户输入时
提供替代方案、重写和技巧建议。
在聊天回复之外触发,而非替代它
这是一个副作用技能。它与用户实际要求你做的任何事情
共存。如果用户说“我正在起草一封给 X 的邮件——帮帮我”,你的聊天回复
起草邮件,同时你的副作用写入 .cues/CUES.md,预测
未来同类邮件的提示。如果用户说“我正在构建一个网站”,你的
聊天回复提出澄清问题,同时你的副作用写入
.cues/CUES.md 预测他们的词汇。
聊天任务和提示副作用是独立的。提示文件 永远不是用户可见的交付物——它存在于磁盘上, 供运行时静默加载。如果你发现因为“已经在聊天中帮了他们” 而省略了文件,你就违反了技能的契约。必须两者都做。
聊天回复末尾的单个括号行是对文件的唯一提及。 它不应挤占聊天输出。
产品是预期。一个在用户已经输入其词汇后才出现的提示 就太晚了。标准是:当用户在下一轮中引入一个新词汇时, 它应该已经被你在这轮中编写的某些内容所覆盖。
两种模式
在执行任何其他操作之前,先读取 .cues/CUES.md。它的存在
会切换模式:
- 初始(文件缺失)——从头预测整个任务的所有预期表面。
- 延续(文件存在)——扩展预期表面。先读取 现有文件;你的输出是严格的超集。
严格扩展(仅限延续模式)
文件中已有的每个源必须出现在你的输出中——
相同的名称、相同的 match:、相同的主体——除非新的对话上下文
直接与它矛盾(用户切换了方向、放弃了该部分等)。你可以:
- 提高当前活跃关注带中源文件的优先级。
- 降低用户已完成部分的源文件优先级。
- 为上一轮未充分预测到的词汇添加新的源。
每轮重写——而非“无变化则不操作”
在每次实质性用户轮次中,你必须调用 Write 工具, 写入一个完整更新的 CUES.md 文件,即使自上一轮以来 变化很小。原因:用户刚给你一条新消息;该消息 移动了对话的焦点,即使只移动了一个子主题。 活跃带需要跟踪该移动。一个“无变化”输出意味着你认为用户没有 切换方向,而在一次新的实质性轮次后,这几乎从不是真的。
如果思考后你真心相信用户的新消息没有增加任何新内容—— 他们回复了“谢谢”或提出了一个仍然在同一微主题内的快速 跟进问题——你可以跳过写入。但标准很高:需明确说出 具体原因(“用户提出了一个完全在活跃带主题内的澄清问题,且没有新子词汇”)。 跳过是例外,而非默认。
Bench 证据(2026 年 5 月,judge-bench):当技能在 N>1 的轮次中跳过 重写时,新鲜度在第 3 轮时崩溃,因为活跃带在第 1 轮的主题上 冻结。每轮都重写能使焦点跟踪用户。
前瞻——命名接下来的 2-3 个部分,提高它们的优先级
在分配优先级之前,先(在脑海中,而非在文件中)写下 在当前领域,基于用户所处的位置,最可能接下来出现的 2-3 个子主题。 然后检查:对于每个即将到来的部分,预期表面是否至少有一个 优先级为 75+ 的源?
如果没有,提高一个源来填补缺口——可以是全新的
### <id>,也可以是提升现有低优先级源。
重点不是确定性;而是覆盖率。如果用户让对话保持向前推进, 你希望他们的下一个 1-2 个部分已经预热。如果他们反而折回, 后处理器/降级规则会在下一轮中将前瞻源标记为非活跃—— 这代价很小。
示例(2026 年 5 月 bench 验证的失败模式):
- 分阶段构建 API 端点:在 T3(错误封装),可能的 T4 是
集成测试或可观测性。至少将一个覆盖
vitest|supertest|describe|it| expect或logger|telemetry|trace|metric的源提高到 75+。 - 逐条起草自由职业合同:在 T3(知识产权),可能的 T4 是
终止/争议解决/责任。至少将一个覆盖
terminate|notice|kill.fee| dispute|arbitration|liability的源提高到 75+。 - 逐页构建网站:在 T2(图库),可能的 T3 是 关于/联系/商店。将这些源提高到 75+。
bench 验证的规则: 对于深度超过 2 轮的对话,活跃带不应仅仅 向后看。至少有一个优先级 75+ 的源应预测领域内一个合理的 下一个子主题。如果你只镜像用户已经说过的话, 一旦他们转变方向,预期表面就会变得过时。
这不是对随机话题的猜测。它是领域中的主线路径: 合同有终止条款,REST 端点有测试,网站有联系页面, 食谱有装盘说明。命名明显的下一个部分并预热它。
降级——基于每个源,可观察
当用户完成一个子主题并转向一个新主题时,你必须降低 已解决源的优先级。问题是降低多少——答案是 在用户的新消息中可观察到的,而非领域判断。
测试:用户的新消息是否包含先前源 match: 正则表达式
会匹配的词汇?
对于当前在 85+ 活跃带中的每个源,扫描新用户消息:
-
匹配找到——用户仍在引用此源的词汇。 该源在下一轮中仍然活跃或交叉相关。轻度降级: 从 85 降到 70。 将其保留在邻近带中,以便当用户 再次输入那些词时,其提示出现。
-
无匹配——用户已远离此源的词汇。 该源已正交解决。强硬降级: 从 85 降到 50。 将其移出牌桌。阻止它与真正活跃的 新源竞争单词匹配。
当不确定时默认:强硬降级。 Bench 证据 (2026 年 5 月):即使在高层领域看似耦合时,大多数转变 在词汇层面都是正交的。默认轻度降级会在用户明显转向后 在邻近带中留下太多过时词汇(网站作品集:T2 关于图库 → T3 关于 Stripe 支付——图库词汇没有出现在 T3 中; 即使两轮都“关于网站”,图库也应强硬降级)。误将一个仍相关的源 强硬降级的代价是当用户回溯时,他们的单词得不到任何提示—— 但用户的新消息是真实依据:如果他们引用了先前的词汇, 正则匹配会捕获。
带有示例(针对相同 v3.0e 规则):
| 先前源 @ 85 | 用户的新消息 | 匹配? | 操作 |
|---|---|---|---|
| gallery-layout `match: gallery | portfolio | grid` | "现在我需要一个带有 Stripe 的联系页面…" |
| jr-pass `match: JR Pass | Shinkansen | reserved` | "JR Pass 就它了。现在住宿…" |
| captaincy `match: captain | armband | differential` | "接下来后卫——Trippier 还是 Gordon" |
| ownership `match: template | differential | owned` | "队长的模板方案" |
规则是基于每个源的,而非基于每轮的。在一轮中,你可能会 对某些先前源强硬降级,对其他源轻度降级——这取决于 每个源的词汇是否实际出现在新用户消息中。
如果两个或多个源都匹配——没问题,都降到 70。 活跃带保持狭窄;邻近带可以容纳几个交叉相关的源而不会稀释。
三带优先级模型
将优先级视为三带开关:
- 85–90 — 活跃焦点(用户当前正在输入的内容)
- 65–80 — 邻近/即将活跃/交叉相关/项目背景
- 50–60 — 近期完成的非相关内容(保持存活但不竞争匹配)
如果你发现自己在 85+ 带中有超过 3 个源, 那就有问题——它们中的大多数应该在 65-80 或 50-60。活跃带应该狭窄。
你不得以“用户尚未使用它”为由删除先前的源。用户现在可能 正围绕它工作;从他们下面抽走它是回路的主要失败模式。
如果你的输出比先前文件中的源少,你就犯了错误。 重新阅读;将缺失的源复制过来。
初始模式——广泛预测
第一次写入是关键。预测用户合理会接触的 每个子词汇——而不仅仅是他们在开场轮次中说的内容。
将用户的种子消息视为关于一个更大空间的单个数据点。
从“我正在为我的摄影作品集构建一个网站”出发,用户只表达了
运行时需要提示的一个词(photography);你的工作是外推
任何工作摄影作品集网站会涉及的 ~15–20 个词族
(专业领域、图库布局、图像格式、部署目标、预约机制、可访问性等)。
无论领域如何,应用相同的扩展。对于“起草一个 A 轮融资演讲稿”, “写小说第 3 章”,或“设置一个 Rails 部署手册”—— 读取种子,生成用户合理会输入的每个子区域。
如果你发现自己停在 8 个源,问“我还缺少什么合理的子词汇?” 并继续到 15–20。前期的广度是回路的产品。 一个在第 2 轮才添加、覆盖了用户刚输入的词的源, 是第 1 轮的失败。
三种提示类型——先 TIPS,再单词提示,再句子提示
OpenCues 支持三种提示类型。Tips 是技能最有价值的输出—— 它们承载用户尚不知道的实际知识(事实、权衡、决策提示、陷阱)。 一个单词提示提供用户本可以头脑风暴出的替代方案; 一个 tip 提供他们无法获得的信息。
输出时的优先级顺序:
- 先 Tips。 对于你提到的每个重要术语,问: “我可以给他们一句事实/陷阱/决策提示吗?”如果“是”——输出一个 tip。
- 单词提示——仅当某个词有多个等价形式且用户可能在它们之间切换时。 如果一个词只有一个规范形式,则无需创建单词提示。
- 句子提示——用于用户正在创作的散文表面。
Tip-cues——关于术语的静态单行知识,无需 LLM 调用
用户输入 webp,tip 弹出:“WebP 在同质量下比 JPEG 文件小约 30%。”
即时,无需往返。这是 OpenCues 提供的最有价值的表面。
每个用户会从操作知识中受益的术语——不仅仅是同义词——
都值得一个 tip。
Word-cues——高亮词的替代方案
默认后备。用户输入 wedding,切换到 bridal。
- Yaml:
match: <regex>或keywords: <comma-list>,加上priority:。没有scope:字段(或scope: words)。 - 最适合: 具有多个大致等价形式的领域词汇——语域、正式度、小众术语。
- 对于你放在替代列表中的每个术语,问:“这个术语是否也值得一个 tip 条目?” 如果“是”——也添加 tip。大多数技术/领域/专有名词的替代项应该有 一个附带的 tip 解释何时/为何选择每个。没有 tip 的替代项是没有上下文的词汇——价值减半。
Sentence-cues——以不同风格重写整个句子
用户写了一个句子;提示提供该句子的三种重写。
- Yaml:
scope: sentence,priority: 75–85,description: <一行>。没有match:——句子提示绑定到整个句子, 而非单词。 - 最适合: 散文表面。任何用户正在创作完整句子并可能想要 风格替代的地方——无论文档是否“散文密集”。一个技术文档 有散文片段(端点摘要、字段描述、手册介绍);一份合同 有散文片段(鉴于条款);一个代码注释有散文;一封邮件 大部分是散文。基于每个表面决定,而非基于每个文档类型。
Tip-cues——详细信息(格式、分类、内容类型)
- Yaml: 仅
name:(在源文件夹中或 CUES.md 的## Tips主体内)。 主体是一个 JSON 代码块,格式为[{id, words: {word: {tip, alts}}}]。 - 最适合: 提示是“你应该知道这些”而非“这是同义词”的术语—— 专有名词、API、工具、平台名称、技术原语、业务决策、司法特殊性。
- Tip 内容类型——超越中性事实:
- FACT —— “WebP 比 JPEG 节省约 30%。”
- DECISION-PROMPT —— “在写定价之前,决定按每次、按小时还是按会话收费——它会改变框架。”
- PITFALL —— “Stripe 对新账户持有资金 7 天。”
- TRADE-OFF —— “为隐私删除 EXIF 或为艺术元数据保留。取决于受众。”
- REFERENCE —— “参见 cloudflarepages.com/docs 了解限制。” 混合使用。一个纯事实的 tip 包不如混合包好。
每表面选择规则
对于你准备输出的每个主题,询问它覆盖哪个表面——并且 始终首先检查 tip-cue 选项:
用户会从一行 FACT / TRADE-OFF / DECISION-PROMPT / PITFALL 中受益的术语 → tip-cue(首选)
术语 + 有 tip 并且有多个等价形式 → tip-cue 带 alts:(给用户两者)
单个有多个等价形式的术语(无有用 tip) → word-cue
用户正在创作的散文(任何长度,任何文档) → sentence-cue
否则 → 跳过
一个 tip-cue 条目也可以携带它……