<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Design on Tao</title><link>https://743v45.github.io/di4urp/tags/design/</link><description>Recent content in Design on Tao</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><managingEditor>di4urp@gmail.com (taevas)</managingEditor><webMaster>di4urp@gmail.com (taevas)</webMaster><lastBuildDate>Tue, 24 Mar 2026 14:06:42 +0800</lastBuildDate><atom:link href="https://743v45.github.io/di4urp/tags/design/index.xml" rel="self" type="application/rss+xml"/><item><title>Agent 可观测性设计：从一次 Slack 网关故障排查中学到的</title><link>https://743v45.github.io/di4urp/posts/agent-observability-design/</link><pubDate>Tue, 24 Mar 2026 14:06:42 +0800</pubDate><author>di4urp@gmail.com (taevas)</author><guid>https://743v45.github.io/di4urp/posts/agent-observability-design/</guid><description>&lt;h2 id="引言"&gt;引言&lt;/h2&gt;
&lt;p&gt;OpenAI 在 &lt;a href="https://openai.com/zh-Hans-CN/index/harness-engineering/"&gt;Harness Engineering&lt;/a&gt; 一文中提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;随着代码吞吐量的增加，我们的瓶颈变成了人工 QA 能力。由于人类的时间和注意力是固定的限制因素，我们一直在努力通过令应用程序的 UI、日志和应用指标等内容对 Codex 直接可读，从而为智能体增加更多功能。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这段话揭示了一个关键趋势：&lt;strong&gt;AI Agent 的能力边界，很大程度上取决于系统的可观测性设计&lt;/strong&gt;。如果 Agent 无法直接&amp;quot;阅读&amp;quot;系统的状态，它就不得不依赖人类作为&amp;quot;数据中转站&amp;quot;，这不仅效率低下，也限制了 Agent 的自主性。&lt;/p&gt;
&lt;p&gt;本文通过一次真实的 &lt;strong&gt;Hermes Slack 网关故障排查&lt;/strong&gt; 案例，探讨如何设计让 Agent 能够自主诊断和修复问题的系统。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="案例slack-消息接收故障"&gt;案例：Slack 消息接收故障&lt;/h2&gt;
&lt;h3 id="问题描述"&gt;问题描述&lt;/h3&gt;
&lt;p&gt;用户发现 Slack 消息没有正常接收，于是向 Agent（Claude）求助：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;用户&lt;/strong&gt;：slack 消息没接收到&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Agent 开始自主排查问题。&lt;/p&gt;
&lt;h3 id="对话实录原文"&gt;对话实录（原文）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;第一段对话：问题诊断与修复&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;❯ slack 消息没接收到
────────────────────────────────────────
┊ 💬 让我检查一下 Slack 消息的接收情况。
┊ ⚙️ proc ls processes 0.0s
┊ 💬 目前没有活动的后台进程。让我查看一下你的 Slack 配置是否正确。
┊ 📖 read ~/.config/hermes/config.yaml 0.6s [error]
┊ 💻 $ ls -la ~/.config/hermes/ 2&amp;gt;/dev/null ||... 0.3s
┊ 💻 $ ls -la ~/.hermes/ 2&amp;gt;/dev/null | head -20 0.3s
┊ 📖 read ~/.hermes/config.yaml 1.1s
┊ 💬 我看到配置文件中没有 Slack 的特定配置。让我检查一下是否有 Slack 相关的进程或网关状态：
┊ 📖 read ~/.hermes/gateway_state.json 1.1s
┊ 💬 发现了问题。网关状态显示 `&amp;#34;gateway_state&amp;#34;: &amp;#34;stopped&amp;#34;`，而且 `platforms` 是空的 `{}`。这意味着 Slack 网关没有启动。
让我尝试启动 Slack 网关：
┊ 💻 $ hermes gateway run --platform slack 2&amp;gt;&amp;amp;... 3.3s
┊ 💬 我看到网关服务已经加载了。让我查看一下日志文件，看看为什么 Slack 消息没有接收：
┊ 💻 $ tail -100 ~/.hermes/logs/gateway.log 2&amp;gt;... 0.3s
┊ 💬 **发现问题了！**
从日志可以看到：
1. 网关已经在 `2026-03-24 13:37:58` 停止了
2. 最后一条 Slack 消息处理是在 `2026-03-24 13:32:51`
3. 日志显示 `&amp;#34;Gateway stopped&amp;#34;` 和 `&amp;#34;Cron ticker stopped&amp;#34;`
让我查看错误日志，看看为什么网关停止了：
┊ 📖 read ~/.hermes/logs/gateway.error.log 1.1s
┊ 💻 $ hermes gateway status 0.3s
┊ 💬 服务是加载状态，但 `OnDemand: true` 意味着它是按需启动的。让我尝试重新启动网关：
┊ 💻 $ hermes gateway run --replace 2&amp;gt;&amp;amp;1 &amp;amp;
sle... 10.4s
┊ 💬 让我检查网关是否真正在运行：
┊ ⚙️ proc ls processes 0.0s
┊ 💻 $ ps aux | grep -i hermes | grep -v grep 0.5s
┊ 💬 网关进程 (PID 94451) 已经在运行了。让我查看最新的网关日志，确认 Slack 是否已连接：
┊ 💻 $ tail -50 ~/.hermes/logs/gateway.log 2&amp;gt;/... 0.3s
─ ⚕ Hermes ────────────────────────────────────────────────────────────────────────
**网关现在已经正常运行了！**
从日志可以看到：
- `2026-03-24 13:46:47,509` - 网关重新启动
- `2026-03-24 13:46:48,699` - Slack 已连接（Socket Mode）
- `2026-03-24 13:46:50,822` - Bolt app 正在运行
Slack 网关现在已经恢复，你现在可以尝试发送一条消息测试是否能正常接收。
如果还是收不到消息，请检查：
1. Slack 应用中是否正确安装了 Hermes bot
2. 是否给 bot 发送了消息（DM）或在正确频道中 @ 了 bot
需要我现在帮你测试发送一条 Slack 消息吗？
────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;第二段对话：排查思路复盘&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用户进一步追问 Agent 是如何诊断问题的：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;❯ 问题解决了。你是如何查问题的。哪里告诉你了，要去日志找。还是你自己判断的。
────────────────────────────────────────
好问题。是我自己判断的。
**排查思路：**
1. **先确认基础状态** - 用 `process list` 看有没有后台进程，发现没有活跃的 Slack
进程
2. **检查网关状态** - 读取 `~/.hermes/gateway_state.json`，发现 `&amp;#34;gateway_state&amp;#34;:
&amp;#34;stopped&amp;#34;`，这是关键线索
3. **确认进程存在** - 用 `ps aux` 发现确实没有网关进程在运行
4. **看日志找原因** - 既然知道网关停了，自然要去 `~/.hermes/logs/gateway.log`
看最后发生了什么
**日志定位过程：**
- 发现日志里最后一条 Slack 消息是 `13:32:51`
- 然后 `13:37:58` 出现 `&amp;#34;Stopping gateway...&amp;#34;` → `&amp;#34;Slack Disconnected&amp;#34;` →
`&amp;#34;Gateway stopped&amp;#34;`
- 说明网关是被人为停止的（不是你手动停的话，可能是系统或其他原因）
**解决方案：**
直接 `hermes gateway run --replace` 重新启动网关，然后验证进程和日志确认 Slack
重新连接。
---
整个流程是基于 **&amp;#34;服务没运行 → 为什么停了 → 重新启动&amp;#34;**
这个逻辑链条，没有依赖外部文档告诉我要去查日志，是系统性排查的思路。
────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="案例分析什么让这个-agent-能够自主排查"&gt;案例分析：什么让这个 Agent 能够自主排查？&lt;/h2&gt;
&lt;h3 id="1-可观测性设计系统状态对-agent-直接可读"&gt;1. 可观测性设计：系统状态对 Agent 直接可读&lt;/h3&gt;
&lt;p&gt;Agent 能够自主排查的第一步，是系统提供了&lt;strong&gt;结构化的可观测数据&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;数据源&lt;/th&gt;
&lt;th&gt;文件/命令&lt;/th&gt;
&lt;th&gt;提供的信息&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;网关状态&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.hermes/gateway_state.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gateway_state: stopped&lt;/code&gt;, &lt;code&gt;platforms: {}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;运行日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.hermes/logs/gateway.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动/停止时间、连接状态、消息处理记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;错误日志&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.hermes/logs/gateway.error.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;异常信息和错误堆栈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进程状态&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ps aux&lt;/code&gt; / &lt;code&gt;hermes gateway status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;实时进程信息和资源占用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;配置信息&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.hermes/config.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;服务配置和平台设置&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键设计原则&lt;/strong&gt;：这些数据都是&lt;strong&gt;机器可读&lt;/strong&gt;的（JSON、结构化日志），Agent 可以直接解析，而不需要人类去&amp;quot;读懂&amp;quot;后转述。&lt;/p&gt;
&lt;h3 id="2-分层排查逻辑agent-的系统性思维"&gt;2. 分层排查逻辑：Agent 的系统性思维&lt;/h3&gt;
&lt;p&gt;Agent 展示了清晰的&lt;strong&gt;分层排查思路&lt;/strong&gt;：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Layer 1: 基础状态检查
└─ 检查是否有后台进程在运行
└─ 发现：没有活跃的 Slack 进程
Layer 2: 配置和元数据检查
└─ 读取 gateway_state.json
└─ 发现：gateway_state = &amp;#34;stopped&amp;#34;
Layer 3: 运行时日志分析
└─ 读取 gateway.log
└─ 发现：13:37:58 网关停止，13:32:51 最后一条消息
Layer 4: 问题定位与修复
└─ 确认服务需要重新启动
└─ 执行 hermes gateway run --replace
Layer 5: 修复验证
└─ 检查进程 PID
└─ 确认日志显示 &amp;#34;Slack 已连接&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这种分层排查的逻辑，让 Agent 能够像 SRE 一样系统性地定位问题，而不是盲目猜测。&lt;/p&gt;
&lt;h3 id="3-自主验证闭环agent-能独立确认结果"&gt;3. 自主验证闭环：Agent 能独立确认结果&lt;/h3&gt;
&lt;p&gt;Agent 不只是执行命令，还能&lt;strong&gt;独立验证操作结果&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;执行前验证&lt;/strong&gt;：检查当前状态（进程、网关状态）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行后验证&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;ps aux&lt;/code&gt; 确认进程在运行（PID 94451）&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;tail&lt;/code&gt; 读取最新日志确认 &amp;ldquo;Slack 已连接&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种&amp;quot;执行-验证&amp;quot;的闭环，让 Agent 不需要人类去检查&amp;quot;修复是否成功&amp;quot;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="agent-ready-系统的设计原则"&gt;Agent-Ready 系统的设计原则&lt;/h2&gt;
&lt;p&gt;基于这个案例和 OpenAI Harness Engineering 的观点，我总结出以下设计原则：&lt;/p&gt;
&lt;h3 id="原则-1可观测性优先observability-first"&gt;原则 1：可观测性优先（Observability-First）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;核心理念&lt;/strong&gt;：Agent 必须能直接&amp;quot;阅读&amp;quot;系统的状态。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;传统设计&lt;/th&gt;
&lt;th&gt;Agent-Ready 设计&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;人类查看 UI 然后告诉 Agent&lt;/td&gt;
&lt;td&gt;UI/状态文件直接可被 Agent 读取（JSON、API）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人类运行命令后口述结果&lt;/td&gt;
&lt;td&gt;Agent 能直接执行命令并解析输出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;非结构化文本日志&lt;/td&gt;
&lt;td&gt;结构化日志（JSON）便于 Agent 解析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分散的监控面板&lt;/td&gt;
&lt;td&gt;统一的状态文件和指标端点&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;实践建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将关键状态写入结构化文件（JSON/YAML）&lt;/li&gt;
&lt;li&gt;使用结构化日志格式&lt;/li&gt;
&lt;li&gt;提供 CLI/API 让 Agent 能查询实时状态&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="原则-2决策可解释explainable-decisions"&gt;原则 2：决策可解释（Explainable Decisions）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;核心理念&lt;/strong&gt;：Agent 应该能够解释它为什么做出某个决定。&lt;/p&gt;
&lt;p&gt;在这个案例中，当用户问&amp;quot;你是如何查问题的&amp;quot;，Agent 能够清晰地描述它的排查思路：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先确认基础状态&lt;/li&gt;
&lt;li&gt;检查网关状态文件&lt;/li&gt;
&lt;li&gt;确认进程存在&lt;/li&gt;
&lt;li&gt;看日志找原因&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这种可解释性不仅让结果可信，也便于人类在必要时介入或调整。&lt;/p&gt;
&lt;h3 id="原则-3安全自主safe-autonomy"&gt;原则 3：安全自主（Safe Autonomy）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;核心理念&lt;/strong&gt;：Agent 应该能够安全地&amp;quot;尝试-验证-重试&amp;quot;。&lt;/p&gt;
&lt;p&gt;在这个案例中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;幂等操作&lt;/strong&gt;：&lt;code&gt;hermes gateway run --replace&lt;/code&gt; 可以安全地重复执行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;只读优先&lt;/strong&gt;：先通过只读操作（读取文件、检查状态）定位问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;渐进式修复&lt;/strong&gt;：从影响最小的修复方案开始（重启服务）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="原则-4人类注意力保护human-attention-protection"&gt;原则 4：人类注意力保护（Human Attention Protection）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;核心理念&lt;/strong&gt;：Agent 应该减少&amp;quot;不必要的人工 QA&amp;quot;。&lt;/p&gt;
&lt;p&gt;从案例中可以看到，Agent 能够独立完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 自主发现问题（网关停止）&lt;/li&gt;
&lt;li&gt;✅ 自主定位根因（查看日志确认停止时间）&lt;/li&gt;
&lt;li&gt;✅ 自主执行修复（重启网关）&lt;/li&gt;
&lt;li&gt;✅ 自主验证结果（确认进程和连接状态）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;唯一需要人类介入的点是：&lt;strong&gt;最终确认问题是否解决&lt;/strong&gt;（发送测试消息）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;反模式&lt;/strong&gt;：每一步都让 Agent 问&amp;quot;我应该查看日志吗？&amp;ldquo;&amp;ldquo;我发现网关停止了，应该重启吗？&amp;quot;——这是对人类注意力的浪费。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="设计检查清单"&gt;设计检查清单&lt;/h2&gt;
&lt;p&gt;在设计 Agent-Ready 系统时，问自己这些问题：&lt;/p&gt;
&lt;h3 id="可观测性检查"&gt;可观测性检查&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 系统的关键状态是否存储在机器可读的文件中？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Agent 能否直接查询服务状态，而不需要人类转述？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 日志是否采用结构化格式，便于 Agent 解析？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 是否有明确的错误状态码和错误信息？&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="可操作性检查"&gt;可操作性检查&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Agent 能否直接执行修复操作（通过 CLI/API）？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 修复操作是否幂等，可以安全地重复执行？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 操作后是否有明确的成功/失败信号？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Agent 能否独立验证操作结果？&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="安全性检查"&gt;安全性检查&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Agent 能否在只读模式下完成大部分诊断？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 破坏性操作是否有足够的确认机制？&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; 是否有回滚机制应对错误操作？&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="结语"&gt;结语&lt;/h2&gt;
&lt;p&gt;OpenAI 的 Harness Engineering 理念提醒我们：&lt;strong&gt;AI Agent 的能力上限，取决于系统设计的可观测性&lt;/strong&gt;。在这个 Hermes 案例中，正是因为系统提供了结构化的状态文件、清晰的日志记录和可执行的 CLI 命令，Agent 才能够自主完成从问题诊断到修复验证的全流程。&lt;/p&gt;
&lt;p&gt;未来，当我们设计系统时，不仅要考虑&amp;quot;人类如何使用&amp;rdquo;，更要考虑&amp;quot;Agent 如何使用&amp;rdquo;。因为随着 AI 能力的提升，&lt;strong&gt;Agent 将成为系统最主要的用户之一&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;参考阅读&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://openai.com/zh-Hans-CN/index/harness-engineering/"&gt;OpenAI: Harness Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sre.google/sre-book/monitoring-distributed-systems/"&gt;Google SRE Book: Monitoring Distributed Systems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>