青雲的博客
深入浅出 Pi 第一部:先把 Pi 跑起来 第 03 章

启动阶段到底组装了什么

按源码中的真实顺序拆解 Pi 从参数、目标会话 cwd、运行时服务、模型与工具选项,到 AgentSessionRuntime 和 I/O 外壳的启动过程。

源码版本
v0.83.0
验证日期
Commit
845d6ff1f6643aba440341cce877ce1c43ebbc39

如果只看 main() 的长度,Pi 的启动像一串杂乱的初始化。把 ownership 放进去以后,顺序其实很严格:先找“这次要恢复或创建哪份会话”,再确定它的 cwd;配置、资源、provider 和模型都绑定到这个 cwd;这些服务准备好后才创建 AgentSession;最后,运行模式把自己的 I/O 接上去。

第一份 SettingsManager 不是最终配置

main() 开头先取进程 cwd 和 agentDir,创建一个 projectTrusted: false 的 bootstrap settings manager。它负责全局代理设置和若干启动前命令。参数解析之后,还会为会话查找创建 startup settings manager。真正绑定目标 cwd 的 runtime settings manager 要更晚才出现。

为什么要多绕一步?--session--resume 可能打开另一项目的会话。SessionManager.open() 会优先从 session header 恢复 cwd,除非调用方显式覆盖。若先拿当前 shell 的 cwd 加载 .pi/settings.json 和扩展,再恢复另一项目的 session,配置和代码就串了。

main() 因此先完成 sessionDir 与 sessionManager 选择,再读取 sessionManager.getCwd()。源码注释直接要求:目标 session cwd 未确定之前,不得解析项目设置、资源、provider 和模型。

services 先于 session

有效 cwd 确定后,createRuntime 才开始工作。它计算项目是否需要信任,创建 runtime settings manager,把 CLI 指定的扩展、skill、prompt、theme 和禁用开关交给 createAgentSessionServices()

这个函数返回的是基础设施集合:ModelRuntimeSettingsManagerResourceLoader 和 diagnostics。它先 reload 资源,再把扩展注册的 provider 交给 model runtime,最后只做本地 catalog refresh。接口注释明确说明这里还没有创建 AgentSession

服务齐备以后,main() 才解析模型范围和 session options,再调用 createAgentSessionFromServices()。返回结果连同 services、diagnostics 一起封装成 AgentSessionRuntime。同一个 runtime factory 会被保存下来,以便后续 /new/resume/fork 或 import 切换 cwd 时重建整套绑定关系。

flowchart TD
    accTitle: Pi 启动组装顺序
    accDescr: 参数和会话选择先确定目标 cwd,随后解析信任并创建 cwd 绑定服务,再解析模型工具选项、构造 AgentSessionRuntime,最后接入具体运行模式。
    ARGS["Args + TTY"] --> MODE["AppMode"]
    ARGS --> TARGET["SessionManager"]
    TARGET --> CWD["effective session cwd"]
    CWD --> TRUST["project trust"]
    TRUST --> SERVICES["Settings + Resources + ModelRuntime"]
    SERVICES --> OPTIONS["model / thinking / tools"]
    OPTIONS --> SESSION["AgentSession"]
    SESSION --> RUNTIME["AgentSessionRuntime"]
    RUNTIME --> IO["Interactive / Print / JSON / RPC"]

这份启动主干可以用一条只读命令复查:

repo="${PI_SOURCE_DIR:-/tmp/pi-handbook-qbQTcA}"
git -C "$repo" show v0.83.0:packages/coding-agent/src/main.ts |
  nl -ba | sed -n '620,729p;741,800p;868,914p'

图中最需要继续拆开的,是 TRUST -> SERVICES 这一段。配置并不只有一个文件,资源也不只是 skills;项目内容能否进入进程,还取决于信任状态。下一章专门处理这条边界。