Agent Hook 系统对比

Pi 三层 Hook vs LangChain Callback

技术架构白皮书 · 2026年6月

执行摘要
Pi 和 LangChain 采用截然不同的 Agent 事件系统设计:Pi 使用三层 Hook 架构(Agent Loop + Agent Event + Harness/Extension),支持 block/patch/cancel 语义;LangChain 使用 Mixin-Based 的 Callback 系统,纯只读观测。本文档从架构设计、ReAct Loop 映射、修改能力、扩展性四个维度进行系统性对比,揭示两种设计哲学背后的权衡与适用场景。

一、架构设计对比

1.1 核心架构

维度PiLangChain
架构模式 三层分层 Hook Mixin-Based 回调
核心抽象 Agent Loop 回调 + AgentEvent 流 + HookEvent 拦截 BaseCallbackHandler (Mixin 继承链)
类型系统 TypeScript + Phantom Type (HookResult) Python Mixin + 鸭子类型
执行模型 同步/异步混合,返回值参与控制流 异步聚合,回调并行执行
错误处理 Hook 可 block,错误可传播 错误隔离,一个 handler 崩溃不影响其他

1.2 层级对应关系

关键发现:LangChain 的 Callback 系统 只对应 Pi 的 Agent 事件层(只读观测),没有 Agent Loop 层和 Harness/Extension 层的等价物。
Pi 层级能力LangChain 等价物差距
Agent Loop 层 函数回调,直接参与执行逻辑
可 block 工具、修改消息、决定停止
LangChain 没有执行控制点
Agent 事件层 只读事件流,状态同步、UI 更新 BaseCallbackHandler 等价,但 Pi 的事件粒度更细
Harness/Extension 层 类型安全拦截,block/patch/cancel LangChain 无法拦截执行

二、ReAct Loop 事件映射对比

2.1 事件触发时机对比

ReAct 阶段Pi 事件LangChain 事件
整轮开始 agent_start, before_agent_start on_chain_start
LLM 请求 message_start, message_update × N, message_end on_llm_start, on_llm_new_token × N, on_llm_end
工具调用 beforeToolCall, tool_execution_start/end, afterToolCall on_agent_action, on_tool_start, on_tool_end
Agent 完成 agent_end, turn_end on_agent_finish, on_chain_end

2.2 关键差异

Pi 优势
LangChain 优势

三、修改能力对比

3.1 核心能力矩阵

操作PiLangChain
修改 System Prompt before_agent_start 返回新 systemPrompt ❌ 无法修改
修改进入 LLM 的消息 context / transformContext 替换 messages ❌ 无法修改
阻断工具调用 beforeToolCall / tool_call 返回 { block: true } ❌ 无法阻断
修改工具结果 afterToolCall / tool_result patch 结果 ❌ 无法修改
修改 LLM 请求参数 before_provider_request 修改 model/streamOptions ❌ 无法修改
修改流式 Token ⚠️ 不支持(设计上 AssistantMessage 不可修改) ❌ 不支持
决定循环终止 shouldStopAfterTurn 返回 boolean ❌ 无法控制
观测执行流程 ✅ Agent 事件层 observe() ✅ 所有回调都是观测

3.2 设计哲学差异

Pi:"执行前/中/后的拦截与修改" —— 精细化控制 Agent 行为
LangChain:"执行后的观测与记录" —— 追踪 Agent 行为

四、扩展性对比

4.1 Extension / 自定义 Handler

维度Pi ExtensionLangChain Custom Handler
注册方式 文件系统扫描 extensions/ 目录 代码中实例化并传入 callbacks=[...]
生命周期 随 Session 持久化,重启后自动加载 随代码实例化,每次调用独立
注册工具 pi.registerTool() ✅ 通过 tools=[...] 传入
注册命令 pi.registerCommand() ❌ 无内置命令系统
UI 交互 ctx.ui.select/confirm/input ❌ 无 UI 系统
类型安全 Phantom Type + 泛型约束 Python 鸭子类型
错误隔离 Extension 错误不破坏核心 Handler 错误不破坏其他 handler

4.2 沙盒性对比

Pi Extension 沙盒
LangChain Handler 自由度

五、适用场景对比

5.1 选择 Pi 的场景

5.2 选择 LangChain 的场景

六、一句话总结

Pi = 拦截与修改框架:告诉你"发生了什么",还能决定"接下来发生什么"。

LangChain Callback = 观测与追踪框架:告诉你"发生了什么",但无法影响"接下来发生什么"。

两者不是竞争关系,而是互补:LangChain 适合观测和追踪,Pi 适合控制和扩展。在实际项目中,可以根据需求选择或组合使用。