Hermes 子代理委派 —— 并行工作的艺术

第14篇:子代理委派 ------ 并行工作的艺术

delegate_task 工具让主 Agent 生成子 Agent 实例,每个子代理拥有隔离上下文、继承工具访问、独立终端 session。子代理从全新对话开始,仅最终摘要进入父上下文。

单任务委派

python 复制代码
delegate_task(
    goal="Debug why tests fail",
    context="Error: assertion in test_foo.py line 42"
)

并行批量委派

默认最多 3 个并发子代理(可配置):

python 复制代码
delegate_task(tasks=[
    {"goal": "Research topic A", "context": "Focus on recent primary sources"},
    {"goal": "Research topic B", "context": "Compare the leading explanations"},
    {"goal": "Fix the build", "context": "Project root: /home/user/project"}
])

子代理上下文规则(关键)

子代理从完全全新的对话 开始,对父对话历史一无所知。必须通过 goalcontext 传入所有必要信息:

python 复制代码
# BAD --- 子代理不知道 "the error" 是什么
delegate_task(goal="Fix the error")

# GOOD --- 子代理获得完整上下文
delegate_task(
    goal="Fix the TypeError in api/handlers.py",
    context="""The file api/handlers.py has a TypeError on line 47:
    'NoneType' object has no attribute 'get'.
    The project is at /home/user/myproject and uses Python 3.11."""
)

Max Iterations

每个子代理有迭代限制(默认 50):

python 复制代码
delegate_task(
    goal="Quick file check",
    context="Check if /etc/nginx/nginx.conf exists",
    max_iterations=10  # 简单任务
)

嵌套委派(深度控制)

默认为扁平模式(depth=1),子代理不能再委派:

python 复制代码
delegate_task(
    goal="Survey three code review approaches",
    role="orchestrator",  # 允许此子代生成自己的 worker
    context="...",
)
  • role="leaf" (默认):不能再委派
  • role="orchestrator":保留 delegation 工具集,受 max_spawn_depth 约束

被阻断的工具

即使父代理拥有,以下工具在子代理中被阻断:delegate_task(leaf)、clarifymemorysend_messagecronjobexecute_codeterminal 保留。

完整配置

yaml 复制代码
delegation:
  max_iterations: 50                        # 每个子代理最大轮次
  max_concurrent_children: 3                # 每批并行子代理数
  max_spawn_depth: 1                        # 委派树深度(1=扁平)
  orchestrator_enabled: true                # 全局关闭设为 false
  model: "google/gemini-3-flash-preview"    # 子代理模型覆写
  provider: "openrouter"                    # 子代理 provider 覆写
  child_timeout_seconds: 0                  # 0=无超时

监控运行中子代理

text 复制代码
/agents    # TUI 中查看子代理树视图
/tasks     # 同上别名

实时日志:

bash 复制代码
tail -f ~/.hermes/cache/delegation/live/deleg_ab12cd34/task-0.log

Q&A

Q1: 子代理能访问父对话的历史吗? A1: 不能。子代理从全新隔离对话开始,对父对话一无所知。必须通过 goalcontext 参数传入所有必要信息,这是最常见的错误来源。

Q2: delegate_task 和 execute_code 有什么区别? A2: delegate_task 生成完整的 LLM Agent,有推理循环、工具访问和判断力;execute_code 只是执行一段 Python 脚本,没有推理能力。前者适合需要判断力的复杂任务,后者适合机械式多步流水线。

Q3: 嵌套委派的成本如何控制? A3: max_spawn_depth: 3 + max_concurrent_children: 3 最多产生 27 个并行叶代理,成本很高。建议深度设为 1(扁平模式),仅对编排者角色开启更深层级。

@gkisokay 的 Codex 运行时监控:让 AI 看着 AI 干活

Hermes Agent 深度拆解 · 第 14 篇

@gkisokay 的 Codex 运行时监控:让 AI 看着 AI 干活

如果一个 AI 能盯着另一个 AI 工作,实时发现它在哪里出错,当场修好然后继续跑------这不是科幻,这是 @gkisokay 在 "Building AGI for my Hermes Agent" 系列第 10 天的真实操作。Codex + GPT-5.4 以 extra-high 推理档位充当运行时监督者,监视 Hermes 的 agent-to-agent 工作流,在断点处捕获、修复、重试,直到工作流稳定可靠。这是"AI 监控 AI"范式从概念走向实践的关键案例。

作者:@gkisokay 分类:X / Twitter · Dev Workflow 来源:X 推文 + 官方用户故事 发布:2026-04-17

PART 01

案例背景 + 溯源 + 整体架构

开篇:当一个 AI 盯着另一个 AI 干活

想象一下这个场景:你的 agent 工作流正在运行,多个子 agent 互相委派任务、调用工具、传递上下文------然后某个环节静默失败了。你可能要等几十分钟甚至几个小时才意识到出了问题,然后翻日志、定位断点、手动修复、重新跑。这个调试循环在 agent-to-agent 架构中尤其痛苦,因为失败可能在任何一个委派环节发生,而且错误会沿着工作流级联传播。

现在,如果在工作流旁边放另一个 AI------它不参与干活,只负责看。它盯着工作流的每一步状态,发现哪里断了就报出来,然后当场修好让工作流继续跑,直到整个流程稳定可靠。这就是 @gkisokay 在 "Building AGI for my Hermes Agent" 系列第 10 天做的事情:用 OpenAI Codex 搭载 GPT-5.4,以 extra-high 推理档位,充当 Hermes agent-to-agent 工作流的运行时监督者。

核心创新:"AI 监控 AI" 范式

本案例的技术亮点不在于 Hermes 的 agent-to-agent 委派能力本身------那是 Hermes 文档化的原生能力。真正的创新在于跨系统监督 :Codex 作为一个独立的外部 AI 系统,以运行时监督者的角色旁路监视 Hermes 的工作流执行,而非参与执行本身。Codex 负责watch → catch → fix,Hermes 负责delegate → execute → deliver。两个 AI 系统协同:一个干活,一个盯着干活。

作者原话

"Day 10 of Building AGI for my Hermes Agent: Codex saved the day as a runtime monitor for my agent-to-agent workflows. I used Codex with GPT-5.4 on extra-high to watch the workflow run, catch where it broke, and fix it live until it worked reliably."

--- @gkisokay,2026-04-17,X (Twitter)

另一句来自 CSDN 文章的补充引用,进一步揭示了作者的 agent 分工哲学:

"OpenClaw does the junior work, Hermes is the senior."

--- @gkisokay,CSDN 文章

这两句话合在一起,勾勒出一个清晰的分层架构:OpenClaw 做初级工作,Hermes 做高级工作,Codex 监控全局。而 Codex 的关键参数------GPT-5.4 + extra-high 推理------意味着监督者拥有比执行者更强的推理能力,这正是它能"捕获断点并修复"的前提。

溯源信息

溯源渠道与原始链接

作者@gkisokay (X/Twitter) / Gkisokay (GitHub)

原始推文x.com/gkisokay/st...

官方用户故事hermes-agent.nousresearch.com/docs/user-s...

发布日期2026-04-17

分类X / Twitter · Dev Workflow

故事标题"Codex watches my Hermes agent-to-agent workflows live"

系列"Building AGI for my Hermes Agent"(第 10 天)

GitHubgithub.com/Gkisokay(账号存在,但无任何公开仓库

GitHub 简介"Building tools for myself, that you will like as well."

代码可用性不可用(单条推文,无代码、无仓库、无配置文件)

诚实声明:案例性质

本案例是一条单条推文 ,没有对应的 GitHub 仓库(账号存在但无公开 repo)、没有公开的配置文件、没有可审查的代码、没有工作流定义文件。我们能确认的事实仅有:(1) 推文由 @gkisokay 发布于 2026-04-17;(2) 该故事被收录在 Hermes Agent 官方用户故事页面;(3) 推文中明确提及 Codex + GPT-5.4 + extra-high 推理 + agent-to-agent 工作流 + watch/catch/fix 三步流程。本文中所有重建内容------架构图、配置模板、代码实现------均基于 Hermes 文档化的 agent-to-agent 能力(delegate_task、子 agent 生成、工作流管线)和 Codex CLI 的已知监控特性推导而来,并非来自原作者的实际代码。凡涉及推导内容,均以 重建 标签明确标注。此外,"Day 10" 意味着此前有 9 天的上下文我们完全不了解------作者可能已经在 Day 1-9 中构建了大量的 Hermes 工作流基础设施。

案例元数据

字段
故事标题 "Codex watches my Hermes agent-to-agent workflows live"
作者 @gkisokay
来源平台 X (Twitter)
发布日期 2026-04-17
分类 X / Twitter · Dev Workflow
系列 "Building AGI for my Hermes Agent" Day 10
监督工具 OpenAI Codex CLI + GPT-5.4
推理档位 extra-high(最高推理强度)
执行系统 Hermes Agent(agent-to-agent 工作流)
监控三步 watch(监视运行) → catch(捕获断点) → fix(实时修复)
终止条件 "until it worked reliably"(直到稳定可靠)
代码可用性 不可用(单条推文,无代码)
仓库可用性 不可用(GitHub 账号存在但无公开仓库)
配置可用性 不可用(无公开配置文件)
可复现性 可基于 Hermes 文档化能力 + Codex CLI 特性重建 重建

业务问题:Agent-to-Agent 工作流的调试困境

@gkisokay 面临的问题,是所有构建多 agent 系统的开发者都会遇到的:agent-to-agent 工作流在什么地方断掉,很难知道。让我们拆解一下为什么这个问题如此棘手。

调试挑战 说明 为什么传统调试方法失效
静默失败 子 agent 委派任务后,接收方可能返回看似合理但实际错误的结果 没有异常抛出,没有报错日志,工作流继续往下走但已经偏离正确路径
级联传播 步骤 2 的错误输出成为步骤 3 的输入,错误在工作流中传播放大 等你发现问题时,根因可能已经被 3 层委派掩盖
上下文丢失 每个子 agent 有独立的上下文窗口,委派时可能丢失关键信息 无法像单线程程序那样设断点检查完整调用栈
非确定性 LLM 驱动的 agent 输出不确定,同样的输入可能产生不同结果 无法可靠地"重放"失败场景,传统单元测试范式不适用
并行复杂度 多个子 agent 可能并行执行,交互时序难以追踪 日志交错、竞态条件、死锁------分布式系统的所有老问题

这些挑战的叠加效应是:当一个 agent-to-agent 工作流跑不通时,你往往不知道是哪个 agent 的哪个步骤出了问题,更不知道怎么修。@gkisokay 的解法不是去改善调试工具------而是直接放一个更聪明的 AI 在旁边盯着。

"AI 监控 AI" 范式

这个范式的核心洞察是:调试 agent 工作流需要的不只是日志和断点,而是推理能力。传统调试工具(日志聚合、APM、分布式追踪)能告诉你"发生了什么",但无法告诉你"为什么这是错的"以及"应该怎么修"。而一个具备强推理能力的 AI 可以同时做这三件事。

范式对比:传统监控 vs AI 监控

**传统监控(如 Prometheus + Grafana):**采集指标 → 设定阈值 → 触发告警 → 人工排查 → 人工修复。告警告诉你"错误率升到 15%",但不告诉你"为什么"和"怎么办"。

**AI 监控(Codex + GPT-5.4):**读取工作流状态 → 推理"这步的输出是否合理" → 如果不合理,推理"根因是什么" → 生成修复方案 → 应用修复 → 重试。监督者不仅能发现问题,还能理解问题和修复问题------全程无需人工介入。

这个范式还有一个隐含的前提:监督者必须比执行者更聪明。@gkisokay 选择了 GPT-5.4 的 extra-high 推理档位------这是 OpenAI Codex CLI 提供的最高推理强度。一个低推理档位的监督者可能无法识别执行者的微妙错误,更无法生成正确的修复方案。extra-high 意味着监督者在每次决策时都会进行更深度的思维链推理,代价是更高的 token 消耗和更慢的响应速度------但对于"捕获断点并修复"这种需要深度理解的场景,这是值得的。

三步监控流程

从作者原话中,我们可以精确提取出三步监控流程:

1 watch the workflow run

2 catch where it broke

3 fix it live

4 until it worked reliably

步骤 原话片段 实际操作 Codex 能力
1. Watch "watch the workflow run" Codex 持续读取 Hermes 工作流的状态文件、日志输出和子 agent 间消息,理解当前执行进度 Codex CLI 的文件监视 + 上下文读取能力
2. Catch "catch where it broke" Codex 推理每一步的输出是否合理,识别断点位置------哪个子 agent 的哪个步骤产生了错误或异常 GPT-5.4 extra-high 推理 + 工作流语义理解
3. Fix "fix it live" Codex 生成修复方案(修改 prompt、调整参数、重写委派逻辑),应用到工作流中,然后让 Hermes 重试 Codex 代码生成 + 文件编辑 + 命令执行
4. Loop "until it worked reliably" 重复 watch → catch → fix 循环,直到工作流连续多次稳定运行,满足"可靠"判据 迭代修复 + 可靠性评估

"until it worked reliably" 的含义

"reliably"(可靠地)是整个流程的终止条件,但它是一个主观词。在重建中,我们将其解释为:连续 N 次运行无断点、无人工干预、输出符合预期。具体 N 值取决于工作流复杂度------简单工作流可能 N=3 即可,复杂的多 agent 交互可能需要 N=10。Codex 需要一个显式的可靠性判据来决定何时停止修复循环,否则它可能永远修下去(或过早宣布成功)。

Hermes 原生能力清单

本案例依赖以下 Hermes 文档化的原生能力1,以及 Codex CLI 的已知特性2

01 delegate_task 工具

Hermes 原生的 agent-to-agent 委派能力。主 agent 可以将子任务委派给子 agent,子 agent 在隔离上下文中执行并返回结果。工作流管线的技术基础。

02 子 Agent 生成

Hermes 支持动态生成子 agent,每个子 agent 拥有独立的 SOUL.md profile、工具集和上下文窗口。实现并行工作流隔离。

03 工作流状态文件

Hermes 在执行工作流时持续写入状态文件(JSON/YAML),记录每一步的执行状态、输入输出和时间戳。这是 Codex 监视的"数据源"。

04 终端后端

Hermes 7 种原生终端后端(local/Docker/SSH/Singularity/Modal/Daytona/Vercel Sandbox),子 agent 执行命令的底层能力。

05 跨会话记忆

Hermes 记忆层跨会话保留信息。工作流状态、修复历史、可靠性指标均可持久化,Codex 可读取历史修复记录避免重复犯错。

06 Codex CLI 文件监视

OpenAI Codex CLI 具备文件系统监视能力,可实时检测工作流状态文件的变化,触发监控逻辑。GPT-5.4 + extra-high 提供深度推理。

五层架构 重建

基于 Hermes 的文档化 agent-to-agent 能力和 Codex CLI 的已知特性,我们重建这套"Codex 监控 Hermes"系统的五层架构。从上到下依次为:监督层、编排层、工具层、持久化层和部署层。

监督层

Codex Supervisor(GPT-5.4 extra-high)

旁路监视工作流 → 推理断点 → 生成修复 → 应用并重试 → 评估可靠性

↓ 读取状态文件 / 写入修复指令

编排层

Hermes Agent-to-Agent Orchestrator

delegate_task → 子 agent 生成 → 工作流管线 → 结果汇总

↓ 调用工具

工具层

Hermes Tools:terminal · file · web · browser · memory · skills

每个子 agent 拥有独立工具集,按 SOUL.md profile 配置

↓ 读写状态

持久化层

Hermes 记忆(跨会话) · Codex 会话上下文 · 工作流状态文件 · 修复历史日志

状态文件是 Codex 与 Hermes 之间的"通信介质"

↓ 运行于

部署层

本地 或 VPS(Hermes + Codex 同时运行)

两个 AI 系统共享文件系统,通过状态文件实现松耦合通信

架构关键点:松耦合通信

注意这套架构的核心设计:Codex 和 Hermes 之间没有直接 API 调用。它们通过共享文件系统上的"工作流状态文件"实现松耦合通信。Hermes 写状态文件(记录每一步的执行状态),Codex 读状态文件(监视进度、推理断点),Codex 写修复指令文件(修改工作流定义或子 agent 配置),Hermes 读修复指令文件(应用修复并重试)。这种设计意味着两个系统可以独立运行、独立升级,互不依赖对方的内部 API。

"Building AGI" 系列:Day 10 的上下文

推文标题中的 "Day 10" 是一个重要线索。它意味着 @gkisokay 已经在连续 9 天中构建了某种 Hermes 基础设施------可能是自定义工具、记忆架构、SOUL.md profile、工作流定义等。第 10 天引入 Codex 作为运行时监控者,说明前 9 天的工作流已经复杂到需要外部监督的程度。

我们无法获知 Day 1-9 的具体内容------@gkisokay 的 GitHub 账号存在但没有公开仓库,推文也只描述了 Day 10 的操作。但可以合理推测:一个需要"运行时监控"的 agent-to-agent 工作流,至少包含多个委派层级和工具调用链路,否则简单的单元测试就足以验证可靠性,不需要一个 GPT-5.4 级别的监督者。

PART 02

分步搭建教程 + Hermes 命令完整参考

完整搭建流程 重建

以下步骤基于 Hermes 官方文档和 Codex CLI 的已知特性重建。@gkisokay 的实际操作流程可能有所不同,但核心路径一致:配置 Hermes 多 agent 环境 → 定义工作流管线 → 配置 Codex 为外部监督者 → 设定 extra-high 推理 → 运行工作流 → 观察 Codex 捕获断点 → 观察实时修复。

前置条件
  • Hermes Agent 已安装并完成初始化,具备多 agent 委派能力(delegate_task 工具可用)
  • OpenAI Codex CLI 已安装并完成认证,可访问 GPT-5.4 模型
  • 拥有一个已定义的 agent-to-agent 工作流(子 agent 角色已规划)
  • Hermes 和 Codex 共享同一个文件系统(本地或同一 VPS)
  • 工作流状态文件输出目录已创建且 Codex 有读写权限
  • OpenAI API 账户余额充足(extra-high 推理档位消耗显著)
Step 1:配置 Hermes 多 Agent 委派

Hermes 的 agent-to-agent 委派通过 delegate_task 工具实现。你需要在 config.yaml 中启用多 agent 模式并定义子 agent profile。

yaml 复制代码
# ~/.hermes/config.yaml --- Hermes 多 Agent 配置 重建
agent:
mode: multi # 启用多 agent 模式
delegate_task: true # 启用 delegate_task 工具
max_sub_agents: 5 # 最大并行子 agent 数量
sub_agent_timeout: 300 # 子 agent 超时(秒)
# 子 Agent Profile 定义
sub_agents:
researcher:
model: gpt-5.4 # 子 agent 使用的模型
soul_file: ~/.hermes/souls/researcher.md
tools: [web_search, browser, file_read]
max_tokens: 4096
coder:
model: gpt-5.4
soul_file: ~/.hermes/souls/coder.md
tools: [terminal, file_write, file_read]
max_tokens: 8192
reviewer:
model: gpt-5.4
soul_file: ~/.hermes/souls/reviewer.md
tools: [file_read, terminal]
max_tokens: 4096
# 工作流状态文件输出(供 Codex 监视)
workflow:
state_dir: ~/.hermes/workflow_state # 状态文件输出目录
state_format: json # 状态文件格式
write_interval: 1 # 状态写入间隔(秒)
log_level: debug # 详细日志级别
Step 2:定义 Agent-to-Agent 工作流管线

工作流管线定义了子 agent 之间的委派关系和执行顺序。Codex 将监视这个管线的执行状态。

yaml 复制代码
# ~/.hermes/workflows/feature_pipeline.yaml --- 工作流定义 重建
name: feature_development_pipeline
description: "研究 → 编码 → 审查 三阶段 agent-to-agent 工作流"
steps:
- id: step_1_research
agent: researcher # 委派给 researcher 子 agent
task: "调研用户需求,搜索相关技术方案"
input: "{{user_request}}" # 从用户输入获取
output_key: research_result # 输出存入此键
retry_count: 0 # Codex 修复后递增
max_retries: 5 # 最大重试次数
- id: step_2_code
agent: coder # 委派给 coder 子 agent
task: "根据研究结果编写实现代码"
input: "{{research_result}}" # 依赖 step_1 输出
depends_on: step_1_research # 前置依赖
output_key: code_result
retry_count: 0
max_retries: 5
- id: step_3_review
agent: reviewer # 委派给 reviewer 子 agent
task: "审查代码实现,检查正确性和安全性"
input: "{{code_result}}"
depends_on: step_2_code
output_key: review_result
retry_count: 0
max_retries: 5
reliability:
target_consecutive_success: 3 # "可靠"判据:连续 3 次成功
timeout_total: 3600 # 总超时(秒)
Step 3:配置 Codex 为外部监督者

Codex CLI 需要被配置为监视 Hermes 的工作流状态目录。关键是设定 GPT-5.4 模型和 extra-high 推理档位。

yaml 复制代码
# ~/.codex/monitor_config.yaml --- Codex 监督者配置 重建
model: gpt-5.4 # 使用 GPT-5.4 模型
reasoning_effort: extra-high # 最高推理档位
role: runtime_supervisor # 运行时监督者角色
# 监视目标:Hermes 工作流状态目录
watch:
path: ~/.hermes/workflow_state # Hermes 状态文件目录
pattern: "*.json" # 监视 JSON 状态文件
poll_interval: 2 # 轮询间隔(秒)
# 监控策略
strategy:
check_interval: 5 # 状态检查间隔(秒)
breakpoint_detection: true # 启用断点检测
auto_fix: true # 自动修复
max_fix_attempts: 10 # 每个断点最大修复尝试
# 修复输出:写入 Hermes 可读取的指令文件
fix_output:
path: ~/.hermes/workflow_state/fixes/
format: json
# 可靠性判据
reliability:
target_consecutive_success: 3
report_path: ~/.hermes/workflow_state/reliability_report.json
Step 4:编写 SOUL.md --- 监督者 vs 执行者

SOUL.md 是 Hermes 的 agent 身份定义文件。监督者 agent 和执行者 agent 需要不同的 SOUL.md 来定义各自的角色和行为边界。

yaml 复制代码
# ~/.hermes/souls/supervisor.md --- 监督者 Agent SOUL 重建
---
name: Codex Supervisor
role: runtime_monitor
model: gpt-5.4
reasoning: extra-high
---
# 你是谁
你是一个运行时监督者。你不执行任何业务任务。
你的唯一职责是监视 Hermes agent-to-agent 工作流的执行状态,
在发现断点时推理根因,生成修复方案,并应用到工作流中。
# 你做什么
1. **Watch(监视)**:持续读取 ~/.hermes/workflow_state/ 下的
状态文件,理解每个子 agent 的当前执行进度。
2. **Catch(捕获)**:推理每一步的输出是否合理。
如果某个步骤的状态为 "error"、"timeout" 或输出语义不正确,
标记为断点。
3. **Fix(修复)**:对每个断点,推理根因(prompt 不清晰?
参数错误?工具调用失败?上下文丢失?),
生成修复方案并写入 fix 指令文件。
4. **Loop(循环)**:修复后让 Hermes 重试该步骤。
重复直到连续 3 次完整运行无断点。
# 你不做什么
- 你不直接调用 Hermes 的工具(terminal、file、web 等)
- 你不修改 Hermes 的核心配置(config.yaml)
- 你不在未检测到断点时干预工作流
- 你不自行宣布"可靠"------必须有连续成功的数据支撑
# 可靠性判据
"reliably" = 连续 3 次完整工作流运行,
每一步均返回 success 状态,输出通过语义校验。
yaml 复制代码
# ~/.hermes/souls/coder.md --- 执行者 Agent SOUL 重建
---
name: Coder Sub-Agent
role: worker
model: gpt-5.4
reasoning: high
---
# 你是谁
你是 Hermes 工作流中的编码执行者。
你接收来自主 agent 的 delegate_task 委派,
根据研究阶段的输出编写实现代码。
# 你做什么
1. 接收研究阶段的输出(技术方案、需求分析)
2. 编写实现代码到指定文件
3. 返回代码文件路径和实现摘要
# 你的工具
- terminal:执行编译、测试命令
- file_write:写入代码文件
- file_read:读取研究阶段的输出文件
# 注意事项
- 如果研究输出不完整或有歧义,返回 error 状态
并在输出中说明缺什么信息(供监督者修复)
- 如果编译失败,返回 error 状态并附带编译错误日志
Step 5:启动 Hermes 工作流

在 Hermes 中启动工作流,同时确保状态文件输出到 Codex 监视的目录。

bash 复制代码
# 启动 Hermes agent-to-agent 工作流
# Hermes 会按照 workflow YAML 定义依次委派任务给子 agent
你: "运行 feature_development_pipeline 工作流。
用户需求:实现一个 Markdown 转 HTML 的命令行工具,
支持自定义 CSS 和代码高亮。"
# Hermes 开始执行:
# Step 1: 委派 researcher 子 agent → 搜索 Markdown 解析库
# Step 2: 委派 coder 子 agent → 根据研究结果编写代码
# Step 3: 委派 reviewer 子 agent → 审查代码
# 同时,状态文件被写入 ~/.hermes/workflow_state/
# Codex 正在监视这个目录...
Step 6:启动 Codex 监督者

在另一个终端(或另一个 tmux 窗口)启动 Codex,指向 Hermes 的状态目录。

css 复制代码
# 启动 Codex 监督者(在另一个终端)
codex --model gpt-5.4 \
--reasoning extra-high \
--config ~/.codex/monitor_config.yaml \
monitor --watch ~/.hermes/workflow_state/
Step 7:观察 Codex 捕获断点

当工作流中某个步骤失败时,Codex 会检测到状态文件中的 error 状态,推理断点位置和根因。

csharp 复制代码
# Codex 监督者输出示例(控制台日志) 重建
[2026-04-17 14:32:01] WATCH 读取状态文件: step_2_code.json
[2026-04-17 14:32:03] CATCH 检测到断点: step_2_code
→ 状态: error
→ 错误信息: "research_result 中缺少 Markdown 解析库的具体 API 用法"
→ 推理: coder 子 agent 无法执行,因为 researcher 的输出
未包含库的 API 文档链接和调用示例
→ 根因: step_1_research 的 prompt 不够明确,
未要求输出 API 用法示例
[2026-04-17 14:32:08] FIX 生成修复方案:
→ 修改 step_1_research 的 task prompt:
"调研用户需求,搜索相关技术方案,
并输出每个候选库的 API 用法和代码示例"
→ 写入修复指令: ~/.hermes/workflow_state/fixes/fix_001.json
[2026-04-17 14:32:10] RETRY 通知 Hermes 重试 step_1_research
Step 8:观察实时修复过程

Hermes 读取修复指令后,使用修改后的 prompt 重新执行失败的步骤。Codex 继续监视,直到达到可靠性判据。

csharp 复制代码
# 修复循环示例 重建
# 第 1 轮:step_2 失败(缺少 API 用法)
# → Codex 修复 step_1 prompt → 重试 step_1 → 重试 step_2
# 第 2 轮:step_2 失败(代码编译错误,库版本不匹配)
# → Codex 在 fix 中指定正确的库版本 → 重试 step_2
# 第 3 轮:step_3 失败(reviewer 发现安全问题:未转义用户输入)
# → Codex 在 fix 中要求 coder 添加输入转义 → 重试 step_2 → 重试 step_3
# 第 4-6 轮:全部步骤成功
# → 连续 3 次完整运行无断点
[2026-04-17 15:08:42] RELIABLE 工作流已达到可靠性判据
→ 连续成功运行次数: 3/3
→ 总修复次数: 3
→ 总耗时: 36 分 41 秒
→ 报告已写入: reliability_report.json

Hermes 命令完整参考

以下表格列出本案例涉及的所有 Hermes delegate/sub-agent 命令和 Codex CLI 命令。

命令 类别 说明 来源
delegate_task Hermes 工具 主 agent 将子任务委派给指定 profile 的子 agent Hermes 原生
spawn_sub_agent Hermes 工具 动态生成子 agent 实例,分配独立上下文和工具集 Hermes 原生
list_sub_agents Hermes 工具 列出当前活跃的子 agent 及其状态 Hermes 原生
kill_sub_agent Hermes 工具 终止指定子 agent(用于修复后重置) Hermes 原生
get_workflow_state Hermes 工具 读取当前工作流的执行状态(步骤、进度、错误) Hermes 原生
retry_step Hermes 工具 使用修改后的参数重试指定工作流步骤 Hermes 原生
write_state_file Hermes 内部 将工作流状态写入 JSON 文件(供 Codex 监视) Hermes 原生
read_fix_instructions Hermes 内部 读取 Codex 写入的修复指令文件 Hermes 原生
codex --model gpt-5.4 Codex CLI 指定 Codex 使用的模型为 GPT-5.4 OpenAI Codex
--reasoning extra-high Codex CLI 设定推理档位为 extra-high(最高强度) OpenAI Codex
codex monitor --watch Codex CLI 启动监视模式,持续监控指定目录的文件变化 OpenAI Codex
codex analyze Codex CLI 分析当前状态文件,推理是否存在断点 OpenAI Codex
codex fix --write Codex CLI 生成修复方案并写入修复指令文件 OpenAI Codex
codex report --reliability Codex CLI 生成可靠性评估报告 OpenAI Codex

工作流状态文件示例

这是 Codex 读取以检测断点的文件。Hermes 在执行工作流时持续更新它。

json 复制代码
// ~/.hermes/workflow_state/feature_development_pipeline.json 重建
{
"workflow_id": "feature_development_pipeline",
"run_id": "run_20260417_143200",
"status": "error", // 整体状态:running/success/error
"started_at": "2026-04-17T14:32:00Z",
"current_step": "step_2_code", // 当前执行步骤
"consecutive_success": 0, // 连续成功次数(可靠性判据)
"steps": [
{
"id": "step_1_research",
"agent": "researcher",
"status": "success", // 此步骤成功
"output_key": "research_result",
"output_summary": "找到 3 个候选 Markdown 解析库",
"retry_count": 0,
"duration_sec": 12.5
},
{
"id": "step_2_code",
"agent": "coder",
"status": "error", // 此步骤失败 ← Codex 捕获的断点
"error_message": "research_result 中缺少 API 用法",
"retry_count": 0,
"duration_sec": 8.3,
"stack_trace": "coder_agent: cannot determine API usage from research output"
},
{
"id": "step_3_review",
"agent": "reviewer",
"status": "pending", // 尚未执行
"retry_count": 0
}
],
"fixes_applied": [], // 已应用的修复列表
"last_updated": "2026-04-17T14:32:11Z"
}

Codex 修复指令文件示例

这是 Codex 写入、Hermes 读取以应用修复的文件。

json 复制代码
// ~/.hermes/workflow_state/fixes/fix_001.json 重建
{
"fix_id": "fix_001",
"target_step": "step_1_research", // 修复目标是 step_1
"reasoning": "step_2 失败因为 step_1 输出缺少 API 用法",
"fix_type": "prompt_modification", // 修复类型:修改 prompt
"new_task_prompt": "调研用户需求,搜索相关技术方案,
并输出每个候选库的 API 用法和代码示例",
"additional_context": "后续步骤需要具体的 API 调用代码",
"action": "retry_from_step", // 从 step_1 开始重试
"created_at": "2026-04-17T14:32:08Z"
}

PART 03

源码深度拆解 + 部署 + 复刻陷阱

核心代码重建 重建

由于本案例没有公开源码(单条推文,GitHub 无公开仓库),以下代码全部基于 Hermes 官方文档描述的 agent-to-agent 委派能力和 Codex CLI 的已知监控特性重建。代码采用 Python 伪代码风格,模拟 Hermes 内部的委派逻辑和 Codex 的监控逻辑,每行附有中文注释。

1. Agent-to-Agent 委派 --- delegate_task 实现
python 复制代码
# delegate_task.py --- Hermes agent-to-agent 委派实现 重建
# 这是 Hermes 工作流管线的核心:主 agent 将子任务委派给子 agent
import json
import uuid
from pathlib import Path
from datetime import datetime
class DelegateTask:
"""Hermes delegate_task 工具 --- 将子任务委派给指定 profile 的子 agent"""
def __init__(self, config):
self.sub_agents = config["sub_agents"] # 子 agent profile 字典
self.state_dir = Path(config["workflow"]["state_dir"])
self.state_dir.mkdir(parents=True, exist_ok=True)
self.active_agents = {} # 活跃子 agent 实例
def delegate(self, task, agent_profile, context=None):
"""委派任务给子 agent
task: 任务描述(prompt)
agent_profile: 子 agent profile 名称(如 'researcher')
context: 前置步骤的输出(依赖注入)
"""
profile = self.sub_agents[agent_profile] # 获取子 agent 配置
agent_id = str(uuid.uuid4())[:8]
# 生成子 agent 实例(独立上下文窗口)
sub_agent = self._spawn_sub_agent(agent_id, profile)
self.active_agents[agent_id] = sub_agent
# 写入工作流状态:该步骤已开始
self._write_state(agent_id, agent_profile, "running")
try:
# 执行子任务(子 agent 在隔离上下文中运行)
result = sub_agent.execute(task, context)
# 写入工作流状态:该步骤成功
self._write_state(agent_id, agent_profile, "success", result)
return result
except Exception as e:
# 写入工作流状态:该步骤失败(断点!)
# Codex 监督者会读取这个 error 状态
self._write_state(agent_id, agent_profile, "error",
error=str(e))
raise # 重新抛出,让工作流引擎捕获
finally:
# 清理子 agent 实例(释放上下文资源)
del self.active_agents[agent_id]
def _spawn_sub_agent(self, agent_id, profile):
"""生成子 agent 实例 --- 独立上下文、独立工具集"""
return SubAgent(
agent_id=agent_id,
model=profile["model"], # 子 agent 模型
soul_file=profile["soul_file"], # 子 agent 身份定义
tools=profile["tools"], # 子 agent 可用工具集
max_tokens=profile["max_tokens"] # 上下文窗口限制
)
def _write_state(self, agent_id, profile, status, result=None, error=None):
"""写入工作流状态文件 --- Codex 监督者读取此文件"""
state = {
"agent_id": agent_id,
"profile": profile,
"status": status, # running/success/error
"timestamp": datetime.now().isoformat(),
"result_summary": str(result)[:200] if result else None,
"error_message": error # Codex 据此推理断点
}
path = self.state_dir / f"{agent_id}.json"
path.write_text(json.dumps(state, indent=2))
2. 工作流状态追踪器 --- Codex 监视的对象
python 复制代码
# workflow_tracker.py --- 工作流状态追踪器 重建
# 持续追踪工作流每个步骤的状态,写入状态文件供 Codex 监视
import json
from pathlib import Path
from datetime import datetime
class WorkflowTracker:
"""追踪 agent-to-agent 工作流的完整执行状态"""
def __init__(self, workflow_def, state_dir):
self.steps = workflow_def["steps"] # 工作流步骤定义
self.state_dir = Path(state_dir)
self.state_dir.mkdir(parents=True, exist_ok=True)
self.consecutive_success = 0 # 连续成功次数
self.target_success = workflow_def["reliability"]["target_consecutive_success"]
self.run_id = datetime.now().strftime("run_%Y%m%d_%H%M%S")
def update_step(self, step_id, status, output=None, error=None):
"""更新单个步骤的状态,写入状态文件"""
step = next(s for s in self.steps if s["id"] == step_id)
step["status"] = status
step["timestamp"] = datetime.now().isoformat()
if status == "error":
step["error_message"] = error # Codex 捕获的断点信息
self.consecutive_success = 0 # 重置连续成功计数
elif status == "success":
step["output_summary"] = str(output)[:200]
step["retry_count"] = step.get("retry_count", 0)
# 写入完整工作流状态文件(Codex 监视这个文件)
self._persist_state()
def check_reliability(self):
"""检查是否达到可靠性判据
"until it worked reliably" 的具体实现
"""
all_success = all(
s.get("status") == "success" for s in self.steps
)
if all_success:
self.consecutive_success += 1
if self.consecutive_success >= self.target_success:
return "reliable" # 达到可靠性判据!
return "success_not_yet_reliable" # 成功但未达连续次数
return "in_progress" # 仍在执行中
def _persist_state(self):
"""将完整工作流状态写入 JSON 文件"""
state = {
"workflow_id": self.run_id,
"consecutive_success": self.consecutive_success,
"target_success": self.target_success,
"steps": self.steps,
"last_updated": datetime.now().isoformat()
}
path = self.state_dir / "workflow_state.json"
path.write_text(json.dumps(state, indent=2, ensure_ascii=False))
3. 断点检测器 --- Codex 如何识别工作流在哪里断了
python 复制代码
# breakpoint_detector.py --- Codex 断点检测逻辑 重建
# 模拟 Codex (GPT-5.4 extra-high) 如何推理断点位置和根因
import json
from pathlib import Path
class BreakpointDetector:
"""Codex 断点检测器 --- watch → catch 的核心逻辑"""
def __init__(self, state_dir):
self.state_dir = Path(state_dir)
self.last_state = None # 上次读取的状态(增量检测)
def watch(self):
"""Watch 步骤:读取工作流状态文件"""
path = self.state_dir / "workflow_state.json"
if not path.exists():
return None
state = json.loads(path.read_text())
return state
def catch(self, state):
"""Catch 步骤:检测断点
返回断点信息(步骤 ID + 错误 + 推理根因)或 None
"""
if not state:
return None
# 遍历所有步骤,查找 error 状态
for step in state.get("steps", []):
if step.get("status") == "error":
# 发现断点!使用 GPT-5.4 extra-high 推理根因
root_cause = self._reason_root_cause(step, state)
return {
"breakpoint_step": step["id"],
"error_message": step.get("error_message", ""),
"root_cause": root_cause,
"step_output": step.get("output_summary", "")
}
# 检查语义正确性:即使状态是 success,输出可能语义错误
for step in state.get("steps", []):
if step.get("status") == "success":
if not self._semantic_check(step):
return {
"breakpoint_step": step["id"],
"error_message": "语义校验失败:输出不合理",
"root_cause": "输出格式正确但内容不符合预期",
"step_output": step.get("output_summary", "")
}
return None # 无断点
def _reason_root_cause(self, step, full_state):
"""使用 GPT-5.4 extra-high 推理断点根因
这是 Codex 监督者的核心推理能力
"""
# 在实际实现中,这里会调用 GPT-5.4 API
# 传入:错误信息 + 前置步骤的输出 + 工作流定义
# 返回:根因分析和修复建议
error_msg = step.get("error_message", "")
step_id = step["id"]
# 查找前置步骤的输出(依赖链分析)
dependencies = self._find_dependencies(step_id, full_state)
dep_outputs = [d.get("output_summary", "") for d in dependencies]
# GPT-5.4 extra-high 推理(模拟)
reasoning = codex_reason(
model="gpt-5.4",
effort="extra-high",
prompt=f"""
步骤 {step_id} 失败,错误信息: {error_msg}
前置步骤输出: {dep_outputs}
分析根因,并给出修复建议。
"""
)
return reasoning
def _semantic_check(self, step):
"""语义校验:即使没有 error,输出是否合理?"""
# GPT-5.4 推理:这个输出是否满足后续步骤的输入要求?
return True # 简化实现
def _find_dependencies(self, step_id, state):
"""查找步骤的依赖链(用于根因分析)"""
steps = state.get("steps", [])
step = next(s for s in steps if s["id"] == step_id)
deps = step.get("depends_on", [])
return [s for s in steps if s["id"] in deps]
4. 实时修复器 --- Codex 如何修补断点并重试
python 复制代码
# live_fixer.py --- Codex 实时修复逻辑 重建
# 模拟 Codex (GPT-5.4 extra-high) 如何生成修复方案并应用
import json
from pathlib import Path
from datetime import datetime
class LiveFixer:
"""Codex 实时修复器 --- fix 步骤的核心逻辑"""
def __init__(self, fix_dir, state_dir):
self.fix_dir = Path(fix_dir)
self.fix_dir.mkdir(parents=True, exist_ok=True)
self.state_dir = Path(state_dir)
self.fix_count = 0 # 总修复次数
def fix(self, breakpoint):
"""Fix 步骤:根据断点信息生成并应用修复
breakpoint: BreakpointDetector.catch() 的返回值
"""
self.fix_count += 1
# GPT-5.4 extra-high 推理修复方案
fix_plan = self._generate_fix_plan(breakpoint)
# 写入修复指令文件(Hermes 读取此文件应用修复)
fix_instruction = {
"fix_id": f"fix_{self.fix_count:03d}",
"target_step": breakpoint["breakpoint_step"],
"reasoning": breakpoint["root_cause"],
"fix_type": fix_plan["type"],
"new_task_prompt": fix_plan.get("new_prompt"),
"additional_context": fix_plan.get("extra_context"),
"action": fix_plan["action"], # retry_from_step / retry_step / skip
"created_at": datetime.now().isoformat()
}
fix_path = self.fix_dir / f"fix_{self.fix_count:03d}.json"
fix_path.write_text(json.dumps(fix_instruction, indent=2))
# 通知 Hermes 应用修复(通过状态文件标志位)
self._notify_hermes(fix_instruction)
return fix_instruction
def _generate_fix_plan(self, breakpoint):
"""GPT-5.4 extra-high 生成修复方案
根据根因分析,决定修复类型:
- prompt_modification: 修改任务 prompt(最常见)
- parameter_adjustment: 调整子 agent 参数
- context_injection: 注入额外上下文
- tool_swap: 切换子 agent 使用的工具
"""
root_cause = breakpoint["root_cause"]
# 模拟 GPT-5.4 extra-high 推理
if "缺少" in root_cause or "incomplete" in root_cause.lower():
return {
"type": "prompt_modification",
"new_prompt": root_cause.get("suggested_prompt"),
"action": "retry_from_step"
}
elif "超时" in root_cause or "timeout" in root_cause.lower():
return {
"type": "parameter_adjustment",
"action": "retry_step"
}
else:
return {
"type": "context_injection",
"extra_context": root_cause,
"action": "retry_step"
}
def _notify_hermes(self, fix_instruction):
"""通知 Hermes 有修复指令待应用"""
# 通过写入标志文件实现松耦合通知
flag_path = self.state_dir / "fix_pending.flag"
flag_path.write_text(fix_instruction["fix_id"])
5. 可靠性检查器 --- "until it worked reliably" 的判定
python 复制代码
# reliability_checker.py --- 可靠性判定逻辑 重建
# "until it worked reliably" 的具体实现:连续 N 次成功才宣布可靠
import json
from pathlib import Path
from datetime import datetime
class ReliabilityChecker:
"""可靠性检查器 --- 决定何时停止修复循环"""
def __init__(self, target_success=3, max_total_runs=20):
self.target = target_success # 目标连续成功次数
self.max_runs = max_total_runs # 最大总运行次数(防无限循环)
self.history = [] # 每次运行的完整结果
def record_run(self, run_result):
"""记录一次完整工作流运行的结果"""
self.history.append({
"run_id": len(self.history) + 1,
"all_success": run_result["all_success"],
"steps": run_result["steps"],
"timestamp": datetime.now().isoformat()
})
def check(self):
"""检查是否达到可靠性判据
返回: 'reliable' / 'continue' / 'exhausted'
"""
# 检查最大运行次数(防止无限修复循环)
if len(self.history) >= self.max_runs:
return "exhausted" # 超过最大运行次数,放弃
# 计算最近的连续成功次数
consecutive = 0
for run in reversed(self.history):
if run["all_success"]:
consecutive += 1
else:
break # 遇到失败,中断计数
if consecutive >= self.target:
return "reliable" # 达到可靠性判据!
return "continue" # 继续修复循环
def generate_report(self):
"""生成可靠性报告"""
total_runs = len(self.history)
success_runs = sum(1 for r in self.history if r["all_success"])
return {
"total_runs": total_runs,
"successful_runs": success_runs,
"success_rate": round(success_runs / total_runs * 100, 1),
"target_consecutive": self.target,
"achieved_consecutive": self._current_streak(),
"verdict": self.check(),
"generated_at": datetime.now().isoformat()
}
def _current_streak(self):
"""当前连续成功次数"""
streak = 0
for run in reversed(self.history):
if run["all_success"]:
streak += 1
else:
break
return streak
6. Hermes 子 Agent 生成器 --- 并行工作流隔离
python 复制代码
# sub_agent_spawner.py --- 子 Agent 生成器 重建
# 每个子 agent 拥有独立上下文窗口和工具集,实现工作流隔离
class SubAgentSpawner:
"""Hermes 子 Agent 生成器 --- 为每个委派任务创建隔离的执行环境"""
def __init__(self, profiles, memory):
self.profiles = profiles # 子 agent profile 配置
self.memory = memory # Hermes 跨会话记忆
self.spawned = {} # 已生成的子 agent 实例
def spawn(self, profile_name, task, context=None):
"""生成子 agent 实例
profile_name: 子 agent profile(如 'researcher', 'coder')
task: 委派的任务描述
context: 从前置步骤传递的上下文
"""
profile = self.profiles[profile_name]
# 加载 SOUL.md(子 agent 身份定义)
soul = self._load_soul(profile["soul_file"])
# 创建隔离的上下文窗口
context_window = self._create_isolated_context(soul, task, context)
# 初始化子 agent 工具集(仅赋予 profile 中定义的工具)
tools = self._init_tools(profile["tools"])
# 创建子 agent 实例
agent = SubAgent(
model=profile["model"],
context=context_window,
tools=tools,
max_tokens=profile["max_tokens"],
memory=self.memory # 共享记忆层(可读写)
)
agent_id = id(agent)
self.spawned[agent_id] = agent
return agent
def _load_soul(self, soul_file):
"""加载 SOUL.md 文件 --- 子 agent 的身份和行为准则"""
from pathlib import Path
return Path(soul_file).read_text()
def _create_isolated_context(self, soul, task, context):
"""创建隔离上下文 --- 子 agent 看不到主 agent 的完整对话历史"""
return {
"soul": soul, # 身份定义
"task": task, # 当前任务
"context": context or {}, # 前置步骤输出
"history": [] # 独立对话历史
}
def _init_tools(self, tool_names):
"""初始化工具集 --- 仅赋予 profile 中定义的工具"""
# 这确保 researcher 不能写文件,coder 不能做 web 搜索
# 实现"最小权限"原则
tool_registry = {
"terminal": TerminalTool(),
"file_read": FileReadTool(),
"file_write": FileWriteTool(),
"web_search": WebSearchTool(),
"browser": BrowserTool(),
}
return {name: tool_registry[name] for name in tool_names if name in tool_registry}
def cleanup(self, agent_id):
"""清理子 agent --- 释放上下文资源"""
if agent_id in self.spawned:
del self.spawned[agent_id]

部署考量:同时运行两个 AI 系统

本案例的部署架构与之前的单系统案例不同------它需要同时运行两个独立的 AI 系统(Hermes 和 Codex),并且让它们通过共享文件系统通信。这带来几个独特的部署考量。

部署维度 Hermes(执行者) Codex(监督者) 协同要求
运行位置 本地或 VPS 同一机器(共享文件系统) 必须共享 ~/.hermes/workflow_state/ 目录
资源消耗 LLM API 调用(子 agent 执行任务) GPT-5.4 extra-high API 调用(推理开销显著更高) 两个系统同时消耗 API 配额,需确保不超限
进程管理 tmux/screen 会话 或 systemd 服务 另一个 tmux/screen 会话 或 systemd 服务 两者独立启停,但 Codex 需在 Hermes 之后启动
文件系统 写入状态文件 + 读取修复指令 读取状态文件 + 写入修复指令 读写权限对齐,避免竞态条件
网络 需要访问 LLM API + 工具(web/SSH) 需要访问 GPT-5.4 API 两者都需要稳定的 API 连接
日志 Hermes 工作流日志 Codex 监控日志(断点 + 修复记录) 日志分离,便于事后审计

部署陷阱:API 成本叠加

Codex 的 extra-high 推理档位是最昂贵的推理模式 。每次断点检测和修复生成都需要一次深度推理调用。如果工作流频繁失败(例如 Day 10 的前几次运行),修复循环可能触发数十次 extra-high 推理调用,API 成本会快速叠加。建议在开发阶段先用 high 档位测试监控逻辑,确认基本流程跑通后再切换到 extra-high 进行最终调试。

复刻检查清单

如果你想复现 @gkisokay 的"Codex 监控 Hermes"体验,按以下清单逐项准备:

  • 安装并初始化 Hermes Agent,确认 delegate_task 工具可用
  • 安装 OpenAI Codex CLI,确认可访问 GPT-5.4 模型
  • 在 Hermes config.yaml 中启用多 agent 模式和子 agent profile
  • 为每个子 agent 角色(researcher/coder/reviewer)编写 SOUL.md
  • 定义 agent-to-agent 工作流管线(YAML 格式,含步骤依赖和可靠性判据)
  • 配置 Hermes 工作流状态文件输出目录
  • 编写 Codex 监督者配置(monitor_config.yaml)
  • 设定 GPT-5.4 模型和 extra-high 推理档位
  • 将 Codex 监视路径指向 Hermes 状态文件目录
  • 在两个终端分别启动 Hermes 工作流和 Codex 监督者
  • 触发一次工作流运行,观察 Codex 控制台输出
  • 确认 Codex 能检测到 error 状态并推理根因
  • 确认 Codex 修复指令文件被 Hermes 正确读取和应用
  • 确认修复后 Hermes 自动重试失败步骤
  • 观察修复循环直到达到连续成功判据
  • 检查 reliability_report.json 确认最终可靠性评估

复刻陷阱总结

陷阱 1:无公开仓库 --- 一切皆重建

@gkisokay 的 GitHub 账号存在但无任何公开仓库。本案例的全部技术细节------架构图、配置文件、代码实现------均基于推文描述和 Hermes/Codex 文档推导而来。原作者的实际实现可能截然不同。重建内容仅供架构参考,不可视为原作者的真实代码。任何基于本文重建内容的复刻,都应明确标注其推导性质。

陷阱 2:"extra-high" 推理 = 高 token 成本

extra-high 是 Codex CLI 提供的最高推理档位,每次推理调用的 token 消耗可能是标准档位的 3-5 倍。在一个需要多次 watch-catch-fix 循环的场景中,这意味着显著的 API 开销。如果工作流复杂度高、断点频繁,一个调试会话可能消耗数十美元的 API 费用。建议设置费用告警,并在开发阶段使用较低档位验证基本逻辑。

陷阱 3:Codex 和 Hermes 可能产生冲突性解读

Codex(监督者)和 Hermes(执行者)是两个独立的 AI 系统,使用各自的 LLM 推理。Codex 认为的"正确修复"可能不是 Hermes 子 agent 能理解的格式。例如,Codex 生成的修复 prompt 可能包含 Hermes 子 agent 的 SOUL.md 中未定义的术语,导致子 agent 在重试时仍然失败。建议保持修复指令的格式简洁、术语与 SOUL.md 一致。

陷阱 4:实时修复可能引入新 Bug

Codex 的修复方案并非总是正确。一个修复 step_2 的改动可能意外导致 step_3 失败------原本只有一处断点,修复后变成了两处。更糟糕的是,修复可能引入一个"看起来通过但实际错误"的结果,绕过可靠性检查。建议每次修复后不仅重试失败步骤,而是从失败步骤开始重新运行整个工作流,确保级联效应被捕获。

陷阱 5:"reliably" 是主观词 --- 需要可量化判据

@gkisokay 说"until it worked reliably",但没有定义"reliably"的具体标准。是连续 3 次成功?5 次?10 次?是部分步骤成功还是全部步骤成功?是输出通过语法检查还是通过语义校验?如果判据太宽松,可能过早宣布可靠;太严格,则可能永远无法达到。建议在 workflow YAML 中明确定义 target_consecutive_success 和校验类型。

陷阱 6:Agent-to-Agent 工作流的级联失败

在多层委派的工作流中,一个步骤的失败可能不是它自身的问题,而是上游步骤的"隐性错误"------输出格式正确但内容有误。Codex 需要回溯整个依赖链来找到真正的根因,而不仅仅是报错的那个步骤。如果 Codex 只修复报错步骤而不追查上游,修复方案可能无效,导致无限重试循环。建议断点检测器始终分析完整依赖链。

陷阱 7:Day 10 意味着 9 天未知上下文

推文标题中的"Day 10"表明这是 "Building AGI for my Hermes Agent" 系列的第 10 天。前 9 天的工作完全未知------可能包括自定义工具开发、记忆架构设计、SOUL.md 迭代、工作流定义调试等。直接从 Day 10 开始复刻可能缺少关键前提基础设施。建议从 Day 1 的基础能力开始搭建,而非直接跳到运行时监控阶段。

扩展方向

@gkisokay 的案例展示了"Codex 监控 Hermes"的最基础形态。基于同样的"AI 监控 AI"范式,可以扩展出更强大的自动化场景:

01 Agent CI/CD 管道

将 Codex 监控从开发期调试扩展为持续集成管道。每次工作流定义变更后,Codex 自动运行可靠性测试,只有通过才允许部署。Agent 世界的 CI/CD。

02 多模型监控舰队

不止一个 Codex 监督者。部署多个不同模型的监督者(GPT-5.4 / Claude / Gemini),各自从不同角度审查工作流,投票决定修复方案。降低单一模型偏见风险。

03 自愈 Agent 系统

将 Codex 的修复能力内化到 Hermes 自身。Hermes 在运行时自我监控、自我修复,无需外部 Codex。实现真正的"自愈"(self-healing)agent 系统。

04 AGI 构建 AGI

@gkisokay 的系列名为"Building AGI"。终极扩展是:监督者 AI 不仅监控执行者 AI 的工作流,还能自主设计新的工作流、创建新的子 agent、迭代整个系统架构。AGI 构建 AGI。

05 分层监督架构

不止两层(Codex 监督 + Hermes 执行)。构建三层甚至更多层:Codex 监督 Hermes,另一个更强的 AI 监督 Codex 的监督质量。形成递归监督链。

06 修复知识库

将 Codex 每次成功修复的断点-根因-修复方案三元组存入知识库。随着积累,Codex 可以先查知识库找到已知模式,直接复用修复方案,减少推理调用次数和成本。

结语:从工具调用到 AI 监工

@gkisokay 的 Day 10 案例,标志着 Hermes 生态中一个新范式的出现:AI 不再只是执行者,也是监督者。当一个 GPT-5.4 级别的 AI 以 extra-high 推理档位盯着另一个 AI 的工作流,在断点处实时捕获、推理、修复------我们看到的不是"更好的调试工具",而是"AI 监工"这个全新角色的诞生。在传统软件工程中,代码审查、运行时监控、故障修复是三个不同的角色,由不同的人或系统承担。而 @gkisokay 把这三个角色合并到了一个 AI 身上:Codex 既是审查者(watch)、又是监控器(catch)、还是修复者(fix)。"OpenClaw does the junior work, Hermes is the senior"------而在 senior 之上,还有一个 GPT-5.4 的"总监"。当你拥有了"AI 监工"能力时,你与 agent 系统的交互方式就从根本上改变了:你不再需要盯着它干活,因为有另一个 AI 帮你盯着。

溯源引用

  1. Nous Research, Hermes Agent 官方文档。Agent-to-agent 委派能力(delegate_task 工具)、子 agent 生成与隔离、工作流管线、跨会话记忆、7 种终端后端、技能系统。 hermes-agent.nousresearch.com/docs/
  2. @gkisokay, X (Twitter) 原始推文。"Day 10 of Building AGI for my Hermes Agent: Codex saved the day as a runtime monitor for my agent-to-agent workflows. I used Codex with GPT-5.4 on extra-high to watch the workflow run, catch where it broke, and fix it live until it worked reliably." 2026-04-17. x.com/gkisokay/st...
  3. Nous Research, Hermes Agent 官方用户故事页面。@gkisokay 的故事被收录,标题为 "Codex watches my Hermes agent-to-agent workflows live",分类为 X / Twitter · Dev Workflow。 hermes-agent.nousresearch.com/docs/user-s...
  4. @gkisokay, GitHub 账号。账号存在但无任何公开仓库。Bio: "Building tools for myself, that you will like as well." github.com/Gkisokay
  5. OpenAI Codex CLI。命令行 AI 编码工具,支持 GPT-5.4 模型和多档位推理强度(low / medium / high / extra-high)。本案例中 Codex 作为运行时监督者的工具基础,具备文件监视、上下文读取、代码生成和命令执行能力。 openai.com/codex/
  6. @gkisokay, CSDN 文章补充引用。"OpenClaw does the junior work, Hermes is the senior." 该引用揭示了作者的多层 agent 分工哲学:OpenClaw 处理初级工作,Hermes 处理高级工作,Codex 监控全局。 参考:Hermes 官方用户故事页面
  7. OpenAI GPT-5.4 模型。本案例中 Codex 监督者使用的 LLM 模型,以 extra-high 推理档位运行。extra-high 是最高推理强度,提供最深度的思维链推理,适用于复杂断点分析和修复方案生成场景。 openai.com/
  8. Hermes Agent delegate_task 工具文档。主 agent 将子任务委派给子 agent 的原生能力,支持子 agent profile 配置、独立上下文窗口、工具集隔离。本案例中 agent-to-agent 工作流的技术基础。 hermes-agent.nousresearch.com/docs/ (dele...

Hermes Agent 深度拆解连载 · 第 14 篇 · @gkisokay 的 Codex 运行时监控 --- AI 监控 AI 的 agent-to-agent 工作流

溯源驱动 · 源码佐证 · 1:1 可复刻 · 禁止虚构


延伸阅读与交流

本文涉及的Hermes Agent自进化智能体技术体系,目前已有系统化的深度学习资源可供参考。中国通信工业协会通信和信息技术创新人才培养工程项目办公室将于近期组织相关技术专题分享,围绕本文讨论的AI原生架构、智能体工作流、自进化数据层等方向展开系统讲解。

专题信息

  • 主题:AI原生Hermes自进化智能体系统
  • 时间:2026年8月22-23日
  • 形式:线上直播
  • 内容方向:AI原生架构 · Hermes智能体拆解 · 全栈扩展 · 智能自动化 · 产品级实战 · Context Engine · 自进化数据层

分享嘉宾

王老师(Gavin),Agentic AI企业联合创始人兼CTO,十余年硅谷AI系统工程经验。长期深耕NLP、强化学习、可控AI与智能体系统架构,提出"语言即控制(Language as Control)"原创范式,在RLHF、PPO、DPO、GRPO等方向有系统化工程实践,推动智能体技术在社交媒体、医疗、金融、法律、教育等专业场景落地。联系邮箱:hiheartfirst@gmail.com

技术交流

027 | 真实查询 EXPLAIN 实战:从误规划到对症修法

导读:前三篇把 EXPLAIN 的变体、节点的数字、扫描和连接的形态、BUFFERS 的缓存故事都讲清了。本篇是第 8 章的收官:把这套诊断套路扔进 cinetrack 沙箱里的真实查询------三条被规划器误判的查询,每一条都从"这条为啥慢"走到"它已经修好了",全程只用计划做诊断。最后我们盘点读这篇最容易犯的六个错,以及把整个第 8 章凝练成五句话。


cinetrack 三条实战

cinetrack 沙箱里的三条查询,每一条都是一个误规划,全程靠计划从"这慢"走到"修好"。第 8 章的沙箱有 50000 部电影、500000 条评分,这个体量足够让坏计划咬人、让好计划显出功底。

小贴士

跟跑示例:启动第 8 章沙箱 cd chapter-08 && docker compose up -d,然后用 psql -h localhost -U cinetrack -d cinetrack -f init.sql 初始化、psql -h localhost -U cinetrack -d cinetrack -f seed.sql 灌数据。

每条查询都用 EXPLAIN (ANALYZE, BUFFERS) 跑两次。下面的数字是典型的第二次热缓存运行。

一个看起来还好的搜索

一位评论者在浏览高评分近年的电影:

sql 复制代码
SELECT id, title, release_year
FROM movies
WHERE release_year >= 2020
AND title LIKE 'The %'
ORDER BY release_year DESC
LIMIT 20;

原始计划(什么都没动的情况下):

sql 复制代码
 Limit  (cost=0.42..2891.40 rows=20 width=42) (actual time=12.301..184.221 rows=20 loops=1)
   Buffers: shared hit=18120 read=204
   ->  Index Scan Backward using idx_movies_release_year on movies
         (cost=0.42..198440.50 rows=1372 width=42) (actual time=12.299..184.198 rows=20 loops=1)
         Index Cond: (release_year >= 2020)
         Filter: (title ~~ 'The %'::text)
         Rows Removed by Filter: 18102

LIMIT 20 让运行时间看起来还合理,但 Rows Removed by Filter: 18102 是元凶信号 。索引按 release_year 序返回了 18122 行;title 上的 filter 扔掉了 18102 行;LIMIT 在留下 20 行后就停了。我们做了 18000 行的活,才返回 20 行

修法是一个能同时满足两个条件的索引 。在 (release_year, title) 上的复合索引对 LIKE 没用;title 上的三元组索引可以,但对这个场景来说,改写谓词使索引能用、再配适应当前写法的索引最便宜:

sql 复制代码
CREATE INDEX idx_movies_year_title ON movies (release_year DESC, title text_pattern_ops);

text_pattern_ops 让 B 树 能处理前缀 LIKE 模式。重跑:

sql 复制代码
 Limit  (cost=0.42..28.10 rows=20 width=42) (actual time=0.082..0.412 rows=20 loops=1)
   Buffers: shared hit=24
   ->  Index Scan using idx_movies_year_title on movies
         (cost=0.42..1899.40 rows=1372 width=42) (actual time=0.080..0.408 rows=20 loops=1)
         Index Cond: ((release_year >= 2020) AND (title >= 'The '::text) AND (title < 'Th...

Rows Removed by Filter 没了。Buffers 从 18324 掉到 24。运行时间从 184ms 到不到 1ms。错的不是查询、是计划。

看起来简单的那个连接

用户想要自己最近电影的评论:

sql 复制代码
SELECT r.id, r.body, m.title
FROM reviews r
JOIN movies m ON m.id = r.movie_id
WHERE r.user_id = 12
AND m.release_year >= 2023;

第一份计划(内层节点省略节省版面;完整输出每行都带 actual time/rows/loops):

ini 复制代码
 Hash Join  (cost=1240.50..3402.10 rows=80 width=88) (actual time=84.120..312.402 rows=14 loops=1)
   Hash Cond: (r.movie_id = m.id)
   Buffers: shared hit=2104 read=412
   ->  Seq Scan on reviews r
         (cost=0.00..8939.00 rows=100 width=44) (actual time=0.018..201.401 rows=100 loops=1)
         Filter: (user_id = 12)
         Rows Removed by Filter: 499900
   ->  Hash  (cost=1100.00..1100.00 rows=4200 width=44) (actual time=4.812..4.812 rows=4200 loops=1)
         ->  Bitmap Heap Scan on movies m
               (cost=58.10..1100.00 rows=4200 width=44) (actual time=0.412..3.901 rows=4200 loops=1)
               Recheck Cond: (release_year >= 2023)

两个毛病。第一reviews 走了按 user_id 过滤的 Seq Scan,扔掉 499900 行才找出来 100 行------reviews.user_id 上没索引。第二 ,规划器选了 Hash Join,因为它以为 reviews 一侧出 100 行、对上 4200 部近年电影;实际答案只有 14 行,但这数字是两边都全扫完之后才算出来的。

这里正确的修法是设计 reviews schema 时所有人都会忘的那个索引

sql 复制代码
CREATE INDEX idx_reviews_user_id ON reviews (user_id);

重跑:

sql 复制代码
 Nested Loop  (cost=0.85..89.40 rows=80 width=88) (actual time=0.094..1.812 rows=14 loops=1)
   Buffers: shared hit=68
   ->  Index Scan using idx_reviews_user_id on reviews r
         (cost=0.42..32.10 rows=100 width=44) (actual time=0.022..0.412 rows=100 loops=1)
         Index Cond: (user_id = 12)
   ->  Index Scan using movies_pkey on movies m
         (cost=0.43..0.45 rows=1 width=44) (actual time=0.006..0.006 rows=0 loops=100)
         Index Cond: (id = r.movie_id)
         Filter: (release_year >= 2023)
         Rows Removed by Filter: 1

哈希连接变成了嵌套循环 。用户的 100 条评论驱动了对 movies 主键的 100 次快查。这 100 条里 14 条通过了 release_year 过滤。Buffers 从 2516 掉到 68,运行时间从 312ms 到不到 2ms

注意第二份计划怎么暴露出第一份计划藏起来的一件事:内层的 Rows Removed by Filter: 1loops=100一百次主键探针,每一次过滤掉一行或零行 。如果这个用户有 100000 条评论但只有 14 条是近年电影的,这份计划仍然可接受------这个形态能扛住规模

讨厌缓存的那个报表

一条夜跑任务按电影汇总评分:

sql 复制代码
SELECT m.id, m.title, count(r.id) AS rating_count, avg(r.score)::numeric(3,1) AS avg_score
FROM movies m
LEFT JOIN ratings r ON r.movie_id = m.id
GROUP BY m.id, m.title
ORDER BY rating_count DESC
LIMIT 100;

冷缓存运行(HashAggregate 以下内层节点省略版;完整输出每行都带 actual time/rows/loops):

sql 复制代码
 Limit  (cost=15402.10..15402.35 rows=100 width=80) (actual time=2401.812..2401.918 rows=100 loops=1)
   Buffers: shared read=4214 hit=8120
   ->  Sort  (cost=15402.10..15527.10 rows=50000 width=80) (actual time=2401.811..2401.890 rows=100 loops=1)
         Sort Key: (count(r.id)) DESC
         Sort Method: top-N heapsort  Memory: 33kB
         ->  HashAggregate
               ->  Hash Right Join
                     ->  Seq Scan on ratings r
                     ->  Seq Scan on movies m

2.4 秒。再跑一遍热缓存(只列根节点,做对比):

ini 复制代码
 Limit  (...) (actual time=412.018..412.121 rows=100 loops=1)
   Buffers: shared hit=12334

仍然 412ms。计划完全一样。第一次慢在那些 shared read=4214;第二次对一个报表查询算快,但对一个 50000 行的表来说感觉还是慢了点。

这里其实没有真正的 bug 。这条报表要扫每一条评分来算 count。500000 条评分------这就是活本身。ratings.movie_id 上加索引不会 改变"聚合要访问每一行"这一要求。EXPLAIN 告诉你的是:这条查询是被数据体量正确地束缚住了,不是被误规划束缚 。修法在另一层:每晚刷新的物化视图、由触发器维护的计数表,或者接受这次运行时长就是"一次新鲜聚合"的代价。

重要提示

不是每条慢查询都有计划层的修法 。有的查询慢是因为它必须慢。EXPLAIN 最有价值的时刻,是告诉你"你盯着的是哪一种慢":

  • 误规划型慢有计划修法
  • 数据体量型慢有架构修法
  • 冷缓存型慢有内存修法

别用一种工具的修法去补另一种的坑

第 8 章沙箱在 explain-walkthroughs.sql还有五条加注释的查询,比上面三条更进一步。每一条都把误规划的计划和修好的计划并列出来。跑它们。跑之前先预测。看数字怎么动。


这些坑别再踩

读到这里,本篇教过的诊断循环你已经看过了。下面这些是实战中最容易反复出现的错误------多数都跟"凭记忆、不验证"有关。

1. 在慢查询上跑不带 ANALYZE 的 EXPLAIN

你在读规划器的猜测 、却不知道实际发生了什么 。在最需要诊断的查询上,估算可能差几个数量级。想知道时间花在哪,永远跑 EXPLAIN (ANALYZE),并接受跑这条查询的代价------这是诊断的门票。

2. 在冷缓存上对比 EXPLAIN ANALYZE 的耗时

第一次付磁盘代价,第二次显示热计划。把冷第一次跟热第二次当作两份不同计划去对比 ------你会得出错误结论。永远跑两次,看第二次做计划对比

3. 忽略缓冲区

没有它你就分不清缓存病还是计划病。同一份计划在热缓存上能快 50 倍EXPLAIN (ANALYZE, BUFFERS) 该是你的默认;只跑 EXPLAIN (ANALYZE) 是扔掉一半诊断价值。

4. 忘记乘以 loops

一个嵌套循环的内层可能显示 actual time=0.020 rows=4 loops=1000000总时间是 20 秒、总行数是 400 万。人盯着每循环那个值,看见小数字、就当没事故。

5. 把 total cost 当成 total time

cost=15402.10 不是 15 秒。它是 Postgres 内部用来在同一机器上对比计划的任意单位运行时间用 actual timecost 只用来理解规划器为什么挑这个计划而不是那个。

6. 加了索引却不重跑 EXPLAIN

规划器的选择随 schema 和统计变化。一个本该帮上忙的索引常常没用上 ------要么规划器不用、要么统计不导向它、要么这索引根本没盖住谓词。每次改动都重跑。确认新计划真的用上了新索引。

第 8 章压缩成五句话

  • EXPLAIN (ANALYZE, BUFFERS) 是默认 。纯 EXPLAIN 显示猜测、ANALYZE 显示现实、BUFFERS 显示缓存。任何真实诊断都把三者合看。少跑一点就是扔信号。
  • 计划是树,自顶向下读 。根是最终结果、叶是扫描。每个节点五个问题:做什么、预期行数、实际行数、时间(乘 loops)、缓冲命中还是读取。把这套循环跑到变成本能
  • 行估算失准通常是根因rows=actual rows= 差 10 倍以上时,规划器上面每个决策都是基于错误信息做的。修法几乎永远是统计ANALYZE、相关列上的扩展统计、或那一列上更高的 default_statistics_target
  • 缓冲区 把缓存病从计划病里拆出来 。慢查询出 shared hit 数字,问题是计划;出 shared read 数字,问题是缓存。两个毛病、两个修法------没有 BUFFERS 你分不开。
  • 有的慢查询无法在计划层变快 。对大表每行都做聚合的报表,是被数据体量束缚,不是规划器。这时候 EXPLAIN 的活是告诉你"这个工作必须做"------让你停止追一个不存在的计划修法,转去物化视图或计数表
  • 你不总要在现场才能抓到计划 。当慢计划只发生在生产你重跑不出来时,auto_explain 帮你抓:它把超过时长阈值的查询的完整计划写进日志。

小结

读完第 8 章的全部四篇,你应该已经具备下面这套能力:

  • 拿到一份慢查询 ,知道用哪一个 EXPLAIN 变体;知道默认 BUFFERS
  • 读懂计划树 ,自顶向下五个问题逐节点问过去;知道估算 vs 实际 10 倍以上的差距几乎总是根因。
  • 认出四种扫描、三种连接 的合理形态和翻车形态;看出 Rows Removed by FilterHeap FetchesBatchestemp written= 这些信号各自指向哪个修法。
  • 按五步诊断循环走 :跑两遍、找最慢节点、查行估算、查缓存、查红旗,一次只改一件事,然后重跑。
  • 承认"有的慢查询是必须慢",把架构层的修法和计划层的修法分开。

第 9 章我们换一组工具:当一张表上索引选哪个、留哪些、要不要多列------EXPLAIN 给的建议怎么落地。是给"加索引"这件事打底的小学数学课。

下一篇:028 - 索引利弊与多列索引


常见问题答疑(学员答疑)

Q1:Query 1 的修法是建一个带 text_pattern_ops 的复合索引------为什么不直接建三元组索引(pg_trgm)?

三元组索引(pg_trgm)确实能服务 LIKE 'The %' 这类前缀搜索,但它有代价:索引体积比普通 B 树大得多(每行要存所有三元组片段),维护成本高,选择率估算不如 B 树精确。在这个具体场景里,查询同时有两个条件:release_year >= 2020title LIKE 'The %',加上 ORDER BY release_year DESC LIMIT 20。带 text_pattern_ops 的 B 树复合索引 (release_year DESC, title text_pattern_ops) 一口气满足所有需求:按年份范围收窄、按前缀排序、直接返回前 20 行停下。三元组索引做不到这一点------它只能匹配 LIKE,不能同时按年份排序和限制。通用原则:当你能用 B 树覆盖所有条件时,优先用 B 树(更小、更精确);只有当搜索模式不固定(如中间通配 LIKE '%the%')时才用 pg_trgm。SQL Server 的 LIKE 优化策略类似------前缀 LIKE 用普通索引,非前缀用全文搜索。

Q2:Query 3 的报表跑了 412ms,EXPLAIN 说没有计划层的修法------那我该怎么优化?

Query 3 要对 500000 条评分做 countavg 聚合------每一行都必须被访问,这是数据体量的硬约束,不是规划器的错。EXPLAIN 最有价值的时刻不是告诉你"怎么调计划",而是告诉你"这个慢到底是哪种慢"。三种慢对应三种修法:误规划型慢→修统计/加索引/改写 SQL;数据体量型慢→架构层修法(物化视图、触发器维护的计数表、预聚合表);冷缓存型慢→调 shared_buffers/预热缓存。Query 3 属于数据体量型慢------修法是建一个每晚刷新的物化视图 CREATE MATERIALIZED VIEW movie_ratings_summary AS SELECT ...,报表查询直接读物化视图,几毫秒出结果。或者用触发器在每次评分写入时更新计数表------OLTP 写入增加微秒级开销,报表查询从秒级降到毫秒级。判断框架:如果 EXPLAIN 显示扫描了全表但没有 Rows Removed by Filter (没有浪费的活),那就是体量型慢------停止追计划层的修法,转去架构层。

Q3:加了索引但规划器不用------最常见的三个原因是什么?

第一,索引跟查询的谓词形状不匹配。WHERE LOWER(email) = 'alice@example.com' 不会用 email 上的普通索引------索引按原始大小写排序,查询按小写值找,B 树找不到。需要建 LOWER(email) 表达式索引。第二,统计信息让规划器觉得索引不值得用。规划器估算选择率是 30%(返回太多行),干脆走了 Seq Scan------但实际只返回 10 行。修法是 ANALYZE 让统计跟上现实。第三,代价参数不匹配硬件。random_page_cost=4.0 让规划器认为索引的随机读太贵,在 SSD 上应该降到 1.1-1.5。每次加索引后都要重跑 EXPLAIN (ANALYZE, BUFFERS) 确认索引真的被用了------凭直觉加索引然后不验证,是生产中最常见的浪费:索引交着写税,却从未被任何查询用过。

第十三篇:流式响应------让Honcho的推理结果实时呈现在用户面前

等待是体验的杀手。当Agent需要5秒才能回复时,用户已经失去耐心了。流式响应(Streaming)是解决这个问题的标准方案------让内容边生成边显示。

为什么需要流式?

想象两个场景:

  • 场景A:你点击发送,等待5秒,突然一大段文字弹出来
  • 场景B:你点击发送,文字像打字一样逐字显示,2秒后完成

虽然总时间差不多,但场景B的体验远好于A。这就是流式的价值。

Honcho中的流式

Honcho的流式主要用在Chat端点------当Honcho推理关于用户的问题时,响应可以实时流动:

python 复制代码
from honcho import Honcho
import time

honcho = Honcho()
user = honcho.peer("demo-user")
assistant = honcho.peer("assistant")

session = honcho.session("demo-session")
session.add_peers([user, assistant])
session.add_messages([
    user.message("Hello, I'm testing the streaming functionality")
])

# 流式获取响应
response_stream = user.chat(
    "What can you tell me about this user?",
    stream=True
)

for chunk in response_stream.iter_text():
    print(chunk, end="", flush=True)
    time.sleep(0.01)  # 演示用,生产中不需要

TypeScript版本:

typescript 复制代码
import { Honcho } from '@honcho-ai/sdk';

const honcho = new Honcho({});
const user = await honcho.peer('demo-user');
const assistant = await honcho.peer('assistant');

const session = await honcho.session('demo-session');
await session.addPeers([user, assistant]);
await session.addMessages([
    user.message("Hello, I'm testing the streaming functionality")
]);

// 流式获取响应
const responseStream = await user.chat("What can you tell me about this user?", {
    stream: true
});

for await (const chunk of responseStream.iter_text()) {
    process.stdout.write(chunk);
}

实战场景:餐厅推荐

python 复制代码
import asyncio
from honcho import Honcho

async def restaurant_recommendation_chat():
    honcho = Honcho()

    user = honcho.peer("food-lover")
    assistant = honcho.peer("restaurant-assistant")
    session = honcho.session("food-preferences-session")
    await session.add_peers([user, assistant])

    # 存入用户的食物偏好
    user_messages = [
        "我爱辣的泰国菜,尤其是椰奶咖喱。",
        "意大利菜也是我的最爱------新鲜意面和柴火披萨是我的弱点!",
        "我大部分时间吃素,但偶尔吃海鲜。",
        "我不太喜欢太甜的甜点,但黑巧克力是必吃。"
    ]
    session_messages = [user.message(m) for m in user_messages]
    await session.add_messages(session_messages)

    for message in user_messages:
        print(f"User: {message}")

    # 流式获取推荐
    print("\nRequesting restaurant recommendations...")
    print("Assistant: ", end="", flush=True)
    full_response = ""

    response_stream = user.chat(
        "Based on this user's food preferences, recommend 3 restaurants they might enjoy in the Lower East Side.",
        stream=True,
        session_id=session.id
    )

    for chunk in response_stream.iter_text():
        print(chunk, end="", flush=True)
        full_response += chunk
        await asyncio.sleep(0.01)

    # 存储完整回复
    await session.add_messages([assistant.message(full_response)])

asyncio.run(restaurant_recommendation_chat())

流式数据处理模式

处理流式数据时的常见模式:

1. 渐进渲染:每个chunk到达时更新UI,而非等完整响应

python 复制代码
for chunk in stream.iter_text():
    update_ui(chunk)  # 实时更新界面

2. 缓冲处理:累积chunk直到逻辑断点(句子/段落)

python 复制代码
buffer = ""
for chunk in stream.iter_text():
    buffer += chunk
    if "." in buffer:  # 句号作为断点
        process_sentence(buffer)
        buffer = ""

3. 实时Token计数:监控token使用量

python 复制代码
total_tokens = 0
for chunk in stream.iter_text():
    total_tokens += estimate_tokens(chunk)
    if total_tokens > limit:
        break

结构化输出的流式

python 复制代码
from pydantic import BaseModel
from typing import Literal

class FoodPreference(BaseModel):
    food: str
    sentiment: Literal["loves", "likes", "neutral", "dislikes", "hates"]
    confidence: float

class FoodPreferences(BaseModel):
    preferences: list[FoodPreference]
    summary: str

# 结构化输出 + 流式
response_stream = peer.chat(
    "What are this user's food preferences?",
    stream=True,
    response_format=FoodPreferences,
)

# 流式模式下SDK无法自动解析------手动拼接后解析
chunks = []
for chunk in response_stream.iter_text():
    chunks.append(chunk)
    # 可以实时显示JSON构建过程

result = FoodPreferences.model_validate_json("".join(chunks))

性能注意事项

  • 连接稳定性:移动端或不稳定网络需要处理中断
  • 超时设置:为流式操作设置合理超时
  • 内存管理:大响应累积时注意内存
  • 错误处理:网络中断时的优雅降级

Q&A

Q1:流式响应和非流式响应的结果内容一样吗?只是显示方式不同?

A:是的,内容和质量完全一样。流式只是让响应增量返回------chunk在生成时就送达,而非等全部生成后一次性返回。推理过程(搜索结论、追溯前提、合成答案)完全相同。唯一区别是结构化输出+流式时,SDK无法在流式过程中自动解析(因为JSON是不完整的),需要你手动拼接完整字符串后再解析。

Q2:Chat端点的流式和OpenAI API的流式可以嵌套使用吗?比如Honcho回答的同时用OpenAI生成回复?

A:可以。一种常见模式是:先用Honcho的peer.chat()(非流式)获取用户洞察,然后注入OpenAI的prompt,用OpenAI的流式API生成最终回复给用户。另一种是先用Honcho流式获取部分上下文,然后启动OpenAI流式生成。关键是要理清数据流------Honcho的chat结果通常是作为上下文注入LLM的,不需要直接展示给用户。

Q3:流式响应对前端的WebSocket或SSE有什么要求吗?

A:Honcho的流式在SDK层面使用HTTP chunked transfer,SDK把响应包装成可迭代对象。在前端展示时,你的后端需要把Honcho的流式chunk转发给前端------常用的方案是用Server-Sent Events (SSE)或WebSocket。如果你的后端是Python,可以用FastAPI/Flask的流式响应;如果是Node.js,可以直接pipe Honcho的async iterator到HTTP response。关键的时序是:Honcho生成chunk → 你的后端接收 → 转发给前端 → 前端逐字渲染。


大模型论文日报 - 2026-08-18

说明:截至本邮件整理时间(2026-08-18),8月18日当天的 arXiv 日报尚未发布,以下为最近 3 天(08.15--08.17)最受关注的 5 篇论文,均附方向、摘要、结论及对既有假设的挑战与质疑。


1. StateBridge:免训练的隐状态对齐,让多智能体在潜空间直接通信

  • 方向:多智能体 / 隐空间通信 / 推理
  • 论文:StateBridge: Training-free Hidden-state Alignment for Latent Communication in LLM Multi-Agent Systems(arXiv:2608.13317)
  • 摘要:现有 LLM 多智能体系统用文本离散 token 通信,丢弃了连续隐状态里 token 身份无法承载的信息。StateBridge 提出一种免训练的潜空间通信方法:用闭式正交变换把发送方的最后一层隐状态对齐到接收方的输入空间,再辅以轻量范数校准与词表锚定以兼容预训练输入分布,将对齐后的状态作为连续前缀拼接到接收方输入。在 math / 代码 / QA 上用两个家族四个模型评测,StateBridge 在 26 个模型-任务组合中取得 22 个最优或并列最优。
  • 结论:免训练、可移植的隐状态通信可显著提升多智能体协作质量,无需额外训练或逐层注入。
  • 挑战与质疑:直接挑战"多 Agent 只能靠自然语言文本对话协作"的主流假设------离散 token 是信息瓶颈;同时挑战"潜通信必须依赖需训练的项目器/逐层工作记忆注入"的既有路线,证明闭式对齐即可打通。

2. ART:把 VLA 模型改造成会"调用工具"的智能体,动作空间不再是瓶颈

  • 方向:具身智能 / 机器人 / 多模态 Agent
  • 摘要:Evolve Vision-Language-Action Model into an Agent with On-the-fly Tool-use(arXiv:2608.14047)。将端到端视觉-语言-动作(VLA)模型与 agentic 工具调用结合,提出 Agentic Robot with Tool-use(ART)------一个工具注入框架,可微调任意 VLA 模型去调用现成工具模块(低层视觉、高层可供性、具身增强),把连续动作解空间通过工具使用大幅压缩。作者构建 3 万条工具调用轨迹与动作演示数据集,设计长轨迹工具推理训练方案;在仿真与真实任务(如暗光新视角下的抓取放置)上成功率较主流基线高约 20%。
  • 结论:用"工具调用"把全连续动作空间离散化/模块化,可在不堆数据的前提下显著提升跨任务泛化与真实部署成功率。
  • 挑战既有假设:挑战"VLA 落地必须靠更大模型 / 更多动作数据"的主流路径------动作空间本身可以借工具模块压缩,比堆数据更省;同时质疑"端到端 VLA 必须直接输出连续动作"的范式。

3. WMRL:用世界模型替代真实环境执行,RL 训练提速 3--4 倍

  • 方向:强化学习 / 世界模型 / 自动化研究 Agent
  • 摘要:WMRL: Replacing Real-Environment Execution with a World Model Speeds RL 3-4x for Autonomous Research Agents(arXiv:2608.12564)。WMRL 用世界模型替代真实环境执行,将自主研究 Agent 的强化学习训练加速 3--4 倍:在潜空间里 rollout 策略、只在必要时回到真实环境校验,显著降低高成本交互频次,同时保持策略质量。
  • 结论:世界模型可作为"廉价模拟器"承担大部分 rollout,把训练成本大幅下降,且不牺牲策略质量。
  • 挑战既有假设:挑战"自主 Agent 强化学习必须依赖真实环境试错"的隐含前提------真实环境一步贵一步,多数探索可以在潜空间完成,为自动化科研的 RL 训练提供可规模化路径。

4. RippleMem:从"孤立检索"到"联想式回忆",长期 Agent 记忆的补强

  • 方向:Agent 记忆 / 检索增强
    • 摘要:RippleMem: From Isolated Retrieval to Associative Recollection for Long-Term Agent Memory(arXiv:2608.13334)。针对长期 Agent 记忆"检索孤立、缺乏关联"的问题,提出 RippleMem:把记忆片段按语义与事件关联组织,使 Agent 在长程任务中能由一条线索触发相关记忆的连锁召回,而非每次都做无关联的向量检索。
  • 结论:把记忆从"关键词命中"升级为"联想扩散",更贴近人类回忆机制,提升跨会话、跨步骤任务的状态保持能力。
  • 挑战既有假设:挑战"长期记忆 = 更强的向量检索 / 更大的上下文窗口"的工程化假设------记忆的组织与联想结构比检索算法本身更决定可用性,是对现有 RAG 范式的补充与修正。

5. Deliberate Practice:给"该练什么"一个可证明最优的答案

  • 方向:学习理论 / 技能习得 / 自动化科研
  • 摘要:Deliberate Practice: Provably Optimal Allocation for Skill Learning under a Limited Budget(arXiv:2608.13415)。研究在有限"练习预算"下如何最优分配训练资源以习得技能。论文给出可证明最优的资源分配方案,将技能学习建模为预算约束下的资源最优化问题,为"该把算力花在哪些技能/样本上"提供理论保证,而非凭经验堆数据。
  • 结论:刻意练习存在可证明的最优分配方案,为课程式训练、自动化科研的数据选择提供理论基准。
  • 挑战既有假设:挑战"数据越多越好 / 经验式堆料"的惯性------在预算受限的自主 Agent 时代,"练什么"是比"练多少"更优先的科学问题,并首次为练习策略给出严格最优性保证。

以上论文来自 hackcv 每日研究简报(2026-08-17,覆盖 08.15--08.17),并结合 arXiv 原文整理。8 月 18 日 arXiv 日报通常于当日早间发布,若需更精确的"当日"榜单,可于稍晚刷新后再发一版。

大模型日报-2026-08-18

1. Anthropic 年化营收据传突破650亿美元,最快9月或10月IPO

财联社讯:据知情人士透露,Anthropic 营收运行率(年化收入)在7月底已达650亿美元,半年翻超6倍。公司今年二季度实际营收超115亿美元(2025年同期仅7.87亿美元),经调整营业利润首次转正。Anthropic 最快将在9月或10月初进行美股IPO,营收增速被视为"AI能否赚钱"的关键风向标。按此节奏,全球上市公司中届时可能仅微软一家软件营收能压过 Anthropic。

2. Stripe 以超70亿美元收购 AI 模型网关 OpenRouter

彭博社、TechCrunch、Hacker News 确认:支付巨头 Stripe 敲定以超70亿美元收购 AI 模型网关 OpenRouter,是5月B轮13亿美元估值的5.4倍。OpenRouter 覆盖约800万全球用户、接入400+模型、月 token 量超200T。业内视其为"AI流量入口被金融基础设施收编"的标志事件------Stripe 将同时掌控 AI 支出的"计量层(支付)"与"路由层(流量分配)",OpenRouter 连夜上线"路由中立承诺"页面以对冲中立性疑虑。

3. OpenAI 悄然解散"Preparedness"团队,AI 安全治理现分叉

OpenAI 已于7月底解散2023年专设的"Preparedness"团队------该机构负责评估 AI 是否构成严重/灾难性风险。生物与网络风险相关工作被拆分至现有团队,前负责人聚焦"递归自我改进"安全,联合创始人 Greg Brockman 称"安全已更紧密融入模型开发"。同期多名安全人员离职。正值 OpenAI 冲刺 IPO,"商业化加速派"与"安全优先派"的分歧进一步显性化。

4. Anthropic 自曝安全漏洞:生物武器过滤器失效近一年,1.33亿次对话未过滤

Anthropic 最新安全报告披露:用于拦截化学、生物武器相关危险请求的部分安全分类器,在2025年5月至2026年4月期间长期失效;约5万名外部承包商产生的1.33亿次对话未经安全过滤。内部调查未发现相关请求被实际滥用的证据,公司已加强外部承包商筛查要求。这是 Anthropic 上市前最重要的主动披露动作,与 OpenAI 解散安全团队形成鲜明对比。

5. DeepSeek API 峰谷定价正式生效,二轮500亿融资接近签约

8月17日零时起,DeepSeek V4-Flash/V4-Pro 实行峰谷差异化定价:高峰时段(北京时间9:00-12:00、14:00-18:00)价格为非高峰2倍,V4-Pro 峰时段输出价27元/百万tokens(原6元,涨幅超3倍)。同时据报道,DeepSeek 二轮约500亿元融资接近签约,投前估值约5000亿元(约合740亿美元),科创板 IPO 同步推进。配合多家银行推出的"算力 Token 贷",中国大模型正式进入"算投入产出比"阶段。

2026年重磅喜讯! 喜报!热烈祝贺Gavin大咖人工智能领域经典著作《企业级ChatGPT AI大模型应用开发实战(1000分钟视频)》中国水利水电出版社发行上市!

内容提要

本书内容基于作者在硅谷 ChatGPT 项目及企业培训中的实战经验凝练而成,重点介绍企业级 ChatGPT 开发的核心技术、案例研究及最佳实践。全书共 16 章,分为基础篇和实战篇两大部分。

基础篇:

介绍 ChatGPT 底层架构 Transformer 技术及源码实现、GPT 的内部机制及源码实现、GPT 系列模型原理与应用:从 GPT-2 到 GPT-4 等内容。

实战篇:

介绍基于 ChatGPT 的端到端语音聊天机器人项目实战,企业级 ChatGPT 开发的三大核心内部机制及案例实战,ChatGPT 插件的内部机制、源码及案例实战,ChatGPT 提示词开发实战,思维链及 ReAct 解析与实战,提示词本质解析及评估实战与源码解析,LangChain 大模型框架的七大核心组件及案例解析(上、下),LangChain 代理深入解析及源码解析,AutoGPT 源码解析及综合案例实战,使用 LangChain 构建问答聊天机器人案例实战,构建基于大模型的自治代理案例,Llama 2 模型与 LangChain 项目详解。书中每个知识点均配有相应的实现代码和实例。

本书适合有一定 Python 基础的 ChatGPT 爱好者阅读,主要面向从事大模型应用开发、机器学习、数据挖掘或深度学习的专业人员,高等院校相关专业的师生,以及相关领域的科研人员。

本书附赠丰富的学习资源,具体如下:①同步学习资源,即 16 集同步教学视频,视频时长共计约 1000 分钟;②教师授课的辅助资源,即 187 个案例知识点、15 个项目实战的全部源代码。

前言

在当今快速发展的科技时代,人工智能(artificial intelligence,AI)技术正以惊人的速度改变着人们的生活和工作方式。在这个新时代的浪潮中,大模型技术成为AI领域的一颗耀眼新星。ChatGPT作为大模型技术的重要应用之一,正在引领着人机交互领域的革新浪潮。本书将带领读者深入探索大模型新时代,通过ChatGPT实战项目和内部解析,深入掌握基于ChatGPT的大模型应用开发领域的关键技术,并解密ChatGPT的底层架构和实现原理。

本书主要内容

本书通过ChatGPT实战项目的方式,为读者呈现一个全面、系统的学习路径,从基础知识的介绍开始,带领读者深入了解ChatGPT的工作原理和实际应用。本书非常适合具备Python基础的读者学习。

全书共16章,分为基础篇和实战篇两大部分。 基础篇包括第1~3章;实战篇包括第4~16章。

第1章 ChatGPT底层架构Transformer技术及源码实现,详解最大似然估计、最大后验概率、贝叶斯Transformer及自编码与自回归语言模型的内部机制。

第2章 GPT的内部机制及源码实现,剖析GPT运行机制、掩码机制、Decoder-Only模式,详解数据流动生命周期及GPT-2源码。

第3章 GPT系列模型原理与应用:从GPT-2到GPT-4,解析ChatGPT提示词流程、GPT-2运行机制,可视化解读GPT-3/4的内部机制。

第4章 基于ChatGPT的端到端语音聊天机器人项目实战,涵盖ChatGPT API开发、前后端构建(ReAct+FastAPI)及项目优化。

第5章 企业级ChatGPT开发的三大核心内部机制及案例实战,解析企业级开发核心,演示Notion问答对话AI案例。

第6章 ChatGPT插件的内部机制、源码及案例实战,详解插件工作原理、检索插件源码及全流程开发实战。

第7章 ChatGPT提示词开发实战,基于LangChain框架的提示词、思维链、链式提示词及模型评估开发。

第8章 思维链及ReAct解析与实战,剖析思维链推理、ReAct技术原理、框架源码及案例实战。

第9章 提示词本质解析及评估实战与源码解析,包含问答评估、代理评估源码解析及提示词本质探讨。

第10~11章 LangChain大模型框架的七大核心组件及案例解析(上、下),涵盖模型、词嵌入、提示词、内存、回调、数据连接、代理等核心组件及聊天机器人综合案例。

第12章 LangChain代理深入解析及源码解析,详解代理工作原理及AutoGPT源码解析。

第13章 AutoGPT源码解析及综合案例实战,剖析AutoGPT内部机制及其在LangChain代理、内存、PromptGenerator中的应用。

第14章 使用LangChain构建问答聊天机器人案例实战,涵盖GPT-4代码生成全流程及LangChain开发实战。

第15章 构建基于大模型的自治代理案例,详解自治代理原理、工具、示例及开源实现源码。

第16章 Llama 2模型与LangChain项目详解,包括模型部署(Replicate)、Hugging Face/LangChain实践、检索增强生成及自定义提示词RetrievalQA开发。

本书特色

●深入探索,全面剖析。 本书涵盖ChatGPT案例实战、LangChain项目实战及框架源码解析等多个层面的内容。每章都深入探讨相关技术与案例,并提供源码解析,使读者能够全面了解ChatGPT和LangChain等技术的内部机制与开发原理,为实际项目的应用提供有力指导。

●实战剖析,项目揭秘。 本书每章都提供具体的案例实战与项目解析,引导读者通过实际操作和代码理解技术细节和底层逻辑。通过理论结合实践的方式,使读者能够更好地运用所学知识,深入了解项目和框架的实现细节。

●前沿突破,技术驱动。 本书介绍了一系列突破性的技术,如ChatGPT、LangChain、Transformer、Prompt、Llama 2、AutoGPT、BabyAGI、CoT、ToT、ReAct、MRKL等。通过对这些技术的深入剖析,读者可以了解相关技术的发展和应用,并了解它们在实际项目中的具体应用场景和效果。

●源码解析,细致讲解。 本书对LangChain框架的关键技术进行了逐行源码剖析。读者可以深入理解源码实现和机制原理,从而更好地理解技术细节和底层逻辑,并将其应用于实际开发工作中。

本书还为读者提供了丰富的知识和实用的技能,帮助读者在ChatGPT和LangChain领域取得突破性的进展。无论是初学者还是有一定经验的开发者,都可以从本书中获得有价值的学习资源。

配套资源

为便于教与学,本书配有同步教学视频(约1000分钟)、源代码、数据集、教学课件、教学大纲、安装程序。

作者简介

王家林

美国斯坦福大学计算机专业毕业。曾在美国担任硅谷顶级机器学习和人工智能实验室主任、杰出AI工程师及首席机器学习工程师,专精于对话式人工智能(conversational AI)。现担任硅谷某知名对话机器人公司CTO,自2019年起专注于基于红队测试(red teaming)的责任型AI(responsible AI),并热衷于构建生成式AI/大语言模型教练系统(GenAI/LLM coaching systems)。在硅谷任职期间,曾领导多个GenAI/LLM解决方案项目,成功平衡企业业务需求下的大模型推理(reasoning)系统与幻觉(hallucinations)及偏见(biases)风险的最小化。

作为数据科学、机器学习、NLP、ChatGPT及大模型等领域25本书的主要作者,王家林对利用人工智能提供解决方案,以及通过机器学习驱动的NLP与LLM流程帮助组织实现数据驱动决策充满热情。他曾领导Apple、PayPal、Chase Bank、Faethm、LinkedIn等公司的11个重大NLP项目。

在NLP、对话式AI、大数据及基于AWS的无服务器(serverless)技术方面,拥有丰富的机器学习咨询经验。

段智华

中国电信股份有限公司上海分公司高级工程师。长期从事大模型与智能体技术领域,专注Agentic AI、Harness Agent等前沿方向研究。

新书购买链接

《企业级ChatGPT AI大模型应用开发实战(1000分钟视频)》 购买链接:item.jd.com/15389212.ht...

相关推荐
步行cgn1 小时前
MyBatis 动态 SQL 中的 <foreach> 标签完全解析
后端
SomeB1oody2 小时前
【RustyML入门】5.0. 模型评估
开发语言·后端·机器学习·rust·教程
唐青枫3 小时前
别只把 enum 当常量列表:Zig 枚举、状态机与 Tagged Union 实战
后端
2601_963870213 小时前
【计算机毕业设计】基于Spring Boot的非遗文创产品交易平台的设计与实现
java·spring boot·后端
lv__pf3 小时前
Spring之AOP底层源码解析(下)【TL spring14】
java·后端·spring
苍何3 小时前
保姆级教程,Codex 接入 DeepSeek V4 Pro 和 Grok 4.6,6 种方法全整理
后端
苍何3 小时前
全球首款原生全模态交互式世界模型来了,AI 视频终于能“玩”了
后端
一只叫煤球的猫3 小时前
Spring AI 2.0 源码解析(一):一次 ChatClient 调用到底经历了什么?
后端·面试·ai编程