news 2026/9/20 8:40:02

gbrain 的 Resolve Before Asking:先穷尽大脑查询链,再向用户提问的身份识别守门 Skill

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gbrain 的 Resolve Before Asking:先穷尽大脑查询链,再向用户提问的身份识别守门 Skill
  • 人工智能
  • RAG
  • Agent 记忆
  • MCP 服务
  • 知识管理

【免费下载链接】gbrain

Garry's Opinionated OpenClaw/Hermes Agent Brain

项目地址:https://gitcode.com/gh_mirrors/gb/gbrain
点击查看免费下载

在 gbrain(Garry's Opinionated OpenClaw/Hermes Agent Brain)中,agent 面对任何「X 是谁」「某人与用户是什么关系」这类身份问题,都必须先跑完一条从大脑内部到外部网络的完整查询链;只有整条链都无果,才允许向用户提问——而且提问必须带着假设,绝不能抛出赤裸裸的「who is X?」。本文完整拆解这条守门链路的六步协议、置信度判定、ingest 阶段「无占位符」规则,以及它与 query / brain-ops / ask-user / enrich 等技能的边界划分。

这份 Skill 在解决什么问题

resolve-before-asking是 gbrain 技能体系中负责身份识别问题守门(gate)的技能,定义于 plugin/skills/resolve-before-asking/SKILL.md(仓库同时维护一份相同的 skills/resolve-before-asking/SKILL.md)。其核心承诺一句话可以概括:

Never ask the user "who is X?" when the answer already exists in the brain.(当答案已经存在于大脑中时,永远不要向用户问「X 是谁?」)

这句话背后是一条产品级承诺:记忆应该在打扰用户之前就给出答案——"The memory answers before the human is bothered"(见 SKILL.md)。用户的注意力是稀缺资源,agent 每一次把本可自查的问题抛回给用户,都是在消耗这份资源。

它要「杀死」的 Bug 是一种典型的**懒惰升级(lazy escalation)**模式:agent 明明面对着一个大脑页面极其丰富的实体——带角色描述的 timeline 条目、大量的会议历史、导入的消息归档——却不读这些内容,直接问用户「这个人是谁?」。SKILL.md 中给出了两个匿名化的真实例子:

  • alice-example:她的 brain 页面已经写有角色行("Chief of Staff at acme-example")和长长的会议历史,agent 仍然问了;
  • charlie-example:有一大堆导入的邮件线程,主题行全部指向同一个共享项目,agent 仍然问了。

触发时机:这是一条路由约定,不是机械保证

SKILL.md 明确强调,这是一个harness-routing convention(编排层路由约定),而非机械保证。只要满足以下任意一条,就应路由到本技能:

  1. 回复草稿中出现 "who is [name]?" 或等价表达;
  2. 草稿在询问某人的角色、关系或身份;
  3. 即将把一个实体呈现为 "unknown" 或 "unidentified";
  4. 大脑页面存在[To be filled by content analysis]或类似的占位文本;
  5. 正在整理一份人员清单,却把某些人留作 "unknown relationship"。

这一路由约定在仓库中有对应的测试夹具支撑:skills/resolve-before-asking/routing-eval.jsonl定义了多组意图样本,其中明确写道「This skill owns WHETHER an identity question reaches the user; plain lookups route to query, page enrichment to enrich, choice-gate mechanics to ask-user」。例如"I have an unidentified contact in this reply draft — run resolve before asking"路由到本技能,而"who is alice-example? tell me about her background"这类纯查询则明确路由到query"what's for breakfast"则无技能匹配(expected_skill: null)。同时 skills/RESOLVER.md 把"resolve before asking""unidentified contact""unknown relationship"等触发短语直接映射到本技能文件。

六步查询链:按序执行,遇到第一个明确答案就停

这是整份技能的核心骨架。查询链必须严格按顺序执行,在第一个给出明确答案的步骤就 STOP,绝不跳过。

Step 1:think—— 跨大脑综合(解决大多数情况)

gbrain think "Who is {entity}? What is their relationship to the user? What role do they play? Use all available context — meetings, timeline, imported archives, facts."

think会跨越全部大脑数据进行综合。如果该实体有一个带导入活动统计、timeline 条目和会议历史的页面,think能把这些点连成线。在源码层面,think是 src/commands/think.ts 中runThinkClirunThink的封装,它支持--anchor <slug>(拉取某 slug 周边的实体子图)、--rounds N(多轮综合)、--since/--until(时间窗口)、--source <id>(限定证据来源范围)等参数,并通过--save把综合结果持久化为synthesis/<slug>-<date>.md页面。think是一个需要 LLM 调用的昂贵路径(见 skills/brain-ops/SKILL.md Phase 1.5 的提示),但它返回的是「有引用、有冲突/缺口分析的回答」,而不只是「匹配页面列表」。

在 MCP 传输层上,entity("{entity}")首先返回一张零 LLM 调用的卡片(aliases、last-touched、top edges,brain-ops中描述为 sub-100ms 的gbrain entity调用);当卡片信息不足时,synthesize才是重型跨页答案。

如果这一步返回了明确答案 → STOP,直接使用答案,不要问用户。

Step 2:search+ 整页读取

gbrain search "{entity}" --limit 5 gbrain get {entity-slug}

这一步要看的东西有四处:

  • frontmatter 中的relationship字段——已填充即已解决
  • timeline 条目中反复出现的角色信号("advisor"、"colleague at acme-example"、"chief of staff");
  • Facts 表——任何角色/关系类事实;
  • 会议历史——这个人参加过哪些会议?和谁一起?

如果 timeline 条目反复出现一致的角色 → STOP,角色已经显而易见,不要问用户。

Step 3:逐一查询大脑实际挂载的每个 source

不要硬编码渠道。先检查大脑持有哪些数据,再按数据形态查询:

gbrain sources list gbrain query "emails with {entity}" --limit 10 gbrain query "meetings with {entity}" --limit 5

gbrain sources list对应 src/commands/sources.ts 的 sources 子命令族——source 是「DB 内的大脑子库」(wiki、gstack、yc-media 等),每个页面/文件/ingest_log 行都归属于某个sources(id),slug 在 source 内唯一。无论挂载了什么——邮件归档、日历导入、聊天记录、会议笔记——几条主题行或会议标题通常就能暴露关系

  • Invoice / scheduling / billing 类主题 → 专业服务关系;
  • 会议标题反复出现且与会者一致 → 同事;
  • Dinner / weekend-plan 类消息 → 私人朋友。

Step 4:Timeline + 图遍历

gbrain timeline {entity-slug} --limit 20 gbrain backlinks {entity-slug} gbrain graph {entity-slug} --depth 2

看带日期的活动、谁引用了这个实体、它连接着什么。一个从公司页面和三张会议页面反向链接过来的(back-link)的人,绝不是 unknown。反向链接是 gbrain 的「Iron Law」之一(见 skills/_brain-filing-rules.md 的 Back-Linking 铁律:每个提到某人/某公司的页面必须从该实体页面创建反向链接)——「An unlinked mention is a broken brain. The graph is the intelligence.」

Step 5:Web 搜索(外部升级,遵循 brain-first)

只有在步骤 1–4 都一无所获之后才执行。用"{entity name} {company/domain hints accumulated in steps 1-4}"做一次通用网络搜索,并把任何发现先回写(fold back)到大脑页面再使用——这正是 brain-ops 的 read-enrich-write 循环,确保下一次查询不会重复做功。

这一顺序的合法性来自 skills/conventions/brain-first.md 的基础查询链约定(search → query → get_page → external APIs),本技能把这条链再向外延伸一跳,到达人类边界:向用户提问是最后的最后手段,排在「大脑」与「外部升级」之后。

Step 6:升级给用户(最后手段)——带假设提问

只有当所有前面的步骤都返回不了结论时:

  • 说明你搜了什么(State what you searched);
  • 说明你找到了什么——哪怕是部分信号(State what you found);
  • 提出一个具体、可确认的问题:不是「X 是谁?」而是「{entity} 是不是 {根据部分信号拼出的最佳猜测}?」

选择门的机制细节(2–4 个选项、逃生通道、停止回合)交给 ask-user 处理——它定义了完整的 choice-gate 模式:2–4 个选项上限、强制逃生通道(Skip/Cancel)、标签必须是「动词 + 简短限定词」、发出选项后必须停止回合(不继续行动、不预选默认值)。

置信度阈值:只有两种状态

置信度判定条件行动
高置信(不提问)think/synthesize给出明确答案,3+ 条 timeline 条目携带一致的角色描述,页面relationship字段已填充使用答案,不问用户
低置信(带着最佳猜测提问)信号矛盾或数据极稀疏提问,但问题以假设开头,并陈述矛盾(如有)

不存在第三种状态。要么大脑回答了(用它),要么没回答(跑完整个链,然后带假设提问)。这是 SKILL.md 明确划下的边界,杜绝「部分信号 = 已解决」的虚假置信。

No Placeholders at Ingest:摄入阶段同步解决

这是本技能的第二个重要职责,覆盖所有摄入管线——邮件导入、日历 enrich、聊天记录、会议摄入——创建的或显著更新的人物/公司页面:

以下这些页面形态都是 Bug:

  • [To be filled by content analysis]
  • > Contact from the user's personal network.
  • 空的## Context小节

尤其当摄入批次本身就携带了几百条关于这个人的信号时。因此要在每次批量摄入后,对所有被创建/更新的页面执行一次后处理扫描

  1. 检查占位符:扫描被触碰页面的标记([To be filledUnknown relationshipTBD)。无占位符且relationship已填充 → 跳过(已解决)。
  2. 跑查询链(上述步骤 1–4;在 ingest 时刻,通常第 1 步think就够,因为批次刚写入了think所需的信号)。
  3. 抽取:关系类型(friend / colleague / advisor / family / founder)、职业角色(title + company)、关键上下文(如何认识用户、什么时代)。
  4. 更新页面put_page):填充relationshipfrontmatter 字段、用真实一句话描述替换占位描述、更新## Context或开篇段落。
  5. 批量效率(100+ 页的大批量):每批 10–20 页处理;按 captured-activity 量排序(活动越多,用户在 briefing 中遇到这个名字的可能性越大);跳过已经实质性的页面。

Email 域名捷径(假设生成器,不是证据)

在跑链之前,发件人域名经常就能种下假设:

域名形态假设
@acme-example.com—— 大脑中已有的公司很可能是 acme-example 员工。对照公司页 + 共享会议确认后再填充。
大脑中没有的企业域名新公司。跑完整链条;考虑播种一个companies/页面。
个人域名(gmail 等)没有捷径——跑完整链条。

注意技能对此的定位非常谨慎:域名只是假设生成器(hypothesis generator),不是证明("not proof")。

质量标准

一个「已解决」的页面要能通过这个测试:如果用户在 briefing、triage 或会议准备中遇到这个名字,页面的第一行就能说出这个人是谁,无需用户再问。

  • 坏:> Contact from the user's personal network.
  • 好:> Operations lead at acme-example — handles invoicing and vendor onboarding for the user.

这条质量标准与_brain-filing-rules.md的归档规则(按主主题归档到people/companies/)以及 enrich 的分层 enrich 协议互为表里——「No Placeholders at Ingest」正是 enrich 写入必须达到的验收标准。

输出格式:静默解决 vs 带假设升级

(a) 静默解决(Resolved silently)

身份被用于当前流程;如果页面有占位符,则以put_page顺带填充。不向用户发送任何关于这次查询的消息。

(b) 带假设升级(Escalation with a hypothesis)

按 ask-user 的选择门格式输出:

🔀 **Is {entity} the {best guess}?** Searched: think, search + page read, mounted sources, timeline/graph, web. Found: recurring invoices from @widget-co.com; two meetings alongside the acme-example team. Nothing names their role directly. 1. **Confirm** — {entity} is {best guess} 2. **Correct me** — it's someone else (tell me who) 3. **Skip** — leave unresolved for now

发出选择门之后停止回合(详见 ask-user)。

反模式清单(Anti-Patterns)

  • ❌ 没有先做任何查询就抛「Who is X?」;
  • ❌ 大脑页面有几十条 timeline 条目,还问「他们和你什么关系?」;
  • ❌ 列出一堆 unknown 却没有对每一个跑查询链;
  • ❌ 在摄入批次携带几百条信号的页面上留下[To be filled by content analysis]
  • ❌ 询问一个邮件地址本身就暴露雇主的人(jane@acme-example.com);
  • ❌ 用memory_search做实体查询——memory 工具搜的是会话笔记(MEMORY.md),不是大脑知识图谱,brain-first.md 明确禁止;应使用search/query/entity
  • ❌ 把非零的search命中数当作「链已完成」——必须读页面;在断言「大脑里没有」之前,还要用query跑同义词改写。这一点在brain-first.md中同样被强调("A nonzerosearchcount is NOT a completeness signal");
  • ❌ 带着虚假置信升级——部分信号是假设,不是解决;如果信号矛盾,升级时必须陈述矛盾。

技能边界(Dedup):谁拥有什么

这份技能与相邻技能有刻意划清的锐利边界,理解这些边界是正确使用的前提:

技能拥有什么与 resolve-before-asking 的关系
query查询动词机制(3 层搜索、综合、引用)本技能消费同样的工具,但拥有的是一个决策(身份问题是否允许到达用户),而非一次查询
brain-ops每次大脑交互的通用 read-enrich-write 循环本技能是该循环某一条特定出口(面向人类的身份问题)上的闸门
ask-user如何提问(选择门格式、选项上限、停止回合)本技能拥有是否应该提问,以及问题必须包含什么(searched / found / hypothesis)
enrich用分层 enrich 协议创建和更新实体页本技能的「No Placeholders at Ingest」是 enrich 写入必须达到的验收标准;占位符需要填充时,先跑本技能查询链,再按 enrich/brain-ops 约定写入
conventions/brain-first.md所有查询的「大脑优先于外部 API」顺序本技能继承该顺序,并加上最后一层边界:外部优先于人类
建页前去重守卫(dedup-before-create)写入时防止重复页面不同的失败类别:它防止写入期的重复页,本技能防止询问期的无用提问。交叉引用,不合并

最终检验标准

SKILL.md 用一句话定义了这个标准的检验方式(The Standard):

用户看着这个人的大脑页面——导入的归档、暴露雇主的邮件域名、反复重复同一角色的 timeline 条目——会不会觉得 agent 问「这个人是谁」是合理的?

如果答案是不会,说明查询链没跑完。跑完它。

延伸阅读

  • resolve-before-asking 技能定义 与 skills 目录下的同源副本
  • 基础查询链约定:skills/conventions/brain-first.md
  • 归档规则(按主主题归档到people/companies/):skills/_brain-filing-rules.md
  • 选择门机制:skills/ask-user/SKILL.md
  • 大脑读写循环:skills/brain-ops/SKILL.md
  • think命令源码:src/commands/think.ts;sources 管理源码:src/commands/sources.ts
  • 路由测试夹具:skills/resolve-before-asking/routing-eval.jsonl
  • 人工智能
  • RAG
  • Agent 记忆
  • MCP 服务
  • 知识管理

【免费下载链接】gbrain

Garry's Opinionated OpenClaw/Hermes Agent Brain

项目地址:https://gitcode.com/gh_mirrors/gb/gbrain
点击查看免费下载

相关推荐

上一篇:DebugSwift WebView网络监控:WKWebView请求追踪完整指南
下一篇:免费PDF补丁丁:批量修好书签、尺寸、被锁的文档

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 8:38:26

低速永磁同步电机在稠油开采中的技术突破与应用

1. 低速潜油永磁同步电机的行业背景在石油开采领域&#xff0c;稠油井的开采一直是个技术难题。稠油就像蜂蜜一样黏稠&#xff0c;流动阻力大&#xff0c;常规的抽油设备很难高效工作。这时候就需要螺杆泵这种专门对付高黏度原油的设备出场了。但问题来了——螺杆泵需要匹配低速…

作者头像 李华
网站建设 2026/9/20 8:37:54

LibreChat 自托管部署与多模型配置实战指南

LibreChat 这个项目&#xff0c;第一次听到的人多半会愣一下&#xff1a;名字里带个“Libre”&#xff0c;又带个“Chat”&#xff0c;直觉上像是个开源聊天工具&#xff0c;但真去翻它的仓库和文档&#xff0c;会发现它远不止“又一个聊天界面”那么简单。它更像是一个把大模型…

作者头像 李华
网站建设 2026/9/20 8:37:46

PAT乙级1092字符串处理技巧与算法实现

1. 题目解析与核心思路PAT乙级1092是一道典型的字符串处理类编程题目&#xff0c;主要考察考生对字符串操作和基础算法的掌握程度。题目通常会给出一个字符串或一组字符串&#xff0c;要求实现特定的处理逻辑&#xff0c;比如统计字符出现次数、查找特定模式或进行字符串转换等…

作者头像 李华
网站建设 2026/9/20 8:36:55

离线交付实战:隔离机房环境下的依赖打包与部署设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 8:36:23

从OnlyOffice迁移到LibreOffice Online:在线文档编辑方案选型与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华