# Pi Agent 架构与迭代边界
本项目日常运行的主链路是 Java v1 + React Web,不包含额外的 Node Agent 服务或实验 UI 运行时。
# 当前架构目标
pi-agent-v1 定位为单 Agent 的可运行 Core,而非完整的 Agent 平台。后续先完善稳定的 运行契约和可观测性,再按真实需求选择性吸收工作区、记忆、沙箱、子 Agent 或分布式能力。
先做:RuntimeContext + Message/Event 契约 + 权限 + Middleware + Trace
后做:Harness(记忆、技能、计划、子 Agent、沙箱)
最后才考虑:Service(控制面、托管、跨 Agent 编排)
这与 AgentScope Java 的分层一致,但不直接复制其 Harness/Service 复杂度。
# 运行主链路
web/ React
└─ HTTP + SSE
└─ WebMain(HTTP 接入、会话锁、路由、SSE 适配)
└─ AgentLoop(模型 → 工具/交互 → 工具结果 → 下一轮)
├─ RuntimeContext(runId / sessionId / userId / workspace / 请求级属性)
├─ EventEnvelope(eventId / timestamp / runId,供 SSE 与 Trace 关联)
└─ AgentMiddleware(Agent / Reasoning / Acting / Model / Prompt 扩展点)
├─ model/(模型适配)
├─ tools/(工具定义、执行、路径与输出边界)
├─ ToolApprovalCoordinator(高风险命令审批)
└─ UserInputCoordinator(ask_user 结构化追问)
├─ SessionStore / SessionRegistry(会话历史)
└─ TraceStore(运行链路)
# 后端职责
| 模块 | 当前代码 | 只负责什么 | 新功能放置规则 |
|---|---|---|---|
| --- | --- | --- | --- |
| 协议 | Protocol | Message、Tool、Event 的公共契约 | 新 SSE / 工具决策类型先改这里,再改上下游 |
| 编排 | AgentLoop | 多轮循环、工具结果回灌、生命周期事件 | 不写 HTTP、DOM、具体风险规则 |
| 请求上下文 | RuntimeContext | run/session/user/workspace 与请求级临时属性 | 不持久化;不把请求状态塞进单例或会话历史 |
| 扩展 | AgentMiddleware | Agent、推理、行动、模型、system prompt 的轻量 hook | 观测、提示注入等放这里;长期状态写入会话层 |
| 事件关联 | EventEnvelope | eventId、时间戳与 RuntimeContext 关联 | SSE 和 Trace 必须保留 runId/eventId,不用 UI 自行猜关联 |
| 接入 | WebMain | /api/*、SSE、会话互斥、应用组装 | 路由只做参数校验与委派,不堆业务判断 |
| 交互 | ToolApprovalCoordinator、UserInputCoordinator、WebToolCallHandler | 暂停、用户决定、超时、恢复原 Agent 调用 | 新增确认/表单/权限策略优先在此层实现 |
| 工具 | tools/ | schema、执行、工作区和输出安全边界 | 执行工具注册在 BuiltinTools;交互工具放 tools/interaction/ |
| 模型 | model/ | 厂商请求/响应格式转换 | 不包含会话、工具执行或 UI 状态 |
| 持久化 | SessionStore、AgentState、SessionRegistry、TraceStore | JSONL 对话历史、可演进会话状态、索引、链路 | AgentState 当前保存摘要、权限规则、任务与待答交互;完整跨重启续跑仍需暂停状态机 |
# 前端职责
web/src/main.tsx 当前仍是单文件实现,后续功能按以下组件边界拆分,避免继续增长为巨型文件:
web/src/
app/ # App 壳、会话与请求状态
chat/ # 消息、Markdown、工具卡、运行卡
trace/ # 链路面板、JSON 树、历史
interactions/ # ApprovalDialog、UserInputDialog、表单字段
api/ # SSE 解析、REST 请求、前端类型
styles/ # token、布局、组件样式
拆分时保持 API 类型与展示组件分离:api/ 管请求与解析,组件只接收明确 props。现有代码在修改相邻功能时逐步迁移,不做无收益的大搬迁。
# 交互契约
| 场景 | 模型工具/事件 | 浏览器提交 | Agent 后续行为 |
|---|---|---|---|
| --- | --- | --- | --- |
| 高风险命令 | bash → tool_permission | /api/approvals/{approvalId} | allow 执行;deny/timeout 作为工具失败回灌 |
| 信息追问 | askuser → userinput_required | /api/chat/continue | 结构化答案作为成功工具结果回灌 |
所有可暂停交互必须具备:唯一 ID、会话归属、超时默认值、链路记录、一次性消费语义。需要跨刷新/重启恢复时,再增加持久化状态机;不能只依赖内存 Future。
# 迭代约定
- 先定义协议和状态,再实现 API/SSE,再做 UI。
WebMain不新增业务规则;优先新建协调器或服务类。- 关键决策、状态转换、风险边界写简洁中文注释。
- 每项功能至少验证:流式、多轮、工具调用、刷新后历史;涉及 UI 再做浏览器验证。