关于 omh-deep-research
omh-deep-research 是一项多阶段网络研究技能,可综合并核验多个来源的发现,生成研究报告。它适用于单次搜索无法回答的问题,并将工作分为搜索、差距检查、综合和验证阶段。
主要功能
- 01将主题拆分为研究子题
- 02批次并行执行研究任务
- 03检查发现中的研究差距
- 04综合发现并生成报告
- 05核验报告与引用
适用场景
- 01根据多个网络来源撰写报告
- 02规划前研究陌生领域
- 03综合证据回答综合性问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ witt3rd/ oh-my-hermes --skill omh-deep-research安装后在 Claude Code 中输入/omh-deep-research确认已加载。
详细介绍
OMH 深度研究 — 多阶段网络研究与引文核验
适用场景
- 用户要求“深入研究……”“撰写一份关于……的研究报告” “全面研究”“调查 X”“关于 Y 有哪些已知信息”
- omh-deep-interview 遇到陌生领域,需要背景信息
- omh-ralplan 需要外部背景信息才能负责任地制定计划
- 用户的问题需要综合 3 个以上网络来源,形成连贯的答案, 而非仅进行一次搜索
不适用场景
.omh/research/{slug}-report.md中已有该主题的已确认报告, 且其status: confirmed——改为查看该报告- 只需调用一次 web_search 就能回答问题
- 用户只需要实时/时事数据(此技能侧重于持久性综合分析,而非时效性)
- 此 Hermes 安装中没有可用的
web工具集(见前提条件)
前提条件
如果缺少以下任一项,此技能会快速失败:
web工具集 — 提供web_search和web_extract。如果任一工具 不可用,则打印:
并在执行任何工作前退出。omh-deep-research requires the `web` toolset (web_search + web_extract); aborting.omh_state工具 — 首选方式。如果不存在,则回退到手动 读取/写入.omh/state/research--{slug}.json(按实例存储 —{slug}是在阶段 1 生成的 kebab+日期+随机 4 位字符串;多个研究主题 可以并发运行)。如果两种方式都无法写入,则快速失败并显示清晰的错误信息。- 对
.omh/的写入权限,用于保存状态、计划、发现、报告和日志。
Hermes 发现:安装后,hermes skills list | grep omh-deep-research 应当
返回此技能。
安装(为 Hermes 发现创建符号链接)
mkdir -p ~/.hermes/skills/omh && ln -snf <repo>/plugins/omh/skills/omh-deep-research ~/.hermes/skills/omh/omh-deep-research
创建父目录必须先于创建符号链接。
架构
分为 5 个调用阶段,任意两个阶段之间都可以安全退出:
| # | 阶段 | 读取 | 写入 | 子 Agent |
|---|---|---|---|---|
| 1 | decompose | 用户查询 | {slug}-plan.md,state.phase=search | 无 |
| 2 | search | 计划、状态、findings/ | 新建发现文件,state.completed_subtopics、phase | 1-3 个并行 [omh-role:researcher] |
| 3 | gap_check | 所有发现 | 可选的 _followup.md 或直接切换 phase | 0 或 1 个 [omh-role:researcher] |
| 4 | synthesize | 所有发现(由父级内联) | {slug}-report.md status: draft,phase=verify | 1 个 [omh-role:research-synthesist] |
| 5 | verify | 报告 + 发现(由父级内联) | 已确认的 frontmatter/状态变更/阻塞 | 1 个 [omh-role:research-verifier] |
按实例存储状态。 每个研究会话都保存在
.omh/state/research--{slug}.json 中(引擎会将 instance_id
转换为文件名)。多个主题可以同时进行——阶段 1 生成的 slug 即为
instance_id,后续每次调用 omh_state(...) 都会传入 instance_id="{slug}"。
每个会话的产物(计划、发现、报告)均以 slug 为键,存放在
.omh/research/ 下。旧版规范中使用的 research-{id}.json 和
research-state.json(单例)表述已被取代。
文件系统由父级负责。 所有网络工具的使用都在委派的
子 Agent 内进行。父级读取发现文件,并将其内容内联到综合者和核验者的
context 字段中。子 Agent 仅返回文本。
角色只引用,不内联。 使用 [omh-role:NAME] 标记。
完整的角色定义位于 plugins/omh/references/role-*.md 中。
流程
阶段 0:检查现有状态和哨兵文件
在开始任何新的研究会话之前:
- 为新请求生成一个候选 slug(参见阶段 1 规则)。
将其称为
new_slug。后续枚举时需要用它来消除歧义。 - 列出现有研究实例 —
omh_state(action="list_instances", mode="research")。如果该工具不可用,则手动对.omh/state/research--*.json执行 glob。每个条目都包含一个instance_id(== slug)和active标记。 - 对每个活动条目,先执行取消检查:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 如果已取消,则记录CANCELLED slug={slug},并通过omh_state(action="clear", mode="research", instance_id="{slug}")清除该实例。 - 哨兵自我修复(从确认后、清除前发生的崩溃中恢复)。 对每个剩余的活动条目,如果其
.omh/research/{slug}-report.md的 frontmatter 中有status: confirmed,则说明上一次运行在写入哨兵文件后、清除状态前发生崩溃。将其视为已完成:记录REPORT_CONFIRMED_RECOVERED slug={slug},并通过omh_state(action="clear", mode="research", instance_id="{slug}")清除。 - 匹配主题并恢复 —— 如果任何剩余活动条目的
topic与新请求匹配,则直接跳转到该 slug 对应的阶段 2/3/4/5(使用其现有instance_id);不要生成new_slug。 - 该主题已确认 —— 如果存在
{slug}-report.md,且其status: confirmed与新主题匹配,则提示用户选择:刷新(生成新 slug 并重新运行)/查看现有报告/取消。 - 无冲突 —— 使用
new_slug进入阶段 1。允许同时对不同主题开展研究;不要阻止。
阶段 1:分解主题
- 取消检查:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 - 生成 slug — 具体规则:
slug = kebab(topic)[:40] + '-' + YYYYMMDD + '-' + random4其中random4是 4 个小写十六进制字符。kebab()= 转为小写,将连续的非字母数字字符替换为-, 去除开头和结尾的-,截断至 40 个字符。 - 将用户的主题分解为 3-5 个子主题。为每个子主题拟定 2-3 个候选搜索查询。
- 原子写入计划(tmp → fsync → rename)到
.omh/research/{slug}-plan.md,并添加以下 frontmatter:--- status: planning topic: {original user topic} slug: {slug} subtopics: - name: {subtopic 1 name} queries: [{q1}, {q2}, {q3}] - ... --- - 通过
omh_state(action="write", mode="research", instance_id="{slug}", data={...})初始化状态:{ "phase": "search", "slug": "{slug}", "topic": "{topic}", "subtopic_count": N, "completed_subtopics": [], "started_at": "{ISO-8601}", "session_id": "{uuid4}", "synthesis_attempts": 0 } - 记录
STARTED slug={slug}和PLAN_WRITTEN slug={slug} subtopics=N。 - 退出。再次调用时,将通过阶段 0 的恢复路径从阶段 2 继续。
阶段 2:搜索(并行批处理,可重入)
此阶段可重入:每次调用会派发一批最多包含 3 个研究员子 Agent,然后退出。再次调用即可派发下一批。通过 state.completed_subtopics 驱动重入。
- 检查取消状态:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 - 读取状态和
{slug}-plan.md的 frontmatter。 - 计算
pending = [s for s in plan.subtopics if s.name not in state.completed_subtopics]。 - 取下一批
batch = pending[:3](最多并行处理 3 个)。 - 使用
[omh-role:researcher]标记派发一批任务:
每个任务的delegate_task(tasks=[ { "goal": "<self-contained: topic, subtopic name, exact queries to run, output template per [omh-role:researcher]>", "context": "<plan excerpt for this subtopic; no other subagent's findings>", }, ...up to 3... ])goal都完全独立,无需依赖其他子 Agent。每个目标中都必须包含角色标记[omh-role:researcher],以便子 Agent 加载该角色。 - (严格的写入顺序——绝不可颠倒):
- 原子写入本批次的所有 findings 文件(tmp → fsync → rename)。每个文件写入
.omh/research/{slug}-findings/{subtopic-slug}.md,其 frontmatter 需包含subtopic、source_urls,以及从子 Agent 返回的 SOURCES 区块中提取的可信度标签。 - 更新
state.completed_subtopics(扩展列表,并通过omh_state(action="write", mode="research", instance_id="{slug}", data=...)持久化)。 - 退出。
- 原子写入本批次的所有 findings 文件(tmp → fsync → rename)。每个文件写入
- 阶段转换。 下次调用时,阶段 0 会路由回此处。如果写入后
pending变为空,则在退出前设置state.phase = "gap_check"(仍需在 findings 写入之后;顺序为:findings → completed_subtopics → phase flip)。 - 每批记录
BATCH_COMPLETE batch=N subtopics=[name1,name2,...]。
阶段 2 特有的注意事项:
- 跨子主题去重。 两位研究员可能会找到相同的 URL。综合整理者(阶段 4)会通过全局 Sources 重新编号处理跨子主题去重;阶段 2 无需跨文件去重。
- findings 文件名的 slug。 使用
kebab(subtopic.name)[:60]。如果两个子主题转换成相同的 kebab slug,则追加-2、-3等。 - 父级绝不直接调用
web_search或web_extract。 所有网页工具的使用都由委派的[omh-role:researcher]子 Agent 完成。父级的职责是派发任务和操作磁盘。
阶段 3:缺口检查(仅两个分支)
父级技能绝不直接调用 web_search 或 web_extract;所有网页工具的使用都发生在委派的子 Agent 内。
-
检查取消状态:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 -
读取所有
.omh/research/{slug}-findings/*.md文件。提取每个文件中的GAPS:项目符号列表。合并后,按字面去重(忽略大小写并去除首尾空格进行比较;保留首次出现的条目)。 -
仅两个分支:
-
(a) 0 个缺口 — 设置
state.phase = "synthesize",记录GAP_CHECK_COMPLETE gaps=0,退出。 -
(b) ≥1 个缺口 — 委派一个
[omh-role:researcher]子 Agent。 目标:创建名为_followup的合成“子主题”,并将去重后的缺口列表作为查询。父级将返回的文本原子写入.omh/research/{slug}-findings/_followup.md。设置state.phase = "synthesize",记录GAP_CHECK_COMPLETE gaps=N,退出。
不设阈值等级。不按 N 与 M 的缺口数量分支。不设内联
web_search分支。仅有两个分支——这是既定约定。 -
阶段 4:综合(父级内联发现;父级撰写报告)
-
检查取消状态:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 -
父级内联发现内容。 读取
.omh/research/{slug}-findings/下的所有文件(包括存在时的_followup.md)。将它们的完整内容合并到委派的context字段中。综合子 Agent 无权访问文件系统。预算应急方案(已验证安全)。 如果合并后的内容超出编排器的工具参数预算(5 个以上发现文件合计约 40KB 以上为软性阈值),父级可以对每个发现文件的 SYNTHESIS 部分进行摘要,同时保留:
- 完整的 SOURCES
[N]块,原样保留(标题 + URL + 标签 + 日期) - 所有 GAPS 部分,原样保留
_followup块,原样保留(通常最精简且包含最多论据) 不要删除或转述任何 URL、引用标签或数字论断。 2026-04 年实测:一个包含 5 个子主题 + 1 个后续项的运行中,摘要 SYNTHESIS 正文并原样保留来源列表后,通过了高置信度验证,且 28 个全局重新编号的引用均完整无误。 如有疑虑,优先完整内联;仅在不得已时才进行摘要。
- 完整的 SOURCES
-
派发一个
[omh-role:research-synthesist]任务:delegate_task( goal="<self-contained: produce report per [omh-role:research-synthesist] template; topic={topic}; reference inlined plan + findings>", context="<plan frontmatter + every findings file content, fully inlined>", ) -
重试上下文。 如果
state.synthesis_attempts > 0,将之前验证器的 REQUEST_CHANGES 反馈(存储于state.last_verifier_feedback)附加到目标中,格式如下:Address these prior verifier findings: {feedback} -
父级始终覆盖写入
.omh/research/{slug}-report.md,内容为返回的文本。Frontmatter 以status: draft开始。不要添加-v2后缀。之前的判定仅保存在状态中,不写入磁盘。 -
C3 传递。 父级不得编辑返回的报告。任何
(insufficient sources for this subtopic)字符串都必须原样保留。 -
设置
state.phase = "verify",记录REPORT_DRAFT,然后退出。
阶段 5:验证(父级内联;三次失败限制;按序确认)
-
检查取消状态:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 -
父级内联报告 + 发现内容。 读取
{slug}-report.md和所有{slug}-findings/*.md文件。将两者合并到验证器委派的context字段中。验证器子 Agent 无权访问文件系统。 -
工具允许列表(A5)。 派发时传入一个工具允许列表,排除写入/编辑/文件系统工具(前提是 Hermes 支持按调用范围限定工具)。如果 Hermes 不支持按调用范围限定工具,请在已知缺口中说明,并遵循
role-research-verifier.md中的只读约定。 -
派发一个
[omh-role:research-verifier]任务。解析返回的 VERDICT。 -
VERDICT:PASS 时——严格按序执行(绝不可颠倒):
- 将
{slug}-report.md的 frontmatter 写为status: confirmed(原子操作;幂等哨兵;这是唯一可信来源,必须最先写入)。 - 将
REPORT_CONFIRMED slug={slug}追加到事件日志。 - 通过
omh_state(action="clear", mode="research", instance_id="{slug}")清除状态。 - 向用户打印摘要,然后退出。
如果步骤 1 到步骤 3 之间发生崩溃,阶段 0 会自动修复(检测到已确认哨兵后清除孤立状态)。
- 将
-
VERDICT:FAIL 且
state.synthesis_attempts < 3时:- 递增
state.synthesis_attempts。 - 将验证器的 REQUEST_CHANGES 判定(完整正文)存入
state.last_verifier_feedback。 - 设置
state.phase = "synthesize"。 - 记录
VERIFY_FAIL slug={slug}和SYNTHESIS_RETRY attempt={N}。 - 退出。重新调用时会携带反馈上下文重新运行阶段 4。
- 递增
-
VERDICT:FAIL 且
state.synthesis_attempts == 3时:- 设置
state.phase = "blocked"。 - 向用户展示验证器的缺口列表。
- 记录
VERIFY_FAIL slug={slug}和BLOCKED_RETRIES_EXHAUSTED slug={slug}。 - 退出。状态会保留,以便用户检查或升级处理(阶段 0 不会自动重启已阻塞的会话)。
- 设置
日志记录
将事件追加写入 .omh/logs/research-{session_id}.log。事件仅记录决策和阶段转换,不包含任何发现内容(符合 omh-deep-interview 的约定)。
已记录的事件词汇:
STARTED slug={slug}PLAN_WRITTEN slug={slug} subtopics=NBATCH_COMPLETE batch=N subtopics=[...]GAP_CHECK_COMPLETE gaps=NREPORT_DRAFTVERIFY_PASSVERIFY_FAILSYNTHESIS_RETRY attempt=NBLOCKED_RETRIES_EXHAUSTED slug={slug}REPORT_CONFIRMED slug={slug}REPORT_CONFIRMED_RECOVERED slug={slug}BLOCKED slug={slug}CANCELLED
标记文件
下游技能(omh-deep-interview、omh-ralplan、omh-autopilot)通过以下内容检测研究会话是否已完成:
.omh/research/{slug}-report.md with frontmatter `status: confirmed`
此文件是持久化契约。状态是临时的;标记文件才是事实来源。
注意事项
- 绝不要从父级调用
web_search或web_extract。 所有网页工具的使用都发生在委派的[omh-role:researcher]子 Agent 中。 - 绝不要内联角色文本。 使用
[omh-role:NAME]标记;正文位于plugins/omh/references/role-*.md中。 - 阶段边界是提交点。 每个阶段都必须在写入输出并更新状态后干净退出。跨越多次委派的长时间运行阶段无法安全退出。
- 每个项目只能有一个活动研究会话。 阶段 0 会强制执行此规则。不要创建并行的研究状态。
- Slug 冲突对用户可见。
random4后缀可避免同一主题在同一天重复运行时相互覆盖。
已知缺口
- 尚未集成持久化到 wiki / fact_store / memory。 在 v1 中,标记报告是唯一的持久化接口。(Q2)
- 可能无法为
[omh-role:research-verifier]按调用范围限定子 Agent 工具,具体取决于 Hermes 的安装情况;若不可用,则通过role-research-verifier.md中的文字约定强制执行只读契约。(A5)