分析范围:Kimi code 仅基于
packages/agent-core-v2;Pi 基于packages/agent与packages/coding-agent的主执行链路。
祝贺 Kimi K3 发布,让中国开源模型走向下一个阶段。
1. 引言与术语
Pi 和 Kimi code 都提供模型、工具、上下文、调度、持久化和交互能力,却选择了不同的组织方式:Pi 是容易嵌入的状态机,Kimi code 是分作用域、可恢复的调度内核。
两套代码对 Turn 的定义不同。本文使用三个中性术语进行比较:
| 中性概念 | Pi | Kimi code |
|---|---|---|
| Conversation:长期对话与工作历史 | Session / Agent transcript | Session / Context Memory |
| Job:一项需要独立处理的任务 | 通常是一次 Agent run | Turn |
| Model round:一次 LLM 请求及工具处理 | Turn | Step |
Pi 的 Turn 是一次 Assistant 响应及其工具调用;Kimi 的 Turn 可以包含多个 Step,更接近完整任务。
2. 两套 Harness 全景
2.1 Pi:状态机外包一层产品编排

Pi 分为三层:runLoop() 执行模型与工具循环;Agent 保存 transcript、消息队列和运行状态;AgentSession 增加 Extension、持久化、重试和压缩。
调用链是 AgentSession → Agent → runLoop()。中间的 Agent 不是另一个循环,而是连接内外两层的状态容器:内层 runLoop() 处理正常执行,外层 AgentSession 在一次 run 结束后决定是否调用 agent.continue()。
2.2 Kimi code:分 Scope 的调度内核

Kimi code 将生命周期分为 App、Session 和 Agent Scope。每个 Agent 拥有 Loop、Context、Tool、Wire 和 EventBus。Prompt、Goal、后台 Task、重试和压缩等模块生成 StepRequest,再由 Loop 统一调度。
两套设计的核心差异由此出现:Pi 用控制流组织 Agent,Kimi code 用工作请求组织 Agent。
3. 控制模型:控制流与 StepRequest
3.1 Pi:下一步写在循环条件中
Pi 的主循环直接理解业务含义:
模型调用工具 → 执行工具 → 再请求模型
出现 steering → 下一轮前注入 → 再请求模型
准备停止但有 follow-up → 注入消息 → 再请求模型
工具调用、steering queue、follow-up queue 和停止回调共同决定循环是否继续。正常路径集中在一个函数里,控制流直观,但 Loop 需要理解每种续跑原因。
3.2 Kimi:下一步成为工作请求
Kimi 将续跑原因转换成统一的 StepRequest:
| 原因 | 表达方式 |
|---|---|
| 用户开始任务 | PromptStepRequest |
| 工具执行完毕 | ContinuationStepRequest |
| 用户修正当前任务 | SteerStepRequest |
| 瞬时错误 | 失败请求重新入队 |
| Context overflow | 压缩后重新入队 |
| Goal 或 Hook 要求继续 | 相应的 continuation request |
这里的“续跑”是指当前 Model round 结束后,因为工具结果、错误恢复或用户补充而再次调用 LLM。Loop 只负责排空队列,“为什么继续”由请求生产者决定。
Pi 新增续跑原因,通常需要增加控制分支或外层处理;Kimi 新增续跑原因,通常只需增加一种 StepRequest 生产者。前者降低了理解成本,后者降低了扩展调度策略的成本。
4. 任务边界与并发输入
4.1 Pi:围绕一个 active run 排队
Pi 同时只允许一个 active run。运行期间再次调用 prompt() 会报错,调用方必须选择:
steer():当前工具 batch 完成后,尽快修正正在执行的任务。followUp():当前任务原本准备停止时,再处理这条消息。
Pi 没有 pending run,也不会为后续消息预留独立 ID、取消信号和结果 Promise。两类消息都围绕当前 run 运转。
4.2 Kimi:先确定工作属于哪个 Turn
Kimi 将 Job 建模为 Turn。每个 Turn 创建时就获得 ID、状态、取消通道、结果 Promise 和独立队列。一个 Agent 只有一个 active Turn,但可以有多个 pending Turn。
StepRequest 通过 admission 声明归属:
| admission | 语义 |
|---|---|
newTurn | 创建独立 Turn |
activeOrNewTurn | 加入当前 Turn;空闲时创建 Turn |
activeOrNextTurn | 加入当前 Turn;空闲时等待下一个 Turn |
activeTurnOnly | 只能加入正在执行的 Turn |
例如,用户在 Agent 工作时输入“不要修改公开 API”,它可以作为 steer 加入当前 Turn;“完成后再补测试”通常先成为 pending Prompt,之后创建新 Turn。
Pi 主要决定消息何时进入当前控制流;Kimi 还要决定工作由哪个可结算 Job 所有。
5. 错误恢复:Loop 外与 Loop 内
5.1 Pi:结束 run 后恢复
Pi 通常将请求失败编码为 stopReason: "error" 的 Assistant message,随后结束低层 run。AgentSession 再检查结果:
可重试错误 → 退避 → agent.continue()
Context overflow → 压缩 → agent.continue()
agent_end 后出现新消息 → agent.continue()
一次产品任务因此可能跨越多个 Agent run。低层 Loop 保持简单,但完整控制流分布在 runLoop() 和 AgentSession 两层。
5.2 Kimi:在当前 Turn 内恢复
Kimi 将 Step 错误交给恢复模块。重试模块经过退避后把失败请求放回队首;压缩模块缩减 Context 后重新入队。恢复成功时,调用方看到的仍是同一个 Turn。
Kimi 用同一套队列处理正常续跑和异常恢复,但恢复模块必须在认领错误后安排下一 Step。
6. 状态、事件与持久化
6.1 Pi:统一的 awaited event stream
Pi 用一条 AgentEvent 流描述 Agent、Turn、Message 和 Tool 的生命周期。Agent 先根据事件更新内存状态,再依次等待 listener;AgentSession 通过 listener 转发 Extension 事件、持久化消息并通知 UI。
持久化属于宿主层:低层 Agent 先产生消息,AgentSession 再将 message_end 写入 SessionManager。这个模型容易嵌入,也保证事件与状态顺序一致;代价是慢 listener 会直接阻塞执行。
6.2 Kimi:三种机制分担职责
| 机制 | 职责 |
|---|---|
| Wire | 状态操作、Reducer、JSONL journal、恢复与迁移 |
| EventBus | 向 UI、transport 和遥测广播事实 |
| Ordered Hook | 有序介入 Step 生命周期,修改控制决策 |
Kimi 通过 Wire Op 更新内存模型并追加 journal,需要时再派生 EventBus 事件。必须影响下一 Step 的逻辑使用 Ordered Hook,而不是普通事件订阅。
因此,Pi 是“Agent 先运行,宿主记录结果”;Kimi 是“Agent 通过可记录的状态操作运行”。前者更轻,后者更适合恢复、迁移和多客户端同步。
7. 工具与 Context
7.1 工具执行
Pi 将工具执行和续跑放在同一个低层 Loop。一次 Assistant message 的工具组成一个 batch,执行结果写入 Context 后,Loop 直接判断是否再请求模型。
Kimi 将两项职责分开:ToolExecutor 执行工具,LoopContinuationService 在 after-step Hook 中决定是否提交 ContinuationStepRequest。Pi 的工具链更内聚,Kimi 的执行与调度边界更清晰。
7.2 Context 管理
Pi 在每次请求前通过 transformContext() 生成临时视图,再由 convertToLlm() 转换为供应商消息。持久压缩主要由 AgentSession 在 run 结束后完成。
Kimi 的 StepRequest 在真正出队时才把消息写入 Context,取消的排队请求不会污染历史。压缩既可以在 Step 前主动进行,也可以在 overflow 后恢复失败请求。
两者都区分请求视图和长期历史;Kimi 进一步将 Context 写入纳入调度过程:排队不等于提交,消费请求时才改变历史。
8. 架构取舍与结论
Pi 优先降低概念数量和嵌入成本,适合本地 CLI、单 active Agent,以及以工具和消息扩展为主的场景。它的复杂性主要留在宿主层:产品能力增多时,AgentSession 会逐渐承担第二套编排逻辑。
Kimi 优先处理运行时治理,适合多入口、多输入来源、长期任务和可恢复状态。它通过 Turn、StepRequest、Wire 和 Scope 统一编排,但也增加了 admission、队列和跨模块 Hook 的认知成本。
两条路线可以概括为:
Pi:简单内核 → 宿主逐层增强
Kimi:通用内核 → 业务模块按协议组合
两者的区别不在于是否支持工具调用,而在于如何表示尚未完成的工作:Pi 将它保留在运行状态中,有工具或消息就继续;Kimi 将它放入显式队列,每个继续原因都成为工作请求。
因此,Pi 更像一台透明、紧凑的 Agent 状态机;Kimi code 更像一个可调度、可恢复的 Agent 运行时内核。选择哪种设计,取决于系统的主要复杂性来自单个 Agent 的推理链,还是来自多个输入、生命周期和恢复策略之间的协调。