aps-agent/docs/adr/0006-engine-as-subprocess.md

2.9 KiB
Raw Permalink Blame History

ADR-0006:引擎以长驻子进程运行

  • 状态:已接受
  • 日期:2026-09-23
  • 决策人:技术负责人
  • 相关:任务表 A3(决策 D10);设计文档《架构设计》5.1、5.2

背景

平台需要一个智能体循环来理解意图、挑工具、解释结果。这一循环跑在哪,决定了三件事:故障隔离、进程模型的复杂度、以及工具怎么交给引擎。

两项事实约束着选择:Codex 是 Rust 二进制,只能以子进程驱动,无法进程内嵌入;Pi 提供两种形态——进程内库(SDK),以及长驻子进程(RPC 模式,官方附带 RpcClient 客户端库)。若一个进程内、一个子进程,适配层要维护两套进程模型。

另有一个运行期问题:Node 是单线程。智能体循环与平台服务同进程时,长任务会挤占事件循环,影响所有会话的响应。

选项

选项 做法 代价 不选的理由
A 引擎都进程内 Pi 进程内、Codex 也进程内 无 IPC 开销 Codex 无法进程内嵌入,此路不通
B 引擎都子进程 两个引擎都以长驻子进程运行,平台通过各自官方客户端通信 Pi 侧要写扩展桥与进程管理 选定
C Pi 进程内 + Codex 子进程 维持现状 无需新增工作 两套进程模型;智能体循环与平台争抢事件循环

结论

选 B:两个引擎都以长驻子进程运行,由平台拉起与守护。

  • Pi:子进程 + RpcClient,协议是标准输入输出的 JSONL
  • Codex:子进程 + app-server 协议
  • 平台侧只认统一的 AgentRuntime 接口,不感知两者协议差异

首版一个会话对应一个引擎进程;若进程数成为负担,再评估进程复用(Pi 支持会话切换,Codex 支持多线程复用)。

影响

  • 隔离:智能体循环不再占用平台的事件循环,长任务不拖累其他会话
  • 工具面仍然不同,没有统一:Codex 可通过 MCP 或实验性动态工具接收平台能力;Pi 需要在 pi 侧写一个扩展,注册工具并把调用以本地 HTTP 回调平台,平台再走 Core.invoke。该链路的鉴权复用现有模式:loopback 随机端口 + nonce 注入 + origin 校验
  • 进程管理是共用的:启停、超时、崩溃重启、日志轮转、父进程看门狗只写一套;可借鉴现有 Electron sidecar 的实现
  • 对代码:server/agent 增加引擎进程管理与 Pi 扩展桥;Pi 扩展放在 pi 侧的扩展目录,由平台启动子进程时指定
  • 对任务:A3.3 改为以子进程接入;新增两个工作包(引擎进程管理、Pi 扩展桥)
  • 不可省:无论哪个引擎,工具调用只有一个出口 Core.invoke

遗留

  • Pi 扩展桥的鉴权细节:nonce 轮换周期、端口预留策略,在 A3 设计时定
  • 引擎进程的复用策略(一进程一会话还是一款多会话)首版不做,观察实际进程数后再评估