跳转到内容

第 18 课:Runtime Services

阅读 Pi 的 createAgentSessionServices、runtime factory、session replacement 和 cwd-bound services 设计。

Runtime Services 是 Pi 把 CLI、SDK、print mode、interactive mode 和 RPC mode 统一起来的边界层。它为当前有效工作区创建一组 cwd-bound services,再基于这些 services 创建 session;当用户 new、resume、fork 或 import 时,runtime 替换整套 session 和 services。

runtime services 将资源、配置和 active session 重新装配的教学图

为什么不能把 resource loader、settings、model registry 和 session 都做成进程级全局单例?

  • services 是围绕当前工作区创建的一组依赖。
  • runtime factory 把宿主参数转成 services 和 session。
  • active runtime 保存当前 session、diagnostics 和替换能力。
  • session replacement 不是换一个 id,而是重建一套 cwd-bound runtime。

下面不是完整源码,而是把本课主线压缩成可以在文档里直接阅读的关键形状。读者即使不打开本地源码,也应该能看出运行时如何组织职责。

async function createRuntime(scope: RuntimeScope) {
const services = await createServices(scope);
const session = await createSessionFromServices(services);
return {
session,
diagnostics: services.diagnostics,
async switchSession(nextScope) {
const next = await createRuntime(nextScope);
this.session = next.session;
this.diagnostics = next.diagnostics;
},
};
}
  • 这段源码形状说明 runtime replacement 的关键:切换 session 时,相关 services 也要跟着重建。
  • 如果只替换 session id,却复用旧 resource loader,就会出现 stale context。
  • CLI、RPC、交互模式可以不同,但都应该共享这个 runtime 边界。

设计一个 runtime tracer 输出,记录创建、切换、diagnostics 变化和 active session 替换结果。

  • 能说明 cwd-bound services 的意义。
  • 能解释 session replacement 为什么要重建 runtime。
  • 能判断哪些对象不应该做成全局单例。
  1. 实践题:基于本课的省略版源码,补出一个最小实现草图,要求写清输入、输出、副作用和错误处理。
  2. 思考题:本课机制如果只靠 prompt 约束,而不放进 harness 或 runtime,会出现什么工程风险?