00 Agent 基础概念学习记录
这一章是给第一遍学习 Pi agent 的前置缓冲层。目标不是读源码,而是先把几个核心词讲清楚:LLM、Context、toolCall、toolResult、agent loop、session。
本章一句话
agent 不是“问模型一次”。agent 是一个循环:把上下文交给模型,模型可能返回文本,也可能返回 toolCall;本地执行工具后把 toolResult 回填上下文,再让模型继续推理,直到没有下一步动作。
为什么要有 00 章
如果直接从 01 的 CLI 入口开始,很多概念会混在一起:
- 模型返回 toolCall,但工具并没有自动执行。
- 工具执行结果是 Pi 本地知道的,模型还不知道。
- 上下文不是完整磁盘历史,而是本轮要发给模型的输入。
- session 不是 UI 记录,而是恢复、分支、压缩和审计的基础。
packages/ai、packages/agent、packages/coding-agent是不同层。
00 章先建立这些词的边界,后面读源码会更稳。
基础词表
LLM
LLM 是模型本身。它接收一批输入消息和工具描述,然后输出文本、思考片段或 tool call。
在 Pi 里,模型不是直接面对 CLI、TUI、session 文件或扩展系统。它看到的是 provider adapter 转换后的请求。
Context
Context 是 Pi 发给 provider 的统一模型请求格式,可以理解为“本轮模型调用的输入包”。
核心内容:
systemPromptmessagestools
Context 不是磁盘上的完整 session,也不是 UI transcript。它是 agent 根据当前状态整理出来、准备交给模型的一次输入。
toolCall
toolCall 是模型提出的动作请求,比如:
我要调用 read(path="README.md")
它只表示模型想调用工具,不表示工具已经执行。尤其在流式输出里,tool call 参数可能是逐段生成的,必须等参数完整后才能校验和执行。
toolResult
toolResult 是 Pi 本地执行工具后的结果,比如:
README.md 的内容是 ...
模型不会天然知道这个结果。Pi 必须把 toolResult 回填进上下文,模型下一轮才能基于观察结果继续推理。
agent loop
agent loop 是把模型和工具串起来的执行循环。
极简版:
while (true) {
const assistant = await model(context);
context.messages.push(assistant);
if (!assistant.toolCalls.length) break;
const results = await executeTools(assistant.toolCalls);
context.messages.push(...results);
}
真实 Pi 里还会多出 streaming、hooks、steering、follow-up、abort、terminate、parallel/sequential tools、session 持久化等逻辑。
session
session 保存一次长期对话的历史。它不只保存用户和 assistant 文本,也保存 toolResult、分支、压缩等信息。
如果只保存 assistant 的 toolCall,不保存 toolResult,恢复后模型就不知道工具实际返回了什么,历史会断。
普通聊天 vs agent
普通聊天:
user -> model -> assistant text
agent:
user -> agent -> model -> toolCall -> local tool -> toolResult -> model -> final text
区别在于:agent 有本地动作、外部观察结果和循环状态。
主线图
flowchart TD
U[用户输入] --> S[AgentSession]
S --> L[Agent loop]
L --> M[模型]
M -->|text| R[最终回答]
M -->|toolCall| T[本地工具]
T --> TR[toolResult]
TR --> L
Pi 的三层结构
packages/ai
模型/provider 层。
负责:
- 定义统一 Context。
- 接 OpenAI/Anthropic/Google 等 provider。
- 把 provider stream 转成 Pi 统一事件。
不负责:
- CLI 怎么显示。
- session 文件怎么写。
- 工具如何持久化历史。
packages/agent
通用 agent runtime。
负责:
- 保存 agent 内存状态。
- 调用模型。
- 识别 tool call。
- 执行工具。
- 回填 toolResult。
- 判断是否继续下一轮。
不负责:
- coding agent 的具体产品能力。
/tree、skill、extension UI。
packages/coding-agent
Pi 产品层。
负责:
- CLI/interactive/json/RPC/SDK 外壳。
- 默认工具
read/edit/write/bash。 AgentSession。- session、compaction、skills、extensions。
- 把通用 agent runtime 变成 coding agent。
常见误解
误解 1:toolCall 等于工具已经执行
不对。toolCall 是模型请求。真正执行发生在本地 agent loop 里。
误解 2:toolResult 是给 UI 看的日志
不对。toolResult 是模型下一步推理的必要上下文。UI 可以展示它,但它最重要的作用是回填给模型。
误解 3:Context 就是完整 session
不对。session 是历史存储;Context 是本轮要交给模型的输入视图。
误解 4:AgentSession 和 Agent 是一回事
不对。AgentSession 是产品会话层,Agent 是运行控制器,agent loop 是执行引擎。
自测题
- 为什么 agent 不是普通聊天?
- toolCall 和 toolResult 的区别是什么?
- 为什么工具结果必须回填上下文?
- Context 和 session 的区别是什么?
packages/ai、packages/agent、packages/coding-agent分别负责什么?
本章验收
学完 00 后,应该能说清:
- 模型只提出 toolCall,本地 agent loop 才执行工具。
- toolResult 是工具返回给模型继续推理的观察结果。
- agent loop 会反复“模型生成、工具执行、结果回填”。
- session 是长期历史,Context 是本轮模型输入。
- Pi 的源码可以先按 ai、agent、coding-agent 三层去看。
下一章
进入 01:先把 Pi 跑起来,观察一次真实 prompt 如何从 CLI 进入 AgentSession、Agent 和 runAgentLoop()。
Source: 00-agent-basics-notes.md