OpenClaw 内核简析——网关、心跳与记忆
1. 从一次 Agent 掉线说起网关、心跳与记忆到底在解决什么如果你正在自建 Agent大概率遇到过这三种让人抓狂的场景手机端发出去的消息石沉大海翻日志才发现 WebSocket 早就断了让 Agent 盯一个跑两小时的数据抓取任务中途它悄悄睡过去你完全不知道换了台电脑重新连上Agent 像失忆一样问你我们之前聊到哪了。这三个问题分别对应 OpenClaw 内核里的三根支柱——网关统一入口、心跳保活、记忆持久化。OpenClaw 是 2026 年初冒出来的开源 Agent 项目GitHub 开源不到一个月冲到近 15 万 Star中间还经历了三次快速更名。它火的原因不是模型多强而是把Agent 该怎么活着这件事拆得很清楚。你可以把它理解成一个数字生命的骨架网关是身体和感官负责所有消息进出的统一调度心跳是自发呼吸让 Agent 在没人盯着的时候也能自检记忆是人格连续性让它跨会话记住你是谁、做过什么。这篇不聊虚的架构图直接给你能复制粘贴的网关配置片段、心跳间隔参数、记忆存储结构再附上本地验证步骤。适合已经动手写过 Agent loop、但被连接稳定性和上下文丢失折磨过的开发者。读完你应该能自己搭一个最小可用的三件套并且知道每个参数改大了改小了会发生什么。先说清楚一个前提下面所有配置里的 Base URL 和 Key我用的是 TaoToken 的接入方式因为它的 API 格式和主流 OpenAI 兼容接口一致改起来最省事。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 后面配置片段里会反复出现。2. 网关 Gateway统一请求入口的配置与热重载实战网关要解决的核心问题是消息可能来自 Telegram、Discord、飞书、CLI、IDE、手机客户端格式五花八门但 Agent 只应该看到一个统一入口。OpenClaw 的 Gateway 就是干这个的——所有请求先到它这里由它决定交给哪个 Agent、怎么回。它的启动不是简单开个端口而是一套有依赖顺序的编排先加载插件才知道有哪些渠道要启动先建好 HTTP/WS 服务器才能把 WebSocket 处理器挂上去。这个顺序不能乱乱了就会出现渠道注册了但服务器还没起来的竞态。启动完成后进入运行态同时开两扇门HTTP 层处理一问一答式的 Webhook 回调和 API 调用WebSocket 层处理需要长连接的实时双向通信。为什么非要两层因为 Telegram、Slack 这类渠道是 Webhook 推送的天然适合 HTTP而自有客户端要实时收 Agent 回复只有 WebSocket 撑得住。下面是一份可以直接改的网关配置片段我把它写成 JSON路径按 OpenClaw 默认的~/.openclaw/gateway.json放{ gateway: { http: { enabled: true, host: 127.0.0.1, port: 8787, auth: { mode: token, token: sk-your-taotoken-key } }, websocket: { enabled: true, path: /ws, pingIntervalMs: 25000, pongTimeoutMs: 10000 }, providers: [ { name: taotoken, baseUrl: https://taotoken.net/api, apiKey: sk-your-taotoken-key, model: claude-sonnet-4-5, protocol: openai-compatible } ], hotReload: { enabled: true, debounceMs: 800, watchPaths: [./gateway.json, ./hooks, ./cron] } } }几个参数值得单独说。pingIntervalMs设 25000 是给 WebSocket 层做底层保活和后面讲的心跳不是一回事——这个只管 TCP 连接别被中间设备掐掉。debounceMs是热重载的防抖窗口你编辑器保存文件时可能触发多次写盘800 毫秒能把它们合并成一次重载。watchPaths里列的是会被监听的路径改了 hooks 只热重载 hooks改了渠道只重载对应渠道只有动了安全配置或核心参数才会整体重启。热重载背后的逻辑是变更路径 → 重载动作的规则匹配配置文件变更后先防抖再对新旧配置做 Diff把每个变更路径映射到对应策略。这也解释了为什么启动编排要拆得那么细——热重载本质就是重新执行启动流程里的某几步如果启动不是模块化的局部重载根本无从谈起。认证这块网关支持从公网 Token 到本机免认证的多种模式按部署场景选。本地开发我一般直接mode: none省事但只要暴露到公网就必须上 Token别偷懒。3. 心跳机制让 Agent 在无人注视时保持活着传统心跳只检测连接是否存活OpenClaw 的心跳检测的是 Agent 的精神状态。区别在哪连接活着不代表 Agent 还在正常工作——它可能卡在一个死循环里或者任务早就失败了但进程还挂着。心跳的做法是定期向 Agent 提问根据回答判断状态。流程是个闭环定时器触发 → 构造心跳 Prompt 发给 Agent → Agent 回复 → 系统检查回复里有没有约定 token默认HEARTBEAT_OK→ 有就静默丢弃没有就转发给用户。这个静默过滤是设计精髓Agent 一切正常时不会每半小时骚扰你一次我很好只有它认为有异常、回复里不带那个 token消息才会推到你面前。还有个细节是确认消息的最大字符数默认 300。如果 Agent 的一切正常回复超过这个长度系统会认为这不是简单确认而是有实质内容要告知于是照样转发。这个阈值防止 Agent 用一大段话把异常藏在正常回复里。心跳配置片段放在~/.openclaw/heartbeat.json{ heartbeat: { enabled: true, intervalMs: 1800000, promptFile: ./HEARTBEAT.md, okToken: HEARTBEAT_OK, maxAckChars: 300, forwardOnMissingToken: true, provider: taotoken, model: claude-sonnet-4-5 } }intervalMs默认 1800000 就是 30 分钟。这个值怎么定我试过调到 5 分钟结果 Agent 频繁自检token 消耗肉眼可见地涨调到 2 小时又出现过任务挂了 40 分钟才被发现的情况。经验是监控类任务用 15 到 30 分钟纯对话型 Agent 可以拉到 1 小时以上。promptFile指向的HEARTBEAT.md让你自定义检查内容比如检查以下项目全部正常则只回复 HEARTBEAT_OK 1. 数据库连接是否可用 2. 今日抓取任务进度百分比 3. 是否有超过 10 分钟未处理的消息心跳 Prompt 支持自定义这点很关键它把保活升级成了业务自检。你可以让 Agent 每次心跳时顺手报告抓取进度等于免费获得一个定时巡检。4. 记忆体系四层上下文注入与跨会话持久化结构大模型没有持久记忆每次对话从零开始上下文窗口还有限。OpenClaw 用四层上下文注入解决这个问题每次 Agent 执行前自动组装成系统提示词。四层从上到下稳定性递减、变化频率递增SOUL 几乎不变TOOLS 随环境调整USER 随交互积累Session 每条消息都在变。SOUL 层是人格内核SOUL.md定义 Agent 的语气、行为准则系统检测到就注入指令要求它体现人格避免呆板回复。TOOLS 层是动态工具注册根据当前环境有没有沙箱、渠道类型、模型是否支持视觉决定注册哪些工具最终渲染到提示词的 Tooling 部分。USER 层是长期记忆由USER.md用户档案和memory/目录组成。Session 层处理当前会话包含实时对话历史、会话归档和上下文压缩。记忆存储结构长这样memory/目录下每个文件是一段可检索的记忆{ memory: { dir: ./memory, chunkSize: 400, chunkOverlap: 80, vectorWeight: 0.7, fulltextWeight: 0.3, topK: 6, minScore: 0.35, embedding: { provider: taotoken, baseUrl: https://taotoken.net/api, model: text-embedding-3-small } } }检索是混合搜索向量搜索占 70% 权重在 SQLite sqlite-vec 里做语义近似全文搜索占 30%补上向量在精确匹配上的短板。两种结果加权合并取 top 6低于 0.35 分的过滤掉。记忆文件按每 400 token 一块、80 token 重叠切分重叠是为了防止跨块上下文被切断。系统提示词里有专门的 Memory Recall 指令要求 Agent 回答任何关于历史工作、决策、偏好的问题前先搜记忆库。四层协同形成产生 → 积累 → 沉淀 → 检索的闭环Session 归档后沉淀为 USER 长期记忆Agent 对话时检索长期记忆丰富当前回应上下文压缩前静默保存重要信息防止丢失。这套设计让 Agent 不再是每次从零开始的健忘症患者。5. 本地验证与常见报错排查配置写完得验证。先起网关再发一个测试请求确认链路通curl -X POST http://127.0.0.1:8787/v1/chat/completions \ -H Authorization: Bearer sk-your-taotoken-key \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 只回复 HEARTBEAT_OK}] }正常返回里应该能看到HEARTBEAT_OK说明网关、认证、模型调用三段都通了。接着验证心跳把intervalMs临时改成 10000观察日志里有没有静默过滤的记录。再验证记忆手动往memory/丢一个 md 文件重启后问 Agent 一个相关问题看它能不能检索到。下面是我踩过的几个真实报错对照着排401 Unauthorized最常见八成是apiKey和auth.token不一致或者 Key 里带了多余空格。检查配置里两处 Key 是否都指向同一个有效值。local proxy failed通常出现在baseUrl写错的时候。注意 API 入口是https://taotoken.net/api别手滑写成带路径后缀的形式协议头也别漏。reading choices: unexpected end of JSON input说明返回体不是标准 OpenAI 格式多半是protocol字段没设成openai-compatible或者模型名写错了导致上游返回了错误页。OAuth token expired如果你用的是 OAuth 类认证检查 token 刷新逻辑本地开发建议直接切 Token 模式绕开。WebSocket 连上又断先看pingIntervalMs是不是大于了中间设备的空闲超时一般设 25 秒比较稳。心跳不触发检查enabled和intervalMs以及promptFile路径是否存在——文件找不到时心跳会静默失败。6. 把三件套接进你的 Agent 工作流网关、心跳、记忆不是三个独立模块而是一条时间线上的三个阶段搭建 → 运行 → 安全 → 演进。网关按依赖顺序把组件搭好心跳让它在无人时保持在场记忆让它跨会话保持连续。缺任何一个生命感都会塌。如果你想把这套东西真正跑起来建议按这个顺序推进先用网关配置把请求入口统一确认 HTTP 和 WebSocket 都能通再打开心跳把HEARTBEAT.md写成你实际的巡检项最后接记忆先只上 USER.md跑顺了再加memory/的混合检索。模型和 Embedding 都走 TaoToken 的兼容接口配置里改baseUrl和model就行接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 申请。想先验证模型对话效果可以直接用 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 试长期跑编码类 Agent 的话Coding Plan 在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后留一个我自己的习惯每次改完网关配置先跑一遍上面那条 curl再去看心跳日志最后问 Agent 一个只有长期记忆才知道的问题。三步都过才算这次改动真的生效了。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →