工程化 / 大模型应用工程化
6. 上下文工程——给 AI 正确的信息,而不是尽可能多的信息
原文备份 · 第 8 / 21 篇 · 查看极客时间原知识库 ↗
本篇目录 · 8 节
来源:大模型应用工程化
笔记助手里有一个旧函数,查询语句末尾写着LIMIT 50。有人看到它,提出一个很合理的怀疑:“是不是只在最近50条记录里搜索,所以更早的问题找不到?”
如果只把这一小段代码发给AI,它可能立刻建议去掉上限。如果把整个项目、全部聊天记录和历史规格一起发过去,它又可能被“搜索尚未实现”的旧状态带偏,重新规划一个已经完成的功能。
这次真正需要回答的是:当前首页到底调用哪个函数,50条限制发生在匹配之前还是之后,有什么证据能验证判断?
本篇把这个怀疑作为教学调查,练习为一次任务选择、组织和更新上下文。它不是读者真实报障,也不是已确认的程序缺陷。完成后,你会得到一份有来源、适用范围和未核实事项的调查工作单;应用代码保持现状。
下载完整材料 · 上下文简报 · 读者工作单 · 上一篇:项目约定与文档
核实日期:2026年10月4日。本机Kimi Code为2.0.2,作者只执行help/version和本地离线验证,没有真实Kimi对话、上下文压缩或DeepSeek调用。提示词和失真摘要均为教学材料,参考判断不是Agent生成实录。
一、上一课整理文件,这一课决定本次读什么
上一课把项目约定、当前状态、规格和单次任务分开了。但它们存在于磁盘上,不代表每次请求都应该把全部内容发送给模型。
这里的“上下文”,是模型处理当前任务时能利用的信息:你的要求、项目指令、已经加载的文件、对话历史、工具返回内容,以及工具提供的操作说明。仓库是信息来源;一次请求中实际提供的内容才是当时的输入。索引里写了文件路径,也不等于文件内容已经被读取。
上下文工程就是围绕任务管理这些信息。它包含选择哪些资料、先读哪一层、怎样标记来源和时效,以及何时删去失效结论、补读缺失证据。写好一句提示词是其中一部分,但不能代替提供正确资料。
例如,“仔细分析,不要出错”没有告诉助手当前首页走哪个函数;一份包含真实入口、现行R5规则和旧记录案例的简报,则让判断有了具体依据。
模型的上下文容量有限,文字通常以Token计量,不能简单按一个汉字等于一个Token换算。即使容量很大,放进去的信息仍可能过时、互相矛盾或缺少关键前提。增加输入也可能增加处理耗时与用量,具体取决于模型、缓存和计费方式。因此,我们追求的是足以完成当前判断的信息,而不是固定要求“越短越好”。
flowchart LR
A[本次要回答的问题] --> B[入口和现行规则]
B --> C[相关源码与独立案例]
C --> D[结论和未核实项]
D --> E{还缺什么证据}
E -->|有具体缺口| C
E -->|足够支撑本次交付| F[保存简短记录]
这条路径允许按需补读。过度精简也会出错:只给LIMIT 50,却省掉函数名和调用者,就删掉了判断最需要的背景。
二、从一个可独立使用的工作区开始
解压后进入外层lesson-06,它包含上一课的应用与文档。本篇project的38个文件、两个验证脚本和固定案例都与第05篇相同。
新增的工作材料集中在这里:
lesson-06/
README.md
AGENTS.md
project/
verify_search.py
search-cases.json
docs/
STATUS.md
specs/search.md
tasks/006-context.md
context/
search-review.md 本次任务的资料入口
worksheet.md 自己填写的调查记录
reference.md 完成后再看的作者答案
先读README、AGENTS、STATUS和任务006。docs/tasks/005-docs.md以及旧READING_CHECK保留上一课练习,文件开头已标注历史范围。上一课“本轮只整理项目约定”不会自动成为所有未来任务的永久限制;本课有自己的调查目标和允许范围。
本次只需编辑工作单、上下文简报和STATUS中的读者记录。不要为了验证一个还没确认的怀疑先改代码。如果你继续自己的仓库,先查看已有修改,记录工作副本和提交号;没有Git就记录目录与日期,不要虚构版本号。课程快照中的判断不能直接替代你改过的项目。
没有Kimi账户、没有安装Python环境,也能先做文件阅读和证据分类。实际执行离线检查需要Python3.11或以上与配套依赖,README给出了macOS/Linux和Windows的虚拟环境安装命令。只读练习不要求提前配置模型密钥。
三、先选资料,再写“请分析”
打开docs/context/worksheet.md,先填“为什么需要这份资料”,再读答案。针对“旧问题会不会被50条上限挡住”,第一批资料不多:
| 资料 | 要解决的疑问 | 这次读到什么程度 |
|---|---|---|
| 当前搜索契约 | 原本应该搜谁、匹配什么、显示多少 | R2、R4、R5及必要上下文 |
| web_app.py | 首页实际调用谁、身份从哪里来 | create_app里的完整home函数 |
| storage.py | 匹配、排序、停止与截取的先后关系 | 完整Store.search_history |
| search-cases.json | 怎样区分先限量与后限量 | S08/S09及owner C的51条记录 |
需要执行检查时,再读验证器的Fixture、StoreChecks和入口。需要解释旧说法时,再比较Store.history。API客户端、全部课程文章、个人数据库和所有历史聊天,暂时都不能直接回答这个问题,不必作为第一批输入。
这是一种按问题逐层展开的读法。你不是禁止助手进一步查找,而是要求它说明:现有证据缺了什么,下一份资料怎样补上这个缺口。例如,在代码里发现另一个首页入口,就有理由扩大调用路径检查;仅因为目录里有个文件,并不意味着必须读取它。
小文件可以完整读,大文件先定位到相关函数再读取周围内容。不要只保留一句命中行:过滤条件可能在上面,截断可能在下面,实际调用可能在另一个文件。源码位置最好同时记录“路径+函数名”;单独记第几行,在文件修改后容易失效。
配套search-review.md已经给出一份参考索引。你可以先自己选择,再比较遗漏,重点看每一项是否有明确用途,而不是机械追求相同文件数量。
四、用调用路径处理看似冲突的资料
先在project/web_app.py中找到首页的home。它调用的是:
result = store.search_history(session["owner"], keywords[0] if keywords else "")
这行至少提供两个事实:当前入口使用search_history,可见身份来自session。接着阅读project/storage.py中的完整方法,会看到它先按owner限定记录并按时间和ID降序排列,再逐条匹配问题文本。找到第51个匹配后停止,返回前50条和是否截断的标志。
旧的Store.history确实使用LIMIT 50,但当前首页没有调用它。一个旧函数的行为,不能直接证明另一条正在使用的调用路径存在缺陷。 这也不意味着你可以顺手删除旧函数;清理影响并不属于本次调查。
再读现行R5:搜索范围是本会话全部操作,结果展示最多50条。这里的“全部”描述参与匹配的范围,“50”描述展示上限,不要求把所有命中一次性显示出来。
固定案例把这层区别表达得很清楚:
- S08:owner C有51条记录,最旧的C01含“旧资料针”。查询这个词,应返回C01。
- S09:同一批记录,关键词为空,全部匹配。应显示C51到C02,共50条,并提示截断;C01仍存在。
如果先拿最近50条再找“旧资料针”,C01会在参与匹配前就被排除。当前实现并不是这条路径。匹配稀疏时,它可能扫描很多记录;这是值得以后评估的性能问题,却不能据此声称已经做过性能测试。
遇到材料冲突,不要简单按“更新日期最新”裁决。先分类:规格定义应有行为,源码描述当前实现,测试输出证明某次执行的观察,历史原稿记录当时状态。如果代码偏离当前已批准规格,应调查实现;如果需求已正式变化,应更新规格与案例。新写的错误摘要也可能比旧的正确契约更新。
本例中,archive里的“尚未实现”有明确历史范围,当前源码与STATUS可以解释差异。我们保留原稿,同时避免把它当成今天的待办。
五、交给Kimi的是任务和证据入口
若你已自行安装并登录Kimi Code,在外层lesson-06执行:
kimi --plan
这一步进入开发工具,后续发送任务可能消耗Kimi额度,与笔记助手的DeepSeek用量分开。本课建议只做一次调查请求,核对回答后结束;没有把自然语言“只调查”当成严格费用上限或技术沙箱。
当前CLI官方文档说明,输入@可补全文件路径,选中的引用会提供文件上下文;@文件引用与/命令是两种机制。可以输入@docs/context/,从补全中选择search-review.md。路径候选受当前目录影响,先确认你在外层工作区。Kimi输入与文件引用
接着发送以下任务。即使不用文件补全,明确要求读取这些路径也能表达任务,但仍应核对实际读取和回答的依据。
本轮任务006:只调查,不修改文件或运行应用,不读取个人配置和已有data。
先读根AGENTS.md、docs/STATUS.md、docs/tasks/006-context.md,
再读docs/context/search-review.md列出的第一批来源,先不要看reference答案。
教学假设是“当前首页先取最近50条,再搜索,所以旧问题可能漏掉”。
请沿当前home到存储方法的调用路径核对,并用R5、S08和S09解释判断。
将回答分为:已核对事实、还需验证的推断、不能确认的范围。
每项给出文件/函数或案例编号。若资料不够,先指出具体缺口。
不要因为旧规格写过未实现而重做搜索,不要扩展为答案搜索或性能优化。
本次不发起应用或额外外部模型请求,不运行测试命令;验证由我在本地另行执行。
预期是一份能顺着证据检查的调查结论。它应区分history和search_history,说明S08与S09并不矛盾,并承认自己没有运行测试。若它直接给出重写方案,先回到本次目标和实际入口,不要让未经证实的猜测变成新的施工计划。
你可以逐条打开它引用的文件,检查说法是否存在、是否漏掉条件。路径引用只是定位手段,不是正确性证明;“我已阅读”也不能代替这一步。
六、自己验证关键区别,不把模型回答当测试结果
完成静态阅读后,可以在外层lesson-06运行已有的定向存储检查。它使用公开构造案例和临时数据库,不读取你自己的运行资料。
macOS/Linux:
.venv/bin/python verify_search.py project --stage store
Windows PowerShell:
.\.venv\Scripts\python.exe verify_search.py project --stage store
预期为2个测试方法通过。其中test_spec_cases包含12个固定案例,另一个检查Unicode与非法类型边界。输出通常只列方法名,不逐条显示所有通过的子案例;不能因此以为只测了两条记录。失败时应结合子案例编号和断言定位,不把报错整段替换成“再优化一下”。
作者本轮在新材料目录实际执行了这条定向检查,并用同一批临时数据做了对照:先调用旧history再筛选“旧资料针”,得到空列表;调用当前search_history,得到C01。这个对照说明为什么调用路径重要,不代表线上曾发生过该故障,也不证明Kimi能稳定答对。
本轮没有修改应用或测试,未重新执行HTTP、预览和原应用的全部回归。上一课的检查记录仍是历史证据;本轮结论应写清自己实际做过的范围。你只完成阅读、没有安装环境时,就在工作单填写“静态核对,未运行测试”,而不是照抄作者的通过结论。
最后对照作者参考判断。合格结论类似:当前快照未证实所怀疑的“先取50条再搜索”问题,S08支持旧命中能够被找到;真实用户输入、数据和性能仍未核实。没有必要为了显得有产出而修改代码。
七、上下文需要更新,压缩不等于证据永久保存
调查过程中,最初的假设可能已经被证据修正。如果后续还在重复“存在旧记录漏搜缺陷”,它就会污染下一轮判断。请把工作单中的猜测改为有范围的结论,并在简报或STATUS里注明:依据哪个函数、哪个案例,实际执行了什么,什么还不知道。
对于持续增长的会话,Kimi当前官方文档说明接近上下文窗口上限时会自动压缩历史,也可手动执行/compact并附带保留重点;/new会切换到新会话。压缩是对历史的整理,不应拿来代替核对源文件。Kimi会话与上下文
若自己的会话确实已经很长,可在Kimi输入框中使用:
/compact 保留当前任务006、工作副本、R5与S08/S09、实际调用路径、已运行检查和未验证范围。
这是给压缩过程的提示,不能保证每个细节都保留下来。完成后检查摘要;后续判断依赖的关键函数和案例,可以再读取一次。短小的新会话没有必要为了练命令而强行压缩,本课也未实测压缩结果。
如果决定换新会话,先保存自己的结论与来源,再用/new并明确读取更新后的任务和状态。这里讲的是上下文重新建立;更完整的长任务中断与恢复放到第15篇。
试着修正工作单中的这句教学摘要:
搜索验证通过,所以系统绝不会漏记录,可以删除旧资料并重写查询加速。
至少有三处越界:固定案例通过不等于绝无遗漏;删除资料不在当前任务中;重写加速没有性能数据支持。好的摘要必须同时保留结论和限制,否则越压缩越像一份错误的新指令。
八、遇到这些情况,应该补哪一块信息
| 现象 | 先检查什么 |
|---|---|
| 引用路径不存在 | 当前目录、实际文件名和版本;不要直接复制另一课目录名 |
| 助手坚持搜索未实现 | 让它区分archive、当前STATUS与实际home调用路径 |
| 只看到LIMIT就提出修复 | 补完整函数、调用者和S08,要求先说明证据支持到哪里 |
| 回答全是架构建议,没有调查结论 | 重申本次问题和交付物,减少无关背景,保留必要来源 |
| 输出说已测试,但未见执行 | 要求写明命令与输出;无法核对就记未验证 |
| 压缩后忘了范围 | 对照持久工作单,重新读取当前任务、关键契约与源码 |
| 测试报缺少依赖 | 按README建立虚拟环境,使用其解释器;不要通过删除测试来绕过 |
再换一个问题练习选资料:有人说“我搜‘检索’,为什么找不到默认问题?”优先核对问题原文、输入词和R4。默认问题是“笔记中的RAG流程是什么?”,搜索只匹配问题字段;“检索”出现在笔记或答案里并不会自动让该问题命中。应先确认真实输入与用户期待,再判断是符合当前规则,还是需要讨论新的需求。
这时不必把API计费文档、全部生成日志和旧导出计划都放进上下文。任务变了,需要的证据也随之改变;资料入口可复用,具体选择仍要重新做。
完成本篇后,你的应用仍是同一个搜索版本,多了一份能解释判断依据的工作单。下一篇会利用这些规格、案例和调用边界,进一步讲清怎样设计测试和解释反馈,让“验证通过”本身也成为可以审查的结论。