OpenClaw 的框架内核:Pi

在 AI Agent 领域,大家很容易陷入一种“堆料”思路:工具越来越多,配置越来越复杂,系统越来越像一台难以维护的巨型机器。 Pi 反其道而行。它选择做减法,把框架压缩到最小,只保留真正必要的部分。 它的核心设计理念,可以概括成一句话: 一个调用 LLM 的 while 循环,加上四个基础工具。 Pi 是一个极简、可扩展的 AI 编码智能体框架(harness)。它并不试图替模型“想太多”,而是默认一个前提:像 Claude Sonnet 这样的模型,本身已经具备足够强的推理与规划能力。框架真正要做的,不是替它设计复杂工作流,而是给它一个稳定、清晰、低摩擦的执行环境。 这也是 OpenClaw 建立在 Pi 之上后依然能保持高效的原因。它强大,不是因为设计复杂,而是因为设计克制。 一句话理解 Pi 如果要用最通俗的话解释 Pi,可以把它理解为: 用户提出任务。 LLM 决定下一步要做什么。 框架执行工具调用,并把结果返回给 LLM。 重复这个过程,直到任务完成。 也就是说,Pi 的本质并不是一套庞大的 Agent 基础设施,而是一个非常稳定的“对话 - 执行 - 反馈”循环。 核心循环:Pi 如何驱动一个 Agent 下面这段代码,基本就是 Pi 的核心运行方式: // 外层循环:处理后续消息队列 while (true) { let hasMoreToolCalls = true; let steeringAfterTools: AgentMessage[] | null = null; // 内层循环:处理工具调用和转向消息 while (hasMoreToolCalls || pendingMessages.length > 0) { // 1. 处理待处理消息(用户新输入或转向消息) if (pendingMessages.length > 0) { for (const message of pendingMessages) { currentContext.messages.push(message); } pendingMessages = []; } // 2. 调用LLM获取响应 const message = await streamAssistantResponse(currentContext, config, signal, stream); // 3. 检查是否有工具调用 const toolCalls = message.content.filter((c) => c.type === "toolCall"); hasMoreToolCalls = toolCalls.length > 0; // 4. 执行工具调用 if (hasMoreToolCalls) { const toolExecution = await executeToolCalls( currentContext.tools, message, signal, stream, config.getSteeringMessages ); // 工具结果会作为新消息加入上下文 for (const result of toolExecution.toolResults) { currentContext.messages.push(result); } } // 5. 检查转向消息(实时干预) pendingMessages = (await config.getSteeringMessages?.()) || []; } // 6. 检查后续消息队列 const followUpMessages = (await config.getFollowUpMessages?.()) || []; if (followUpMessages.length > 0) { pendingMessages = followUpMessages; continue; // 继续外层循环 } break; // 没有更多消息,结束 } 这个循环看上去朴素,但正是 Pi 的关键。 ...

March 8, 2026 · Ethan

2025,让一切,流动

我并不期望人生过的顺利,但我希望碰到人生难关的时候,自己可以是他的对手。 —— 加缪 回顾 2025,我很难用“成果”或“进展”来概括这一年。相比于向某个清晰目标逼近,这一年更像是在不断校准自身状态与理解方式。我逐渐意识到,真正困扰我的,并不是事情是否按计划发生,而是当计划失效时,我是否仍然具备应对的能力。 ...

January 4, 2026 · Ethan

在熵增的世界,我放弃了寻找确定性

熵增是永恒的宿命,与其在不确定的洪流中执意追寻确定,不如向内深耕自我,随势流转,随心而行。 引子 九月,我做了一个重要的决定:离开小红书,开启我的下一站旅程。这个决定,源于我不再想追寻那份看似忽远忽近的确定性,而是渴望去丰富自己的经历、提升自己的认知,从而有能力去抵抗这个熵增世界所带来的不确定。 说起来,这篇博客本该在六月就完成,承接年初的总结,聊聊近况。但因种种缘由,稿子只起了个头,便一直在草稿箱里静静积灰。 没想到,这次离职反而给了我一段完全属于自己的时间,正好可以把这个“坑”填上。因此,这篇文章算是一份特别的“二合一”:既是迟到的年中复盘,也是新鲜出炉的碎碎念。我想借这个机会,好好回顾这段旅程,也和大家聊聊我近来的所思所想。 红薯地的这两年 时间拨回到两年前的国庆。23年10月,我接到了小红书的意向书,和HR聊完具体的薪资后,几乎没怎么犹豫就签署了offer。为了早点进入状态,熟悉业务,我选择了火速入职,提前实习。我还清晰的记得,入职第一天,负责我的HR同学打趣地说:“你是今年入职最早的校招生。”。 总觉得时光飞逝,许多画面还历历在目,但现实却是,满打满算,我已经在“红薯地”中成长了两年。这两年,说好听一点,我履历丰富,经历了几乎所有的大厂特色项目:业务方向调整,高强高压的Feature上线,跨多团队的业务协作,以及飞“锅”漫天的精彩场面。这趟旅程算不上完美,但却足够丰富。如果不好好复盘消化,把这些经历提炼成自己的成长,那可真是有些暴殄天物了。 下面,我就罗列几点,我的复盘和成长。 看见“价值”,构建自己价值评判体系 曾经,我对一件事“价值”的判断,很像是在对照一份“价目表”。读个好学校的研究生,值多少分;发一篇顶会论文,值多少分;拿到一个大厂的offer,又值多少分。这份“价目表”由社会共识、前辈经验、主流声音共同构成。我曾是它忠实的拥趸,被动地接受着上面的标价,却从未深究过定价的逻辑。 这并非说我如今质疑这些选择的价值,而是我意识到,它们并非经由我独立思辨、真正内化于心的结论。我只是在沿着一条看起来最稳妥、最多人走的轨迹前行,追求一种“标准答案”式的成功。 而在红薯地的这两年,尤其是在业务一线炮火的洗礼中,这种被动接受的惯性被彻底打破了。在这里,你常常需要去做一件没人做过、没有“标准答案”的事,然后你必须清晰地论证出它的价值,去说服你的老板、你的同事也认可这份价值。我一下子失去了可以参照的“价目表”,这反而逼着我不断地向内拷问自己:“我为什么要做这件事?它的核心价值是什么?它能为用户、为业务带来什么?” 为了回答这些问题,我必须去挖掘更多的信息,去理解业务的逻辑,去洞察用户的需求,去结合产品的生态。这个过程,就像是在一片迷雾中,亲手建立起属于自己的灯塔和坐标系。 这种转变,最直接地体现在我对OKR的理解和对业务的判断上。我不再是一个被动接单、按部就班的“执行者”,而开始学着去拆解老板的目标,主动思考和定义问题,成为一个“规划者”。我开始明白,真正的价值,不是来自外界的标价,而是源于你对事物本质的理解和独立判断后,所产生的那份笃定。 从“独行侠”到“集团军”,拥抱集体智慧 坦白说,我骨子里是个喜欢单打独斗的人,一个典型的“独行侠”。我享受那种从0到1,一切尽在掌控的感觉,并认为这是最高效、沟通成本最低的方式。 然而,在大厂的复杂战场上,个人英雄主义很快就会碰壁,你必须学会“集团作战”。 一个在用户看来或许只是“点一下”的简单功能,其背后可能是一张庞大而紧密的协作网络:产品经理的敏锐洞察,设计师的精心设计,前端、后端、算法工程师的代码实现与优化,测试同学的稳定保障,还有运营同学的推广策略……每个环节都环环相扣,缺一不可。 它要求你必须具备通盘的大局观,主动去拉通上下游,为各种不确定性预留足够的buffer,而不是抱着“自扫门前雪”的态度,守着自己的一亩三分地。 更重要的是,我意识到,“独行”的效率是一种短视的假象。每个人的精力、知识和视野都是有限的。你不可能在每个领域都成为专家。试图掌控一切,最终只会被无穷的细节淹没,筋疲力尽。而“集团作战”的精髓,恰恰在于信任并借助他人的专业性,将每个人的优势拧成一股绳,去攻克单枪匹马无法企及的高地。 这不是简单的任务分配,而是基于共同目标,互相补位、彼此成就的化学反应。 学会拥抱集体智慧,从欣赏个人能力,到敬佩团队的力量,这是我在小红书学到的,关于“做事”的另一堂重要课程。 生活碎碎念 聊完工作,我想再谈谈对生活本身的一些感悟。 从小,我被灌输的人生观和事业观,都与“稳定”二字牢牢绑定。那是一条清晰的人生轨迹:考个好就业的专业,进一家安稳的大公司,在一个岗位上做到退休。我曾以为,只要按部就班,就能收获安稳的人生。 然而,不知从何时起,这个信念开始动摇了。一方面,是性格里总有些不安分,喜欢在安逸中寻找新的可能性;但更重要的,是时代本身的变化——我们早已告别了那个一份工作可以干一辈子的时代。 世界正变得日益复杂和不确定,社会这部机器的运转也在加速,变化与重组成为常态。这股趋势我们无法抗拒。既然如此,与其被动地被浪潮推动,不如主动投身其中,在变化中寻找新的方向和机会。 这也是驱使我离开小红书的原因之一。我想跳出熟悉的环境,去亲身探寻:在不同的商业模式下,一个产品是如何从零到一、再到持续成长的;去理解成功背后更底层的第一性原理,而不仅仅是学习表面的方法;去在更丰富的实践中锻炼自己,建立一种不依赖于任何平台、真正属于自己的核心能力。 归根结底,我想在自己身上做一场实验。 这场实验的核心假设是:人生并非只有一条预设的轨道,它更像一片广阔的原野,处处都是值得探索的路径。 为了验证这个假设,我开始主动结识不同行业的朋友,去各地体验真实的生活,并在实践中反复审视自己过去的认知。我发现,这些看似分散精力的探索,非但没有影响本职工作,反而让我在宏观与微观两个维度上,对社会运转有了更深刻的理解,也建立起一个更全面、立体的价值体系。 这让我更加笃定,我的假设是正确的。 最后,我想借用《冈仁波齐》电影结尾的话来收尾: 这个世界上没有什么生活方式是完全正确的,神山圣湖不是终点,接受平凡的自我,但不放弃理想和信仰,热爱生活,我们都在路上,也许路的尽头是什么从来都不重要。

October 6, 2025 · Ethan

2024, Not bad.

Warning:这是一个矫情的、敏感的双鱼男的自述,带有强烈的个人主观情感偏见。 TL;DR 小时候,我常说:“我想做这个,我想做那个。”,长大了,我却常说:“我不能做这个,我不能做那个。” 细想这些所谓的"不能",其实并非真的不能,而是被现实的种种条件所束缚,失去了选择的自由。 但是,当生存不再是困扰,那我便有了选择的自由。 我选择不再将多余的精力用来追求更富足的物质生活,而是去探索人生的旷野,去寻找那条属于我的路,通向那扇独属于我的窄门。 这条路或许荆棘遍布,或许人迹罕至,但我深信,穿越艰难后的风景,必将美不胜收。 一个人应该能够换尿布,策划战争,杀猪,开船,设计房子,写十四行诗,结算账户,砌墙,接脱臼的骨头,安慰濒死的人,服从命令,发布命令,携手合作,独立行动,解数学方程,分析新问题,铲粪,电脑编程,做出可口的饭,善打架,勇敢地死去。只有昆虫才专业化。 — 罗伯特海因莱因,《时间足够爱你》 序言 转眼间又到年末,像往常一样,不自觉地开始回顾这一年。划着手机相册,从一月滑到十二月,一直翻到昨天,点点滴滴的记忆涌上心头。 ...

December 30, 2024 · Ethan

Policy-gradient Algorithem

Intro Policy-gradient 算法是无模型强化学习算法中的一种,也是Actor-Critic 算法中的Actor。 REINFORCE算法是一个比较基础的 算法 学习目标 Policy-gradient 的目标函数定义如下: $$ \begin{equation} J(\theta)=\mathbb{E}[\sum_{t=0}^{T-1}r_{t+1}] \end{equation} $$ 它表示希望学习一个policy能够最大化累计未来回报(cumulative future reward)。 $r_{t+1}$表示在状态 $s_t$时采取动作 $a_t$从环境中获得的回报。 $r_{t+1} = R(s_t,a_t)$, $R(\cdot)$表示回报函数(reward function) 因为这是个最大化问题,所以可以使用梯度上升来优化policy。 $$ \begin{equation} \theta = \theta + \frac{\delta}{\delta \theta}J(\theta) \end{equation} $$ Policy 一般会使用神经网络进行参数化。 期望(Expection) 在文献中经常出现的是期望符号——之所以使用它,是因为我们想要优化长期未来(预测的)奖励,而这有一定的不确定性。 期望值,也称为期望值或平均值,是通过每个x值及其概率的乘积之和来计算的。 $$ \begin{equation} \mathbb{E}[f(x)] = \sum_{x}P(x)f(x) \end{equation} $$ $P(x)$代表随机变量 $x$出现的概率, $f(x)$代表 $x$的值。 推导策略梯度 我们根据先前定义的目标函数,我们可以将期望项进行展开: $$ \begin{equation} \begin{split} J(\theta) &= \mathbb{E}[\sum_{t=0}^{T-1}r_{t+1}|\pi_{\theta}] \\ &= \sum_{t=i}^{T-1} P(s_t,a_t|\tau)r_{t+1} \end{split} \end{equation} $$ 其中 $i$是轨迹 $\tau$中的任意一个起始点, $P(s_t,a_t|\tau)$是在给定轨迹 $\tau$时,出现 $s_t,a_t$的概率。 对两边同时对policy的参数 $\theta$求导: $$ \begin{equation} \begin{split} \nabla_{\theta}J(\theta) &= \sum_{t=i}^{T-1}\nabla_{\theta}P(s_t,a_t|\tau)r_{t+1} \\ &=\sum_{t=i}^{T-1}P(s_t,a_t|\tau)\frac{\nabla_{\theta}P(s_t,a_t|\tau)}{P(s_t,a_t|\tau)} r_{t+1} \\ &=\sum_{t=i}^{T-1}P(s_t,a_t|\tau)\nabla_{\theta}\log{P(s_t,a_t|\tau)}r_{t+1} \\ & = \mathbb{E}[\sum_{t=i}^{T-1}\nabla_{\theta}\log{P(s_t,a_t|\tau)r_{t+1}}] \end{split} \end{equation} $$ ...

October 21, 2024 · 164 words · Ethan