绑定手机号
获取验证码
确认绑定
提问
0/255
提问
订阅开课提醒需关注服务号
回答成功
知道了
扫码关注智猩猩服务号登录
请使用微信扫描二维码
扫描二维码分享给微信好友
您已订阅成功,有新课程,我们将第一时间提醒您。
知道了
发送提问成功
回答可在
“我的——我的提问”中查看
知道了
失败
欢迎来智东西
关注我们
智东西
车东西
芯东西
智猩猩
0
0
聊聊OpenClaw的AgentLoop
分类: AI技术解析
2026-02-18 10:01:00

作者:少年弈

地址:https://zhuanlan.zhihu.com/p/2003914477209413004

经授权发布,如需转载请联系原作者

OpenClaw最近热度很高。体验下来,它除了是一个可以接管你电脑的通用Agent(Code Agent就是通用Agent)以外,另一点优势还在于你可以通过聊天软件遥控Agent帮你操作电脑。古早的时代我也用手机连过开发机,感到操作非常痛苦——主要是输入不方便。而接入Agent以后可以用简短的指令说明要求,剩下的Agent帮你代管了。

关于具体的实现,OpenClaw内部有个Gateway层用于接入各种IM聊天工具,各种IM工具里的消息发给Channel,然后串行被消费到,然后发送给Pi Agent(这是它内部的核心Agent),Agent输出以后再通过Channel + WebSocket给对应的IM工具发消息。

最近刷到了一些AI生成的OpenClaw的解析文章,发现有的部分和我想的有出入,所以决定自己看一下具体的实现,写篇文章拆解一下它的Agent Loop。

01 概述

本文跳过上文中简略提到的Gateway与Channel,先看一下在一个Session乃至在单轮的模型调用中,它的上下文管理策略是怎样的。

1. Session

Session是OpenClaw内部的用于区分不同上下文的会话概念。简单来说,一个Session类似你在Gemini开的一个会话窗口,不同Session的上下文是独立的。可以容易想到的是,不同的聊天窗口Session是隔离的,比如单聊和群聊。

你可以通过/new指令来新开一个会话。相对的,它有自动的Session切分策略:

1. 空闲的切分:如果一个会话长时间没继续,下次会开启新的会话。

2. 周期性的切分:每天凌晨4点以后发起的会话,相较于前一天会是一个新的会话。

单个Session中历史记录的存储路径是~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl,其中<agentId>通常是main,SessionId由openclaw自行生成uuid,同时还会有个~/ .openclaw/ agents/ <agentId>/ sessions/ sessions.jsonl用来管理session的元数据。

2. Workspace

在OpenClaw被初始化以后,它的工作区(workspace)会存在一些文件。这些文件的内容会影响Agent的行为,我们先感性地认知这些文件会被固定加载到上下文中。

  • BOOTSTAP.md: 提示Agent还没有完成初始化,这会让OpenClaw在第一次被使用时与用户进行一些简单的问答,比如:

Hey. I just came online. Who am I? Who are you?
  • SOUL.md: 指引Agent的行动方式,比如尽可能提供帮助,提问前先尝试自己寻找答案。(内容中提及如果Agent修改了该文件应当显式地告诉用户。

  • IDENTITY.md: Agent在聊天中的风格,比如自称、气质、喜欢用什么emoji。

  • USER.md: 用户的个人画像。

工作区的文件是可以由Agent自行修改和写入的,因此它可能会自行决策什么时候在这些文件中记录一些内容。

3. Pi Agent

OpenClaw并没有自己构造一个agent loop,相反它把Agent相关的事情都交给了Pi Agent,或者说OpenClaw整体来看就是Pi Agent套壳,Pi Agent对外暴露的包是

@mariozechner/pi-coding-agent(高级SDK)
@mariozechner/pi-agent-core (Agent Runtime)
@mariozechner/pi-ai (LLM API)

OpenClaw向Pi Agent提供了System Prompt, Tools, SessionManager(做一些零碎的控制),然后订阅Pi Agent运行过程中的一系列事件,处理流式文本和工具事件并分发给gateway。

注意:session存储到硬盘主要由 pi-coding-agent 的 SessionManager 在运行中完成,不是事件订阅器直接写入

Pi Agent是个非常简洁的Code Agent,只有Read, Edit, Write, Bash四个基础工具,并且Bash工具还被OpenClaw给替换了,其他工具都是在OpenClaw中提供的。

02 Context

1. Pi Agent的Context

如上文所说,OpenClaw的Agent能力是由Pi Agent实现的,因此我们先看看Pi Agent的上下文有哪些部分组成。

其中Messages里有用户输入、模型输出、工具调用结果等,一步步追加到Messages里。

Pi Agent有自己的上下文压缩策略:(1)上下文溢出以后会自动压缩并且重试 (2)到达一定窗口以后进行压缩。

压缩是使用了一段提示词summary,压缩后的消息由压缩后的内容+保留的最近的内容组成。

Tool Definition会由Pi Agent的适配层对OpenAI/Gemini/Anthropic和其他家的模型做适配,传入对应的模型API,然后由模型输出function call

2. OpenClaw的System Prompt

OpenClaw替换了Pi Agent的很多部分,比如System Prompt就给完全替换了,这里我们看一下OpenClaw的System Prompt。

OpenClaw的system prompt有两种模式,full是给主agent使用的,minimal模式是给子agent用的,minimal删减了一部分内容。

项目

描述

minimal模式存在

固定开头

You are a personal assistant running inside OpenClaw.

Tooling

可用的工具列表和工具能力摘要

Tool Call Style

强调工具调用要简洁并且有价值、避免明显重复的工具调用。

Safety section

强调不要越过安全限制,不要做任务以外的事情。

OpenClaw CLI Quick Reference

列出了一些可用的openclaw cli命令,比如openclaw gateway start, openclaw gateway stop,openclaw gateway restart...

Skills

列出可以使用的Skill,格式XML<available_skills> <skill> <name>...</name> <description>...</description> <location>...</location> </skill></available_skills>

Memory Recall

说明使用memory的要求:回答过往工作/决策/日期/人物/偏好/todo这类内容前前,先memory_search,再 memory_get 拉取所需行。Markdown## Memory Recall Before answering anything about prior work, decisions, dates, people, preferences, or todos: run memory_search on MEMORY.md + memory/*.md; then use memory_get to pull only the needed lines. If low confidence after search, say you checked.

OpenClaw Self-Update

除非用户要求,不要自更新

Model Alias

列出所用模型的别名

时区提示

说明当前时区

Workspace

说明当前工作目录的Path,列出notes(todo: notes哪里来

Documentation

提供了文档目录时,读取一些内容

User Identity

用户身份

Heartbeats

让 OpenClaw 能定期确认 agent 是否在线系统会配置一个心跳触发词(heartbeatPrompt),如果收到这类心跳消息且没有需要处理的事,agent 必须回 HEARTBEAT_OK;如果有异常/待处理事项,直接回告警内容。

ReActions

避免 agent 要么完全不反应、要么过度刷表情,保证不同渠道体验一致。minimal: 只在重要确认/明显情绪时少量反应(建议 5-10 轮最多 1 次)。extensive: 可以更自然、更频繁地反应(确认、共鸣、幽默等)。

Project Context

注入contextFiles,包含AGENTS.md,TOOLS.md,USER.md,HEARTBEAT.md,BOOTSTRAP.md,MEMORY.md(可选),memory.md(可选,和 MEMORY.md 去重)拼接格式:## <path> + file contentfile content大于一定长度也会截断

Slient Replies

说明可以用SILENT_REPLY_TOKEN发送用户不可见内容。

Runtime

- agent(会话/agent id) - host - repo - os / arch - node - model / default_model - channel / capabilities - thinking(默认思考级别)

System Prompt的Tooling里还包含了一份tool的简要描述,实际上Pi Agent内部给模型又单独拼接了完整的tool schema给各家模型的API用于function call,可能System Prompt中的tool简要描述起一个强调的作用。

3. Open Claw对上下文的处理

上文所说, Pi Agent内部本身做了自己的上下文压缩,但是Open Claw又给在外面套了一层压缩策略。目前我没有搞清楚两套压缩策略是否会同时生效,需要实际Debug一下。

压缩(compaction)

当会话接近或超过模型的上下文窗口时,OpenClaw 会触发自动压缩,并可能使用压缩后的上下文重试原始请求。

压缩前的memory写入:当会话快接近自动压缩的阈值的时候,OpenClaw有个silent memory flush机制,可以让agent主动把会话中的关键信息记录到memory/YYYY-MM-DD.md

OpenClaw没有自己提供一个独立的提示词来压缩上下文,直接用了Pi Agent里的compact功能相关函数。

这里不讨论用户手动的/compact命令

裁剪(pruning)

Pruning是给Anthropic系列模型(包括OpenRouter的anthropic开头的模型)单独做的功能,对其他模型的请求不会在请求前进行pruning。

看官方文档,做pruning原因是Anthropic系列模型的提示缓存存在TTL。因此如果是提示缓存过期以后的请求,会考虑每次发起请求前把给模型的toolResult类型消息做裁剪(toolResult相对其他类型的消息更容易过大),最后的几条(可配置)toolResult会保留原状。

针对Anthropic系的API, 有两种裁剪策略:

  • Soft Trim: 保留头尾,中间插入....,会追加一个原始token长度的note

  • Hard Clear: 把整个工具结果用一个占位符替换。

优先使用Soft Trim,如果发现Soft Trim以后的toolResult依然过大,就会使用Hard Clear.图片消息永远不会被pruning(base64确实也不应该干掉部分,干掉以后干脆不可用了)

当然我觉得另一个原因是Claude模型卖的比较贵,要用得省一点。

03 Tool && Skills

OpenClaw内部集成了很多工具和Skill,这赋予了它很多能力。

1. Tool

对Tool可以进行分类如下

分类

举例

文件与执行

read, write, edit, apply_patch, exec, process

session相关

sessions_list, sessions_history, sessions_send, sessions_spawn, session_status, agents_list

Web和UI自动化

web_search, web_fetch, browser canvas

设备和节点

nodes, cron, gateway

记忆

memory_search, memory_get

多模态

image

2. Skill

网上看到的openclaw接管Macmini帮用户做杂七杂八的事(比如写备忘录)基本都是通过Skill完成的,内置的Skill可以按照功能分类如下

分类

举例

效率和自动化

tmux, healthcheck, coding-agent, skill-creator, session-logs, clawhub, 1password

开发

github, gog, sag, gemini, eightctl, mcporter, model-usage, summarize

沟通

discord, slack, imsg, bluebubbles, wacli, voice-call

笔记

apple-notes, bear-notes, obsidian, notion, trello, apple-reminders, things-mac

媒体

openai-image-gen, nano-banana-pro, nano-pdf, openai-whisper, openai-whisper-api, sherpa-onnx-tts, video-frames, camsnap, canvas, gifgrep

本地生活

weather, local-places, goplaces, food-order, ordercli, openhue, blogwatcher

娱乐

spotify-player, sonoscli, songsee, bird, peekaboo, blucli, himalaya, oracle

04 跨会话的Memory

1. memory文件

在System Prompt中的memory:如前文所讲, MEMORY.md / memory.md会默认作为 contextFiles 被注入到system prompt。

跨session memory存储在<workspace>/memory/YYYY-MM-DD.md

  • agent主动写入:当用户说“请记住...”,agent可能会使用write工具写入<workspace>/memory/YYYY-MM-DD.md

  • 被动记录:当触发新会话时,session-memory hook 会把最近会话保存为<workspace>/memory/YYYY-MM-DD.md

  • 压缩前记录memory: 见压缩一节的silent memory flush机制。

2. chunks表里的memory

OpenClaw用了sqlite存储chunk用于RAG

CREATETABLE chunks(
id TEXT PRIMARYKEY,
path TEXT,
source TEXT,
start_line INTEGER,
end_line INTEGER,
hash TEXT,
model TEXT,-- 嵌入模型
textTEXT,
embedding TEXT,-- JSON 数组
updated_at INTEGER
);

监听到memory文件夹变化的时候,会写入chunks表。此外还存在往chunks表定时同步的机制。

3. memory相关工具

memory_search工具可以使用RAG的方式搜索memory,

{
"name":"memory_search",
"description":"Mandatory recall step: semantically search MEMORY.md + memory/*.md before answering questions about prior work, decisions, dates, people, preferences, or todos",
"parameters":{
"query":"What did we decide about the API?",
"maxResults":6,
"minScore":0.35}
}

混合搜索:混合搜索是个实验特性,可以通过RAG+BM2.5两种方式共同搜索memory,取topK然后打分合并结果。具体合并策略可以看官方文档里的合并策略.

memory_get可以选择读取memory文件的部分内容(比如部分行)

{
"name":"memory_get",
"description":"Read specific lines from a memory file after memory_search",
"parameters":{
"path":"memory/2026-01-20.md",
"from":45,
"lines":15}
}

05 一些想法

整体来看,OpenClaw是对Code Agent的包装,Code Agent本身可以接管你的电脑,而它给Code Agent外接了更多工具。它实现了统一的往IM工具建立信道的协议,让用户可以通过聊天软件远程遥控它。同时也通过一些比较简单的人设定义文本(contextFiles)和memory机制,让OpenClaw跟用户聊天的时候更丝滑。

此外,作者可能是Anthropic的粉丝,比如在Safety一节,提到了遵循Anthropic的一些安全约定。

References

openclaw/openclaw - Githubgithub.com/openclaw/openclaw

badlogic/pi-mono - Githubgithub.com/badlogic/pi-mono

openclaw Documentdocs.openclaw.ai/

steipete.me/posts

How Clawdbot Remembers Everythingmanthanguptaa.in/posts/clawdbot_memory/