你以为 AI 只看到你打的那句话?错了。每次提问,程序都会在你的话之外,悄悄塞进十几份"背景资料"。本篇讲:这些资料是什么、怎么靠缓存省钱、对话太长装不下怎么办、怎么自动划重点、AI 的记性怎么实现、图片语音怎么喂。
5.1 你的一句话之外,AI 每次还拿到十几份背景资料
模型其实很"笨":它没有记忆,每次请求都是一次全新的开始------它不记得你是谁、在哪个项目里、刚才聊了什么。它之所以表现得像记得,是因为程序每次都把它需要知道的一切重新打包发给它。
这份打包的资料里,除了你刚打的那句话,还有一大段固定内容叫系统提示(system prompt)------相当于每次开工前给 AI 的一本"工作手册"。这本手册由十几个段落拼成:
objectivec
┌─────────────────────────────────────────────┐
│ ① 身份与规矩:你是一个编程助手,行为准则...... │
│ ② 环境信息:什么操作系统、什么命令行、当前路径、│
│ 现在的日期时间 │
│ ③ 代码仓库状态:在哪个分支、有没有未提交的改动、│
│ 最近几条提交记录 │
│ ④ 记忆:关于这个项目/这个用户的长期注意事项 │
│ ⑤ 用户自定义内容:项目里的 CLAUDE.md 等说明文件 │
│ ⑥ 工具说明书:核心工具怎么用(第 4 篇讲过) │
│ ⑦ 技能目录:有哪些进阶能力可以取 │
│ ⑧ 分身目录:可以派哪些类型的子助手 │
│ ⑨ 外部服务清单:接了哪些外部能力 │
│ ⑩ 当前权限模式:现在是什么授权状态 │
│ ⑪ 输出风格:回答要详细还是简洁 │
│ ⑫ 其他开关:遥测是否关闭等 │
└─────────────────────────────────────────────┘
为什么要拆成这么多段,而不是写一大段?
两个原因。第一是有的放矢:不同场景需要的段落不同。被程序调用的场景可能不需要"输出风格",只读模式不需要"权限模式",拆成段就能按需拼装。
第二是省钱,这也是下一章的主题:这些段落里,有些每次都一样(身份规矩),有些经常变(仓库状态)。分开后,不变的部分可以利用模型的"缓存"能力,不必每次重新计费。
这本手册怎么拼出来
程序里有一个"装配工"角色,每次提问前按清单逐段准备:要环境信息就去查系统、要仓库状态就去跑几条 git 命令、要记忆就去档案室翻、要工具说明就去问工具库房。各段准备好后拼成完整手册,连同聊天记录和你的新问题一起发给模型。
注意第 ③ 段:AI 每次都知道"你的代码现在是什么状态",靠的是程序真的去跑了 git status、git log 这些命令,把结果喂给它。AI 对仓库的一切了解,都是这样一次次喂进去的------它自己可看不见你的磁盘。
5.2 怎么省钱:重复的资料不重复交
上一章提到,系统提示有好几万字,而且每次提问都要发 。如果每次都全额计费,一天聊下来费用很惊人。模型厂商提供了一个省钱机制,叫提示缓存(prompt caching)。
缓存是什么意思
打个比方:你去打印店印 100 份装订好的小册子,每份 50 页,其中前 49 页完全一样,只有最后 1 页不同。
- 没有缓存:打印店每次都从头印 50 页,收 50 页的钱 × 100 份。
- 有缓存:打印店把前 49 页印好存起来("缓存"住),之后每份只印新的第 50 页,装订到现成的前 49 页上。前 49 页只收很低的"存储费",你主要付第 50 页的钱。
模型的提示缓存一模一样:你发给模型的内容如果开头一大段和上次完全相同,厂商可以把这段"记住"一段时间,下次你再发,相同部分按很低的缓存价计费,只有新增部分正常收费。
关键:必须是"开头连续相同"
缓存生效有个苛刻条件:它像"对暗号",从内容的第一个字开始逐个比对,一旦某个字不一样,从那里往后全都算新内容。所以系统提示的段落顺序极其重要------必须把最稳定不变的内容放在最前面,容易变的放在后面:
markdown
开头(最稳定):身份规矩、工具说明书 ...... → 几乎永不变,缓存命中率最高
:环境信息、记忆 ...... → 偶尔变
结尾(最易变):仓库状态、当前权限、你的新问题 → 每次可能变
这样安排后,一次对话里绝大多数请求的开头都能命中缓存,几万字的手册实际只付很少的钱。
为了缓存,设计上做的妥协
这个机制影响了很多设计。比如:
- 段落顺序不能随便调(会导致缓存全部失效);
- 能不变的内容尽量不变------有些信息(比如精确时间)如果放进手册,会让缓存每秒都失效,所以要么不放、要么降低更新频率;
- 压缩历史(5.4)时也特意保持手册稳定,不让压缩动作破坏缓存。
这是一个典型的"理解计费模型,然后让代码结构去迎合它"的工程决策。
5.3 对话太长装不下怎么办:字数预算表
模型一次能看的内容有上限(行话叫"上下文窗口",你可以理解成模型的"工作台大小"------桌上能同时铺开的资料是有限的)。对话越聊越长,桌上的资料越堆越高,迟早铺满。怎么管理这块有限的桌面?
先得随时知道"桌上铺了多少"
程序持续在算账:当前所有内容(手册 + 聊天记录 + 工具结果)大概占了多少字、离上限还有多远。这个字数不用很精确(精确数字数太慢),用"几个字符约等于一个字"的方式估算就够了。
三个水位
像水箱的水位线一样,分三档:
erlang
满 ┃───────────────────── ← 到这就不能再聊了,必须先压缩
┃ 危险区(红):超过 80%,自动触发"划重点"
┃─────────────────────
┃ 警告区(黄):超过 50%,界面提示你注意
┃─────────────────────
┃ 安全区(绿)
空 ┃
- 安全区:正常聊天。
- 警告区:界面顶部出现提示条,让你有心理准备,也可以手动提前压缩。
- 危险区:程序自动安排压缩(5.4 讲),防止真的溢出来。
- 真满了:如果压缩也救不了(极少见),程序会拒绝发送,提示你必须清理。
还要预测"这一轮会涨多少"
光看现在用了多少不够,还得预判未来:模型回复会产生新内容、工具结果可能很大。程序会粗略估算"这一轮最多可能再堆多少",提前留余量。这就像装修预算不能只算已经花的,还要给未完工的部分留钱。
不同模型桌面大小不同
不同模型的窗口大小不一样(有的能铺 20 万字,有的更少)。程序按当前选用的模型动态调整水位线。有些特殊情况(比如模型要输出特别长的内容)还会临时抬高输出上限。
5.4 自动"划重点":聊久了它会自己总结前面的内容
当聊天记录逼近窗口上限,程序就启动压缩(compaction)。这个机制很像考试前划重点。
为什么需要压缩
聊天记录里有大量"过程性废话":AI 读了十个文件、跑了五次命令、中间两次走错路又折返......这些细节对继续干活价值不大,但占着大量桌面。真正重要的是:我们在解决什么问题、已经得出了什么结论、试了哪些方案结果如何、用户有什么要求。
压缩怎么做
程序会请模型自己干一次"总结":
markdown
1. 到了危险水位
↓
2. 程序把到目前为止的聊天记录交给模型,下指令:
"请把前面的对话总结成一份摘要:目标、关键结论、
重要决策、待办事项、踩过的坑......"
↓
3. 模型产出摘要(可能几百字,代替原来几万字的记录)
↓
4. 程序把聊天记录替换成:
【前面内容的摘要】 + 【最近几轮的完整原文保留】
↓
5. 桌面腾出一大半,继续聊天
为什么保留最近几轮原文
摘要会丢细节,而最近的对话细节往往最有用(比如你刚贴的报错、刚指出的问题)。所以策略是"远古历史变摘要,近期历史保原文",兼顾省空间和不丢上下文。
三种触发方式
- 自动压缩:到危险水位自动触发(上面讲的)。
- 手动压缩 :你随时可以输入
/compact主动划重点。 - 反应式压缩(实验性功能):不等攒到水位线,发现"单轮内容突然暴涨"时就后台悄悄压缩,不打断当前对话。
还有一种更轻的操作叫"微观压缩":不是总结整个历史,而是单条消息太大时(比如一个工具输出了十万行),就只对这一条做切块、截断处理。
压缩后要保证模型不糊涂
压缩时程序会在记录里放一个明确的"分界线标记",相当于告诉模型:"分界线之前是摘要,不是原文,细节可能不全"。这样模型引用早期内容时会知道"我记得的是摘要,需要细节可以再去读文件"。同时,压缩尽量不动系统提示手册,保证缓存不失效(5.2)。
压缩会不会"失忆"
会损失细节,但有两道保险:一是完整聊天记录始终落盘存着(第 3 篇讲过),压缩的只是发给模型的那份"桌面",原始档案没删;二是文件和代码都在磁盘上,模型真要确认早期细节,重新读一遍文件即可------摘要告诉它"去看哪里",它自己能找回去。
5.5 AI 的记性:怎么记住"这个项目用 pnpm 不用 npm"这类规矩
压缩解决的是"聊得下",记忆解决的是"跨会话记得住"。你昨天告诉它"这个项目用 pnpm,别用 npm",今天新开对话它怎么还知道?
记忆存在哪
记忆是放在磁盘上的一批小文件,分两个范围:
- 用户级:关于你这个人的偏好("我喜欢提交信息用中文""我习惯用函数式写法"),对你所有项目生效;
- 项目级:关于这个项目的规矩("用 pnpm""测试命令是 pnpm test:e2e""部署要找运维要权限"),存在项目文件夹里,可以和团队共享。
此外还有项目说明文件(用户自己写的 CLAUDE.md 之类),相当于"项目说明书",每次也会喂给模型。
记忆是怎么产生的
- 你主动写:你可以直接编辑这些记忆文件,或在对话里让它记住某事;
- 它自动攒:对话结束时,程序会从聊天记录里提炼值得长期记住的事(踩过的坑、定下的规矩、项目特有的操作方式),追加到记忆文件里。每条记忆带日期。
记忆那么多,不可能全喂
用久了记忆文件可能攒下几百条,全塞进手册又会撑爆桌面。用的还是第 4 篇那个熟悉的思想------给索引、按需取、按相关度排序:
- 手册里只放最基础、最通用的记忆;
- 你提出一个问题后,程序拿你的问题和所有记忆做"相关度匹配"(一种按词频计算相似度的方法,思路和搜索引擎搜网页类似);
- 只把和当前问题最相关的几条记忆放进资料包;
- 模型还可以主动用"记忆查询工具"去翻档案。
团队共享记忆
项目级记忆可以存在项目里随代码共享,于是团队的隐性知识("这个服务的坑在哪""发版流程是什么")能沉淀下来,新人、新开会话的 AI 都能读到。有些版本还支持团队记忆在多人之间同步。
记忆和压缩的区别
- 压缩是"这一场对话太长,把过程浓缩",摘要活在会话内;
- 记忆是"跨会话有价值的长期知识",存在磁盘上,每次新会话按需取出。
- 压缩产出的是"我们刚才干了什么";记忆存的是"以后都用得上的规矩"。
5.6 图片、文档、语音是怎么喂给它的
模型不只吃文字。你可以往对话里拖图片、PDF、文档,甚至说话。这些东西怎么进入资料包?
图片
图片以原始图片数据(编码后)直接塞进消息里------现代模型本身就能"看图"。但图片有大小限制,太大的图程序会自动压缩分辨率再发。典型用途:拖一张报错截图让它看、拖一张设计稿让它照着实现界面。
PDF 和文档
PDF 不能直接"看懂",程序先做一层加工:把文字抽取出来、把页面转成图片。文字部分作为文本喂入,复杂排版/图表页面转成图片喂入。Office 文档类似,通常先转成纯文本或网页格式。
代码文件
你用 @ 引用或拖入代码文件时,文件内容作为文本放进消息。同样受预算约束:太大的文件不会全文塞入,而是提示 AI"文件很长,你可以用读文件工具按需分段读"------还是"别一次塞满"。
语音
语音输入要先经过"语音转文字":程序采集音频,调用语音识别服务(或本地识别),把转好的文字作为你的消息发出。转写过程在界面上有提示,转完你还能在发送前核对修改。
附件也会去重
一个细节:如果你拖入的文件内容,恰好和记忆系统或手册里已有的内容重复(比如把项目说明书又拖了一遍),程序会去重,不重复计费、不重复占桌面。
多模态资料的位置
所有这些附件最终都以"消息内容块"的形式存在第 3 篇讲的消息结构里------一条用户消息可以同时装文字、图片、文件引用。模型收到的是一个"大杂烩口袋",它自己能区分哪块是文字、哪块是图。
本篇小结
- 模型没有记忆,每次提问程序都重新打包一切:系统提示手册(十几段)+ 聊天记录 + 你的新问题。
- 手册分段拼装,稳定的放前面、易变的放后面,是为了迎合提示缓存"开头连续相同才省钱"的规则。
- 上下文窗口是有限的"桌面",程序用三档水位线管理占用并预测增长。
- 逼近上限时自动压缩:请模型把远古历史划成摘要,近期几轮保原文;原始记录始终落盘不丢。
- 记忆是跨会话的长期知识,存磁盘、分用户级和项目级、按相关度取 top 几条喂入,不全部塞。
- 图片直接发、PDF 先抽文字转图片、代码按需分段、语音先转文字------附件都装在消息的"内容块口袋"里,并做去重和预算控制。
下一篇换个角度,讲你看得见的部分:黑底白字的终端里,那套会动的彩色界面是怎么画出来的。