AI Agent 开发总纲:从提示词工程走向系统设计
你把几十篇 Agent 博客收藏了一遍,看完每一篇都觉得"很有道理",合上页面却说不清自己到底学会了什么。
那是因为你一直在看"树",没看到"林"。
这篇文章是一张林的地图——把目录里那些博客(生产级 Agent、可观测性、上下文窗口、幂等、SSE、Redis、TTFT)和两个真实项目(Pi Agent Harness、Claude Code 会话式 CLI)串成一张总图,按设计问题、架构问题、安全问题、学习路线四个维度收拢,最后补一节从 Session 设计里提炼的硬需求与软实力。看完它,你再回头看任何一篇,都能说得出"它解决的是这条链路上哪一个问题"。
〇、一张总地图:一次 AI 请求,路过九站
先建全局直觉。一次 Agent 请求,从用户点下发送到最终答案流回屏幕,会路过下面这条链路的每一站。每一站都是一个问题域,每个问题域对应一篇博客或一个项目。
用户目标
│
▼
① 上下文构建 ContextBuilder ← 设计问题:Context 按编译产物来构建
│ 身份 → 检索 → 去重 → 排序 → 过滤 → Token 预算
│ 参考:LLM上下文窗口管理的四层工程防线
▼
② 模型调用 LLMGateway ← 性能问题:首字延迟在这烧钱
│ ← 参考:首字优化-思考博客(TTFT 六层)
▼
③ 工具执行 ToolGateway ← 安全问题:权限要"结构上做不到"
│ → PolicyEngine 风险分级/审批/Schema/限额
│ 参考:生产级Agent
▼
④ 流式返回 SSE ← 架构问题:流式链路的物理现实
│ ← 参考:SSE双队列架构进化之路 / SSE深度解析
▼
⑤ 状态落盘 AgentRun / 幂等键 ← 架构问题:断电了还能续跑
│ ← 参考:幂等性实战
▼
⑥ 全程可观测 Trace / Replay ← 设计问题:先看见,再行动
│ ← 参考:AI可观测性实战
▼
⑦ 跨进程共享 Redis ← 架构问题:多进程怎么安全共享状态
│ ← 参考:Redis实战-AI工作流五个场景
▼
⑧ 经验晋升 Promotion ← 治理问题:经验要过审才能成为规则
│ ← 参考:生产级Agent 第七章
▼
⑨ Session(横切层,铺在每一站之下) ← 设计+架构:Pi 的会话树 / CC 的对话上下文
├─ 执行记录(Pi:会话树 / 回退分支 / 版本化序列化)
├─ 上下文重建(compaction 检查点 / 记忆)
└─ 隔离与干预(沙箱容器 / 权限模式 / 钩子 / 子代理)
← 参考:Pi Agent Harness / Claude Code 会话设计
把这张图压缩成一张"问题 → 博客/项目 → 一句话核心"的对照表,先记住整体:
| 问题域 | 博客 / 项目 | 一句话核心 |
|---|---|---|
| 设计 | 生产级Agent / 可控性 / AI可观测性 | 判断权归模型,执行权归系统 |
| 设计 | LLM上下文窗口管理 | Context 要按编译产物的标准构建 |
| 设计 | 幂等性实战 | 幂等是 Agent 的及格线 |
| 架构 | SSE双队列进化之路 | 流式链路的关键在"队列 + 生命周期"管理 |
| 架构 | Redis实战-AI工作流五场景 | 跨进程共享的每一步都要"原子" |
| 架构 | 首字优化 | 性能要拉通整条链路看 |
| 安全 | 生产级Agent 第三章 / SSE深度解析 | 权限由结构保证,由协议选型配合 |
| 设计/架构 | Pi Agent Harness / Claude Code 会话设计 | Session 是横切一切状态的那一层 |
| 学习 | 上面全部 | Agent 开发 = 后端工程基本功 + AI 特有的不确定性处理 |
下面几节,一节一个维度。每一节末尾都有一张可以直接拿去自检的清单。
一、设计问题:判断权归模型,执行权归系统
设计 Agent 最容易犯的第一个错,是把 Agent 当成"更聪明的提示词 + 更多工具"。
一旦一个 AI 系统拥有"调用工具、改数据"的能力,它就跨过了纯文本生成的边界,进入了**“运行一个程序”**的阶段(《生产级Agent》开场原话)。程序的经典毛病——断电、超时、重复执行、状态不一致——它一个都躲不掉。
从《生产级Agent》那篇里能提炼出六个设计原则,这就是设计问题域的全部骨架。
1.1 第一条边界:模型只建议,系统才执行
这是整张地图里最重要的一句话:
LLM 负责提出判断和计划,真正的系统负责控制它"能看到什么、能做什么、失败后怎么办"。
落地成代码,就是划四条业务代码不得越过的边界:AIApplicationService(编排)、ContextBuilder(上下文)、LLMGateway(模型)、ToolGateway(工具)。任何业务方法里直接 new OpenAIClient()、直接 noteRepository.delete()、直接绕过权限系统,都算设计事故。
模型在链路里只占中间小小一格。它的"想法"都以请求的形式发出去,由外面这一圈确定性的系统来裁决和落地。
1.2 Context 是编译出来的产物
初期的系统这么拼 Prompt:
系统提示词 + 用户问题 + 最近聊天记录 + 搜索到的笔记 + 用户资料 = 最终 Prompt
能跑。跑一段时间问题全冒出来:上下文越来越长、私密内容可能错误进入、新旧文档互相冲突、Token 成本失控、出错后谁也不知道模型当时看到了什么。
解法是《生产级Agent》第二章的 Context Compiler:把"拼接"变成一个带明确 stage 顺序的编译管道。顺序即策略——身份检查永远在最前,Token 预算永远在靠后:
身份权限 → 任务类型 → 知识检索 → 去重 → 相关度排序 → 新鲜度 → 敏感过滤 → Token 预算 → 压缩
配合《LLM上下文窗口管理》那篇的细节:预算不够先砍证据,不砍权限;降级链从低价值信息开始丢,先动免费的(截断),再动便宜的(摘要),最后才动贵的(让人介入)。这背后是经济账,跟心情无关。
1.3 一切操作有回执,一切执行可重放
模型要删笔记,执行完不能只返回一个 success。success 无状态、无法核验,回答不了:谁删的、什么时候删的、能不能恢复、是不是重复执行。
所以要返回结构化 Receipt(operationId / tool / resourceId / status / actor / recoverable),并且每步执行都要落 AgentTrace,让"AI 为什么得出这个结论"从"两手一摊"变成"还原现场"。《AI可观测性实战》的 Trace/Span 设计和《生产级Agent》的 Replay 讲的就是同一件事的两种姿势。
Replay 还有三个用处:排查问题、模型升级回归测试、沉淀评估集。换模型从"凭感觉拍板"变成"看数据做决定"——这是 Agent 团队和聊天机器人团队的分水岭。
1.4 降级链要算经济账
《LLM上下文窗口管理》和《SSE双队列》反复验证同一个道理:正常路径谁都会写,降级路径的设计才是工程师水平的试金石。
上下文超限的降级链要按"先丢弃、再压缩、最后引导人"排序;SSE 的队列满了要先"等 100ms 再丢"而不要立刻丢;TTFT 的高峰期要"让快的、少的、好的,隔离于慢的、多的、坏的"。每条链的每一格,都标着成本:0 次 API、1 次 API、让人介入。
1.5 可观测性要作为设计起点
《首字优化》里最扎心的一句复盘:
V1 那个单点埋点告诉你总耗时,但从来没告诉你钱花在哪了。就像一个只知道总消费金额、却拿不到明细的人。
V1 靠直觉做了流式、连接池、异步解耦,P50 降了 400ms,但 P99 纹丝不动——因为 V1 只盯应用层那几十毫秒,对服务边界外的事一无所知。直到 V5 做了全链路分阶段 Trace,TTFT 的优化才从"猜谜"变成"看表"。看不到的东西没法优化,所以可观测性必须在写第一行业务代码时就埋好。
1.6 幂等是及格线
《幂等性实战》讲的是支付重复扣款,但结论对 Agent 一样致命:只要系统里有一个"超时重试"或"失败重投"机制,幂等就从选择题变成了必答题。
Agent 的每次工具调用都该带 requestId,同一个 requestId 重试时不产生第二次副作用。《生产级Agent》里的 IdempotentInvoker 用键值存储挡一道,就是幂等思想在 Agent 里的直接落地。
设计自检清单:
| 检查项 | 判断标准 | 对应博客 |
|---|---|---|
| 判断权与执行权分离 | 模型永远只发请求,不直接碰数据 | 生产级Agent |
| Context 统一编译 | 各模块不许自己查笔记/自己拼 Prompt | 生产级Agent / 上下文窗口 |
| 操作都有回执 | 没有 success,只有结构化 Receipt |
生产级Agent |
| 执行可重放 | 给定 traceId,能还原模型当时看到的全部上下文 | AI可观测性 / 生产级Agent |
| 降级链有序 | 先免费再便宜再昂贵,每一步标成本 | 上下文窗口 / SSE |
| 幂等兜底 | 每个写操作带 requestId,重试不重复 | 幂等性 / 生产级Agent |
二、架构问题:Agent 是跨进程的分布式执行系统
设计问题管"每一处应该怎么长",架构问题管"整张网怎么织"。五个架构命题,全是从这几篇博客的线上事故里长出来的。
2.1 状态与恢复:断电了还能续跑
《生产级Agent》开头的场景:任务五步走到第三步模型超时了。没有执行状态,系统从头重跑——重复草稿、重复发布、重复扣费。
生产系统要把任务拆成明确步骤,每步状态落盘:幂等(同一操作执行两次结果一致)、Checkpoint(每完成一步保存状态)、Resume(从最后一个检查点继续)。重试要受控,不能无限循环烧钱——RetryPolicy 只重试可恢复的异常。
这里有一个 Agent 特有的架构直觉:普通的聊天是"一句话换一段话",Agent 是"一次任务换一段有副作用的多步执行"。前者无状态可以随时重试,后者一旦落下痕迹,就必须有断点续跑的能力。
2.2 多进程共享:Redis 那张网
《Redis实战》讲的是同一个道理:一条 Agent 请求,Redis 被摸五次——登录态、工具配置缓存、第三方限流、并行分支跨机器传参、汇总节点分布式锁。
把五次收拢成一个架构原则:“多个进程、多台机器之间,怎么安全地共享一份数据”。 每次共享都要回答四个问题:
- 设不设 TTL?(防僵尸 key,也要匹配业务生命周期)
- 要不要原子?(
SET NX EX一条命令、Lua 把"自增+设过期"捆成一块) - 序列化统一吗?(key 用 String,value 用 JSON,跨语言才通)
- 内存满了怎么办?(明确
maxmemory-policy,别用默认noeviction)
2.3 分布式锁的诚实边界
《Redis实战》场景 2 把锁讲透了,也把锁的边界讲透了:主从异步复制下,主节点写锁成功但没同步给从节点,主节点挂了——新主上没有这把锁,两个客户端同时拿到锁。
这是 Redis 分布式锁的理论边界。业界回应有两派:RedLock(antirez)和被反复论证其不严谨(Kleppmann)。架构决策很实在:
- 绝大多数业务,这个故障转移窗口的概率低到可以接受 → 直接用 Redisson;
- 真正不能容忍任何并发(钱、库存的强一致)→ 上 etcd / ZooKeeper 这类基于 Raft / Paxos 的组件。
选型前先想清楚自己在哪一边。 这是架构里最难的部分:承认工具的边界,同时放弃假装没有边界。
2.4 流式链路的物理现实:SSE 的八个坑
《SSE双队列进化之路》的八次蜕变,本质是一次次打破"直觉"的过程:
| 直觉 | 现实 |
|---|---|
| 一个队列就够 | 生成快、推送慢,必须双队列解耦生产消费 |
| 队列能无限存 | 无界队列 = OOM,put() 会阻塞 LLM 源头,要用 offer() |
| 队列满了丢最新的 | 流式场景用户盯着屏幕底部,丢旧保新——旧 token 已渲染,新 token 丢了才要命 |
| 断了就清空一切 | 连接和会话是两种生命周期的资源:瞬时资源随 TCP 死,会话上下文给 8s 宽限期复用 |
| 丢包就学 TCP 重传 | LLM 生成是单向流、一次性的,不能"再生成一遍 seq=47"。 只能分层兜底 |
第 6 条最值得记住:TCP 重传模型假设发送方有缓存可以重发,这个假设在 LLM 场景不成立。强行套用通用方案是架构大忌,适配业务模型才是务实。
2.5 上下文窗口是物理约束
《LLM上下文窗口管理》的标题就点破了本质:模型有"短期记忆"的物理上限。 4K、16K、128K,对话无限增长,窗口固定大小,这是根本矛盾。
架构上的三连问:
- 历史存哪?
HashMap→ Redis → Redis+Caffeine → 落库+向量化(RAG 语义召回替代全量塞入) - 窗口 vs RAG?都选。 滑动窗口和 RAG 回答的是两个不同维度的问题——滑动窗口回答"最近说了什么"(时间维度),RAG 回答"和现在最相关的是什么"(语义维度),叠加使用。
- 截断了用户知道吗?别静默——前端推一条温和提示 + 操作建议。
2.6 性能要拉通整条链路来看
《首字优化》的五次推倒重来给出了 TTFT 的六层框架:客户端传输层 → 接入网关层 → 应用服务层 → 依赖中间件层(Embedding 本地化、向量索引)→ 模型推理层 → 可观测与稳定性层。
V1 只做了第三层,P50 好看 P99 不动。每一层的出现,都对应一次"发现漏了什么"的时刻:漏了链路前半段(DNS、TLS)、漏了 RAG 计算开销(占 30%+)、漏了并发排队效应(单用户快 ≈ 百万并发快)、漏了"先看见再行动"。
架构自检清单:
| 检查项 | 判断标准 | 对应博客 |
|---|---|---|
| 可恢复 | 有 AgentRun / Checkpoint / Resume,没有重跑一遍 | 生产级Agent |
| 幂等键 | 每个写操作可去重 | 幂等性 / 生产级Agent |
| 共享状态 | 跨进程状态进 Redis,明确 TTL / 原子 / 序列化 / 淘汰策略 | Redis实战 |
| 锁的边界 | 想清楚自己能不能接受主从切换窗口,不能就换 etcd | Redis实战 |
| 流式兜底 | 有界队列 + 丢旧保新 + 连接/会话资源分级 | SSE双队列 |
| 性能分层 | 全链路埋点,瓶颈定位到 Span 而不是靠猜 | 首字优化 |
| 上下文预算 | Token 预算绑定模型,降级链按成本排序 | 上下文窗口 |
三、安全问题:权限要"结构上做不到"
AI 工具的安全,大多数人第一反应是在提示词里写上禁止。这层误解最危险。
3.1 Prompt 只能算软约束,安全要靠硬机制
《生产级Agent》第三章直接点名了一个错误设计:Agent → DeleteNoteTool → 删除笔记,然后在 Prompt 里写"没有用户同意不要删除"。
模型可能误判用户意图,可能被注入的提示词误导,也可能就是状态不对产生幻觉。你把安全建立在"模型每次都记得这句叮嘱"上,等于把门锁建在"每个人都自觉关门"上。
生产级做法是加一道硬门卫——PolicyEngine:当前用户是谁、是否有权限、操作是否高风险、是否需要审批、参数是否符合 Schema、是否超限额。核心思想就一句:
Agent 可以申请执行,但决定权限的只能是策略引擎,不能让模型自己说了算。
3.2 风险分级 + 审批要落到代码上
把工具按危害面分三档:LOW(搜索/读取)直接放行,MEDIUM(创建/更新)校验权限和限额,HIGH(删除/发布/导出/改权限)必须走审批。
审批链路最关键的一步:先领审批凭证,凭证未确认之前系统什么都不做(生成凭证 → 用户确认 → 放行执行)。这样权限在结构上就被保证了,不依赖模型自觉。
3.3 注入与幻觉的统一解法:硬门卫
Prompt 注入的本质是"模型的判断被污染了"。既然你不可能 100% 防住模型的判断被污染,那就不要在模型判断正确的假设上设计安全。模型可能被骗着发出一条"危险请求"——没关系,请求到了 PolicyEngine 会被拦下来。这就是为什么注入攻击和幻觉,在架构上共享同一个解法:把信任从模型身上剥离开,放到确定性的门卫代码上。
3.4 敏感数据与日志边界
《AI可观测性实战》第十六章和《SSE深度解析》各指了一条数据泄漏渠道:
- 日志:为了排查问题把所有 Prompt 和笔记全文打进日志——普通 Trace 里只留 runId / snapshotId / queryHash / documentCount / tokenCount / model / cost,完整上下文放加密存储 + 严格权限 + 有限保留期。
- URL 参数:
EventSource只能用 GET,Token 被迫放 URL——服务器日志、浏览器历史、Referrer 头三处泄漏。
这是 2025 年 MCP 从 SSE 迁到 Streamable HTTP 的直接原因之一。
3.5 认证的粒度:连接级还是消息级
SSE 的认证只在连接建立那一刻做,中途 Token 过期了连接照样活着;而且 SSE 长连接很难被标准安全中间件(WAF、API Gateway)逐消息检查。
如果你的场景需要"每一条消息都独立认证"或"严格的中间件审计",SSE 难当此任。选协议之前,先想清楚自己的信任边界在"连接级"还是"消息级"。
3.6 成本失控也是安全问题
《SSE双队列》第八层讲了四道成本防线:宽限期内复用上下文(根治)、会话级重试熔断、任务版本号抢占取消(过时任务自己停)、全局并发限流。核心区分是——“合理的用户行为成本"和"代码缺陷导致的不必要成本”,架构上要消除后者。 一次网络抖动触发的全量 LLM 重试,100 个用户切网就是账单翻倍。
安全自检清单:
| 检查项 | 判断标准 | 对应博客 |
|---|---|---|
| 硬门卫 | 权限判断在 PolicyEngine,不在模型脑子里 | 生产级Agent |
| 风险分级 | HIGH 操作必须审批,审批凭证先于执行 | 生产级Agent |
| 数据脱敏 | 日志存 hash 不存原文,完整上下文加密隔离 | AI可观测性 |
| Token 传输 | 敏感凭证不落 URL / 日志 / Referrer | SSE深度解析 |
| 认证粒度 | 想清楚连接级还是消息级认证,选对协议 | SSE深度解析 |
| 成本熔断 | 重复调用有熔断,过时任务能自杀 | SSE双队列 / Redis实战 |
四、Agent 开发:着重学什么
问题域都讲完了,回答最初的问题——如果你要往 Agent 方向深入,着重学什么?
4.1 一次思维迁移:从"提示词"到"执行系统"
Agent 开发和你之前学的所有后端开发之间,差了一次认知迁移。下表就是这次迁移的对照:
| 普通后端 | Agent 开发 |
|---|---|
| 代码是确定性的,测试覆盖了就不出意外 | 模型是概率性的,同一输入今天明天可能不同 |
| 出错了能靠日志定位 | 出错了要先"还原现场"(Replay) |
| 幂等是支付系统的要求 | 幂等是每次工具调用的默认要求 |
| 权限靠中间件挡 | 权限还要防住"被注入污染的模型判断" |
| 性能优化到瓶颈点 | 瓶颈可能在应用层之外(DNS、排队、Embedding) |
这个迁移一旦完成,你就会发现:那些你以为"是 AI 的坑"的东西,其实全是后端工程的坑。 队列满了是并发问题,跟 AI 无关;超时重试重复执行是幂等问题,跟 AI 无关;上下文拼错是抽象问题,跟 AI 无关。
4.2 七个能力模块,每块配一个精读对象
| 能力 | 精读对象 | 提取的核心技能 |
|---|---|---|
| 边界与分层 | 生产级Agent | 划边界、Context Compiler 管道、Policy Engine、三阶段落地 |
| 可观测与评估 | AI可观测性实战 | Trace/Span 设计、Metric 体系、Dashboard、数据落库 |
| 上下文工程 | LLM上下文窗口管理 | Token 预估、降级链、消息分级、Token 计费 |
| 流式协议 | SSE双队列 + SSE深度解析 | 有界队列、资源生命周期、丢包兜底、协议选型 |
| 分布式基础 | Redis实战 + 幂等性实战 | 原子性、分布式锁边界、幂等 Token、缓存一致性 |
| 性能链路 | 首字优化 | 全链路 Trace、分位数、熔断限流、优先级调度 |
| 会话与状态 | Pi Agent Harness + Claude Code | 会话树/回退分支、compaction 检查点、记忆沉淀、权限模式与隔离 |
4.3 四个"你以为懂,其实要补"的点
《首字优化》结尾总结了 V1 直觉方案漏掉的四件事——这四件事就是 Agent 开发里最典型的盲区:
- 漏了链路的前半段:用户到服务器的路上,DNS 和 TLS 在消耗看不见的时间。你以为的"起点"其实在更前面。
- 漏了 RAG 的计算开销:Embedding 和向量检索占了 30%+ 却被当成"别人的事"。Agent 的性能问题,一半藏在"上下文准备"里。
- 漏了并发下的排队效应:单用户测试很快,不代表百万并发依然快。慢的根源常常在于"隔离不够"。
- 漏了"先看见再行动"的底气:没有分层 Trace,每次排查都是一场猜谜。
这四件事之外,还有一个更大的盲区——Session 怎么设计。下一节专门展开。
4.4 从博客到简历:怎么把经验沉淀成面试答案
目录里这些博客之所以是"面试宝典",关键在于一个共同的写法——每讲一个坑,都追到"为什么",再追到"所以架构上应该怎么设计"(博客里的"思维回溯")。
对应到面试,就是一套自洽的叙事结构:
场景(线上发生了什么)→ 根因(是设计问题还是架构问题)→ 方案(落到了哪条边界 / 哪个组件)→ 代价(牺牲了什么,为什么不选银弹)→ 迁移(这个教训还能用在哪)
你不需要背每篇博客的代码。你需要的是能对任意一个 AI 项目,一口气讲出《生产级Agent》那条总链路、讲出四个问题域各三条红线。能做到这一点,说明你已经有能力把"会调工具的聊天机器人"升级成"能把它变成执行系统的人"。
五、两个 Session 设计:Agent 开发的硬需求与软实力
前面四节讲的是"单体 Agent 服务"的骨架。但 Agent 开发还有一大块没有顾及到——Session 怎么设计。Session 是"一次对话 / 一次任务"的完整状态容器,它决定了你的 Agent 能不能:断线重连接着聊、跨请求记住上下文、并发出错后回到过去、上下文超长后继续干活。
拿两个真实项目对照。一个是 Pi Agent Harness(GitHub 上约 4 万 star 的开源编码 Agent,OpenClaw 的核心运行时也构建在它的 SDK 之上),一个是 Claude Code(会话式 CLI Agent)。两者都是"终端里的编码 Agent",Session 设计却走完全相反的两条路,正好把 Agent 开发的硬需求和软实力摊满。
5.1 Pi 的 Session:一棵可回退、可分支的树
Pi 把 Session 存成 JSONL 文件,每条记录带 id 和 parentId,拼起来是一棵会话树,而不是一条直线:
├─ user: "试试方案 A"
│ └─ assistant: "方案 A 这样写..."
│ ├─ user: "A 跑通了" ← 当前叶子
│ └─ user: "还是试方案 B"
│ └─ assistant: "方案 B..."
这套设计默认了 Agent 会犯错:/tree 可以回到任意一个历史点,改一句 prompt 重新提交,从那里长出新的分支;/fork、/clone 可以把一条分支单独拎成新会话。撤销的单位从"一句回复"放大到了"整条执行路径"。 放弃一条分支时,模型会为那条被放弃的路径生成一段摘要(BranchSummary),挂在分支点附近——走掉的路丢了内容,但留下了上下文。
Pi 的 compaction 和《生产级Agent》的 Checkpoint 是同一思想的另一个落地:上下文超阈值时,把旧消息摘要成一条 CompactionEntry,里面带 summary + firstKeptEntryId + retainedTail(压缩后保留的尾部消息,作为自包含检查点)。重建上下文时从这个检查点往后走,无需翻旧条目。切分点永远落在回合边界,绝不在 tool-result 中间切。
Pi 的会话文件还带着一串很多项目会忽略的字段:
- 版本号:session 格式有 version 1/2/3,加载时自动迁移。磁盘格式的演进是一等公民,升级不毁老会话。
- 记账:每条 assistant 消息都带
usage(input/output/cacheRead/cacheWrite + cost)。Token 和费用长在会话里,能对账、能回溯。 - 换模型:会话记录
model_change事件,同一段对话中途切模型,重建上下文时还能还原当时用的是哪个 provider、哪个模型。
5.2 Claude Code 的 Session:一段可回放、可干预的对话
Claude Code 的 Session 走了另一条路:它把一次交互看作可记录、可续跑、可干预的对话上下文,连接状态只占其中一小部分。Session 里除了对话记录,还挂着:
Session = 对话记录(transcript)
+ 压缩与续跑(长对话自动摘要、断点恢复)
+ 记忆(跨 Session 的持久化文件,独立于上下文)
+ 工具与权限(用户选定的模式,被拒绝即调整)
+ 钩子(系统级干预,中途插入规则)
+ 子代理(隔离运行,并行推进)
+ 工作树隔离(git 级别的沙箱)
Pi 的答案可以概括为"Session 就是一棵树,其余交给沙箱和扩展";Claude Code 的答案是"Session 自带一套治理:记忆、权限、钩子、子代理全部内建"。两种取舍没有对错,差别在边界归谁管。
对应到软实力(做了才"好用",不做也能跑):
1. 上下文压缩的取舍。 对话长到放不下,自动把早期内容摘要成紧凑形式。但要清楚这是有损的——代码、SQL、合同这类内容被压缩等于改语义。正确姿势是分级:可压缩的普通对话才压,关键内容保留原文,并让用户知道"早期部分被精简了"。压缩的边界里同时装着业务判断和工程判断。
2. 记忆跨 Session 沉淀。 记忆文件存的是"用户的身份、偏好、被纠正过的工作方式",它独立于任何一次对话,用索引在每次会话加载。这和 RAG 召回知识是同一件事的两种形态:知识进上下文靠检索,经验进行为靠记忆。
3. 人在环上是安全底座。 权限模式由用户选定,工具调用被拦截时返回的是可调整的反馈,而不是一个硬错误。高风险操作永远留一个需要人确认的闸门。Agent 设计到后面,重心会从"让模型更聪明"挪向"让人更放心"。
4. 可干预、可隔离、可并行。 系统通过钩子在会话中途注入约束;子代理在独立工作区里并行干活、互不污染;文件级沙箱防止一个任务改坏另一个任务。隔离是 Agent 进化的分水岭——从"一个对话干一件事"到"一个对话派出一群隔离的执行者"。
5.3 硬需求 vs 软实力:一张对照表
两个项目的 Session 设计摊开对比,硬需求(结构上不做就崩)和软实力(做了才"好用")一目了然:
| 硬需求(结构上不做就崩) | 软实力(做了才"好用") | |
|---|---|---|
| Session 形态 | 有 ID、可序列化、格式带版本可迁移;断点可恢复 | 树 + 回退 + 分支,撤销粒度放大到整条执行路径 |
| 上下文 | 超长时能压缩,且能从检查点重建,不重翻旧条目 | 切分有业务判断:回合边界切、关键内容不压 |
| 记账 | Token / 费用随消息落库,可对账可回溯 | 把成本当功能设计,而非事后统计 |
| 模型 | 跨 provider 可切换、可回放(record model_change) | 不被单一模型锁死,切换有据可依 |
| 安全 | 必须选一种兜底:沙箱/容器(Pi)或 权限模式+工作树(CC) | 诚实选择安全哲学,在"途中同意"和"容器隔离"之间取舍 |
| 演进 | 磁盘格式带版本、可自动迁移 | 极简主义:核心保持小,能力按需扩展 |
5.4 补进总地图
把两个项目放回总地图,Session 是横切在每一站下面的那一层:
……原链路每一站……
↓
Session(横切层)
├─ 执行记录(Pi:会话树 / 回退分支 / 版本化序列化)
├─ 上下文重建(compaction 检查点 / 记忆沉淀)
├─ 记账与换模型(usage 随消息 / model_change 回放)
└─ 隔离与干预(沙箱容器 / 权限模式 / 钩子 / 子代理)
Agent 开发的路由此补全:前面四节是"单体服务怎么设计",这一节是"一次执行实例怎么设计"。顺带一提,你自己的 PaiFlow 工作流引擎在 TTL 上下文传播、变量池并发安全上踩过的坑,跟这里两张 Session 设计是同一批硬需求的另一面——Session、任务、连接三层状态,永远是 Agent 架构里最容易被低估的地方。
六、落地路线图:别想着一步到位
《生产级Agent》第八章给了三阶段落地法。这里把前面所有维度(含 Session 设计)折叠进三阶段:
第一阶段 · 立边界(设计)
AIApplicationService / ContextBuilder / LLMGateway / ToolGateway
红线:Agent 不直接调 Repository、不碰 DB、不绕过权限系统
第二阶段 · 加恢复和可观测(架构 + Session)
AgentRun / ToolCallLog / ContextSnapshot / RetryPolicy / IdempotencyKey
Session 与上下文:会话序列化与版本 / compaction 检查点 / 跨线程上下文传播
解决:执行断了能续、重复了能挡、出了事能查
第三阶段 · 上治理(安全 + 评估 + 记忆)
ApprovalWorkflow / Replay / EvaluationDataset / PolicyEngine
Session 与记忆:跨 Session 记忆 / 人在环上 / 子代理隔离
解决:审批、回放、评估、策略引擎全部在位
每一阶段都建立在"你已经被上一层的问题折磨过"的前提上。没被 OOM 折磨过,你不会理解为什么要上有界队列;没被 Token 账单惊吓过,你不会觉得全链路计费是刚需。跳级不划算,因为每一层的设计都是问题驱动的。
把链路闭合
回到开头的总地图,把所有维度拼回去,就是一句话:
把不确定的智能,限制在确定的软件工程边界里。
LLM 可以不稳定,但外围系统必须稳定。各自的职责分得很干净:
模型 负责建议
策略 负责授权
工具 负责执行
Runtime 负责记录与恢复
Session 负责状态与记忆
可观测 负责让一切都看得见
人 负责高风险决策
这也是 AI 系统和普通后端最大的区别:你不能假设模型每次都会做对,所以架构要围绕"它可能判断错误"来设计。 模型出错并不可怕,可怕的是出错之后系统既不能发现、也不能恢复、还不能解释。
把这八个词记住——判断、授权、执行、记录、会话、隔离、决策、看见——然后回头去重读任何一篇博客,你都会发现:它写的其实都是这套边界的一个侧面。
更多推荐
所有评论(0)