上下文窗口就那么大,放什么、不放什么,直接决定 Agent 跑不跑得起来。这本书讲的就是这件事:怎么把对的信息,在对的时间,塞进窗口里。
目录
第1章 上下文的诅咒
提示工程不够用了。这一章从 Context Rot 讲起,说清楚上下文越长,模型越容易犯的四种错。
第2章 三大手段:卸载、压缩、隔离
别再往提示词里硬塞。能往外丢的丢出去,能压短的压短,能隔开的隔开。每种手段的边界和代价都讲明白。
第3章 动态上下文实战
看 Cursor 怎么处理上下文,再比较 RAG 和 Agentic Search 到底差在哪、各自什么时候该上场。
第4章 Menlo 踩过的坑
KV 缓存为什么是绕不开的成本,以及"把文件系统当上下文"如何改变了整个架构思路。
第5章 长跑型 Agent 的上下文管理
压缩、串行接力、环境隔离,三种让 Agent 撑过长时间任务的具体办法。
上下文的诅咒
本章是 Hermes Engineering 系列第 2 模块的第 1 章。
AI 的任务已经从单次问答变成了持续项目。但有个反直觉的现象:上下文越多,模型反而越容易失焦。这就是上下文的诅咒,它从不报错,只是慢慢变糊。
从提示工程到上下文工程
提示工程到上下文工程,不是换了个词,是换了个活法。
早年的提示工程,目标很窄:写好一条提示,让模型在一次调用里给出想要的答案。它是战术,琢磨的是那一瞬间的措辞,作用范围也就是那一次调用。提示写得好,模型能聪明一下;调用结束,聪明也就结束了。
Agent 出现之后,事情变了。AI 能自己规划、调工具、跑多轮任务,性质从一次性问答变成了持续项目。这时候它要的不再是一条提示,而是完整的信息视野:系统指令、可用工具、历史对话、从外部检索来的知识,全都得在上下文里就位。
所以上下文工程不只是在写提示,它更像一门架构活。你要动态地、持续地帮 Agent 打理它的整个上下文状态。说白了,我们这批人正在从调提示词的,变成搭系统的。
Context Rot:上下文腐烂
模型越来越强,上下文窗口也越开越大,那为什么不直接把所有信息都塞进去?
因为所有大模型都绕不开一个硬约束:上下文腐烂(Context Rot)。上下文里的信息越多,模型精确回忆、做长距离推理的能力就越往下掉,而且掉得很平滑,你不容易察觉。
一句话:上下文越长越杂,模型越容易走神。
两个底层原因
第一,架构本身的局限。主流大模型都跑在 Transformer 上,每个 Token 都要和上下文里所有其他 Token 产生关联,关系数量是 N² 量级。上下文长度翻一倍,要处理的关系数差不多翻四倍。人的注意力也这样,信息越多,摊到每件事上的精力就越少。
第二,训练数据的偏差。模型预训练时读过的文本绝大多数是中短篇,它很会处理短序列,但长文本的经验少得可怜。
上下文腐烂最阴的地方在于它是结构性的:不会一下子崩,而是慢慢退化。模型不会冒出一句"我不行了",它只是开始答非所问、漏掉重点、逻辑漂走。
最危险的就在这里:它不报错,只是变糊。
四种失效模式
上下文腐烂是底层状态,落到具体任务上,会表现出四种失效模式:
上下文污染(Contamination):一次幻觉或者错误信息混进了上下文,后面还被当成事实接着用。一旦有毒数据进入 Agent 的认知循环,后面整条决策链都可能被带歪。
上下文干扰(Interference):上下文里信息太多,把模型的预训练知识盖住了。大量低价值的即时信息淹没了它本来的知识信号,让它在噪声里迷失,做出违背常识的判断。
上下文混淆(Confusion):多余的、不相关的语境干扰了最终回答。模型注意力被摊薄,抓不住核心逻辑,还会把两个不相干的概念乱连到一起。
上下文冲突(Conflict):上下文不同部分互相矛盾。系统提示说"保持简洁",历史对话里却是一堆冗长例子,模型左右为难,行为变得混乱或者犹豫不决。
Context Rot(上下文腐烂)
├─ 上下文污染:幻觉渗入被当事实 → 决策链条被污染
├─ 上下文干扰:低价值信息淹没常识 → 违背常识的判断
├─ 上下文混淆:注意力稀释,错误关联 → 核心逻辑丢失
└─ 上下文冲突:矛盾信息导致行为混乱 → 模型犹豫混乱
最终:系统输出质量下降
图解:Context Rot 是病因,四种失效模式是并发症。模型不报错,只是慢慢变糊。
因果关系
打个比方。上下文腐烂是病根,四种失效模式是并发症。一个精神饱满的司机,烂路也能开过去;一个疲劳的司机,同样的烂路出事概率高得多。
腐烂带来的注意力稀释和信噪比下降,会直接引发干扰和混淆。模型在腐烂状态下推理能力本来就弱,更容易产生幻觉,等于自己往上下文里投毒。更麻烦的是,腐烂还会遮住模型的眼睛:相隔很远的两条矛盾信息,可能已经超出了它有效的注意力范围,它根本发现不了冲突。
任务进化:单次问答 → 持续项目
↓
Agent 运行依赖动态上下文
↓
Transformer 结构:上下文越多,性能越容易腐烂
↓
上下文工程成为高可靠 Agent 的必修课
图解:任务复杂度的进化撞上了 Transformer 的物理墙。不主动设计上下文,腐烂就会吞噬 Agent 的判断力。
把整条逻辑串起来:任务变复杂,Agent 跑起来依赖动态上下文,而 Transformer 结构决定了上下文越多越容易腐烂,于是上下文工程成了高可靠 Agent 的必修课。
所以真正的出路不是等一个无限大的内存,而是自己上手当上下文架构师,用工程方法主动设计上下文,让模型一直保持清醒和聚焦。
常见错误
三大支柱
本章是 Hermes Engineering 系列第 2 模块的第 2 章。
业内做 Agent 的头部团队,不约而同地收敛到同一套架构:一个极简的原子函数调用层,加上一个庞大的、可供探索的外部文件系统和脚本库。这不是谁的拍脑袋设计,而是整个行业为了兼顾"能力要无限扩展"和"上下文窗口就那么大"这两个死对头,一步步演化出来的解法。
核心矛盾
Agent 说白了就是个在循环里调工具的大语言模型。这个简单的循环一旦碰到长任务,就会炸出一个大问题:上下文爆炸。Menlo 提过一个典型任务平均要调 50 次工具,Anthropic 也佐证过,生产级 Agent 的对话轮次能拉到几百轮。
这意味着模型每走一步,都得背着前面所有轮次的工具结果。成本和时间先不提,最要命的是上下文会腐烂。
所以核心矛盾就在这:Agent 任务天生会产出海量上下文,可模型在海量上下文下偏偏越来越不行。
上下文工程干的事,就是用刚好够下一步用的正确信息,把窗口填满。它拆下来是三根支柱:
核心矛盾:任务产生巨量上下文,但模型性能随上下文增加而下降
├─ 卸载 Offloading:文件系统即上下文 / 分层行动空间 / 渐进式披露
├─ 缩减 Reduction:可逆压缩·指针替代 / 不可逆摘要·最后手段
└─ 隔离 Isolation:通信模式·低成本 / 共享上下文·全视野
底座:极简原子函数层 + 庞大外部文件系统
图解:三大支柱的共同目标,是让模型在每一步只看它需要的东西。多一点是噪音,少一点是盲区。
支柱一:卸载
卸载这件事,已经从"卸数据"走到了"卸工具"。
先说卸数据。给 Agent 一个文件系统,它就能在长任务里把信息存下来、以后想起来。Anthropic 的多 Agent 研究里,Agent 会把计划写进文件,干完子任务再读回来,确保没跑偏。Claude Code 的 .claude.md 也是这个思路,让 Agent 在多次调用之间把用户偏好持久存住。
再说卸工具,也就是分层行动空间。要是把 100 个工具全塞进 Prompt,模型会犯晕,Prompt 也会胀爆。Menlo 的解法是把函数调用层压到极简,只留少数原子工具(bash 加文件操作),其余动作全部卸载成文件系统里的脚本。
你看几个顶级 Agent 的原生工具数都少得可怜:Claude Code 大概 12 个,Menlo 不到 20 个,Deep Agents 只有 11 个。
再往前走一步,是渐进式披露。连脚本都不用一上来全告诉模型。Agent 启动时只加载每个 Skill 的标题,真要用了才把完整内容读进来。它靠 bash 工具在自己那堆脚本目录里翻,找到说明书自己看。
三层行动空间
Menlo 把行动空间由内到外分了三层。
第一层是函数调用,也就是原子操作。这是唯一一层直接跟模型打交道,只有极少数固定不变的原子函数。它拿灵活性换了可靠性和性能,模式安全、缓存友好。
第二层是沙盒里的现成程序,走命令行。Agent 通过 execute_shell 跑预装好的工具。模型被教着去自己发现、自己学:引导提示告诉它工具目录在哪,它主动 ls 看有什么,再跑 --help 学用法。这一层适合那种能等一下的复杂离线任务。
第三层是包和 API,也就是写代码。最开放,能力也最强。Agent 自己写 Python 脚本去调任意 API。什么时候才走到这层?只有前两层的现成工具都搞不定时,它才会做出"我得写代码了"这个决定。
站在模型的角度看,它根本不知道有三层。它最后要做的,无非是调第一层那几个原子函数。接口简洁、缓存友好、设计正交。
唯一的接口(模型视角)
├─ 第一层 函数调用:少数原子操作(极简固定、模式安全)
├─ 第二层 沙盒使用程序:execute_shell 跑预装工具(按需发现、自主学习)
└─ 第三层 包和 API:Agent 写 Python 脚本(能力缺口时才触发)
特性:第一层可靠+缓存友好,第二层灵活+可扩展,第三层开放+最强能力
图解:三层行动空间对模型完全透明。它只看到几个原子函数,但靠这几个就能撬动整个工具世界。
支柱二:缩减
先说压缩,它是可逆的。工具结果放旧了,就把完整内容挪到文件里,在历史消息中换成指向那个文件的指针。以后 Agent 还能 100% 把原始信息捞回来。
压缩不等于摘要。压缩是把内容无损地外移,用个轻指针顶替;摘要是有损、不可逆的,只有在压缩实在省不下多少时才当最后手段用。
执行上讲究顺序:先反复压缩,等压缩收益变小了,再上摘要。做摘要之前,先把完整上下文卸到日志文件里买份保险。压缩只压旧的 50%,最新的几个完整工具调用留着当 Few-shot 示例,帮模型校准行为。摘要必须基于完整版本,不能拿已经压过的东西再压。
再定一个浅腐烂阈值,大概 128K 到 200K Token,到这个数优先压缩,快触顶了才开摘要。
支柱三:隔离
隔离有两种搞法。
一种是通过通信。主 Agent 给子 Agent 丢一句简短指令,子 Agent 在一个干干净净的隔离上下文里把活干完,只把最终结果递回来。成本低、延迟低、KV 缓存也友好,适合那种能切得清清楚楚的简单任务。
另一种是通过共享上下文。子 Agent 被允许看主 Agent 的完整历史,但换一套新的 System Prompt 来行动。好处是带着完整视野能啃复杂任务,代价是 KV 缓存彻底失效,全价预填充成本得照付。
业界共识
说到底,所有顶级的生产级 Agent 都收敛到了同一套打过实战的架构:极简的原子函数调用层,加上庞大的、能自己探索的文件系统和脚本库。上下文工程也就此从零散技巧,变成了一套系统化的设计思路。
动态上下文与实战
本章是 Hermes Engineering 系列第 2 模块的第 3 章。
上下文的设计思路正在从"一次性塞满"转向"按需发现"。模型当 Agent 的能力越来越强,这时候反而该少给点细节,让 Agent 自己按需去拣相关的上下文。
静态上下文:AI 的出厂设置
静态上下文是智能体在启动前就备好的:它是谁、能干什么、该怎么干。AI 的出厂配置由三大核心组件构成:
系统提示是 AI 的灵魂,定下模型的身份、职责和处事方式。关键是粒度要合适:太细,写成伪代码一样的 if-else 硬编码,模型就僵了;太虚,一句"请像专家一样思考",输出就开始飘。做法是用结构化分层加迭代优化,先丢一个最小版本测,再针对性补。
工具是 AI 的手和眼,负责跟外部世界打交道。但工具的定义本身也算上下文:每个工具的名字、描述、输入输出说明,都在占模型的注意力预算。所以原则是最小可行工具集,只留能完成任务的那最小一组。连人类工程师自己都拿不准该用哪个工具时,就别指望 AI 能选对。
示例是告诉模型你希望它怎么想、怎么答。它不是让模型背答案,而是教一种思考方式。示例堆太多,上下文就胀了。好的示例不追求覆盖所有情况,而是亮出一种思考模式,价值在代表性,不在数量。
动态发现:Cursor 的五大实践
Cursor 团队有个判断:当下模型的能力、成本、可靠性都还受约束,最稳的路线是选更简单、更可控、也更好演化的原语,拿来当外部系统的底座。
实践一:工具响应转文件
Agent 跑一个数据库迁移脚本,终端吐出 5000 行日志。传统做法是截断到 2000 字符,可关键报错偏偏可能藏在被截掉的那截里。Cursor 不这么干:把输出完整写进文件,不塞进上下文,只跟 Agent 说"结果在这儿"。再配一个 Tail 工具从末尾开始探,末尾信息够用就收手,不够再往里展开。先探后展开,直到信息刚好够用。
实践二:摘要时引用对话历史
对话太长必须摘要时,原始完整对话被转存成文本文件。Agent 脑子里只留简短摘要,但手里攥着历史文件的路径。一旦发现摘要里的信息不够,就停下来去搜历史文件,把具体细节精准捞回来。这就像开卷考试,脑子里只记重点脉络,细节随时能翻书查。
实践三:Skills 按需加载
所有 Skill 的全文塞进 System Prompt,会严重膨胀。Cursor 的做法是静态上下文里只留名称和描述,全文等用到了再加载。能靠 Grep 关键词搜就先用关键词,关键词不够再上语义匹配。
实践四:MCP 工具按需加载
传统做法是把所有工具说明书塞进 Prompt,100 个工具很可能吃掉 5 万 Token。Cursor 把它卸载到文件系统,初始 Prompt 只留一个极简菜单。Agent 看到菜单、意识到需要某项能力时,主动去读说明书文件。Token 消耗因此降了 46.9%。
实践五:终端会话视为文件
集成终端的所有输出,无感写入本地日志文件。用户说一句"修好它",Agent 不需要你粘贴任何上下文,自己读终端日志、grep 定位 error、分析堆栈、给出修复建议。整个过程你一次复制粘贴都不用。
RAG vs Agentic Search
RAG vs Agentic Search
用户问题
├─ RAG(推理前检索):问题向量化 → 向量数据库查找 → 拼到上下文 → 模型回答
└─ Agentic Search(即时检索):模型思考是否需要信息 → 执行 list_files
→ 观察结果 → 选择打开文件 → 信息够吗?够就停,不够继续探索
混合策略最优:启动时 RAG 预加载,运行时 Agentic Search 探索
图解:RAG 是"考试前发的复习提纲",Agentic Search 是"开卷考试现场翻书"。两者结合才是最优解。推理前检索,也就是 RAG:问题向量化,去向量库找相似片段,拼进上下文,再交给模型。它稳、快、便宜,但信息可能过时,检索不够聪明,也没法主动探索,模型只能被动等投喂。
即时检索,也就是 Agentic Search:模型先想"我需不需要信息",要的话就调工具,执行 list_files、看返回、选文件打开、读前几行,再决定下一步。信息永远最新,只取当下要的,而且能探索。
把两者混着用通常最稳。Claude Code 启动时预加载 CLAUDE.md(这是 RAG),运行时又配了 glob、read 工具(这是 Agentic Search)。
智能探索有两个关键机制。一个是元数据:Agent 不光看内容,还能理解信息结构,文件名、目录、时间戳都是给它指方向的信号。另一个是渐进式披露:别一次把所有信息塞进去,让模型一步步发现。
行业趋势在收敛
Cursor、Minecraft、Devin,还有 Anthropic 的 Skill 机制,不同团队在不同产品形态下,各自独立收敛到了一套很像的工程思路:上下文是稀缺内存,文件系统是近乎无限的外部存储,卸载是缓解压力的基本手段,渐进式披露是默认策略。
Menlo 的教训
本章是 Hermes Engineering 系列第 2 模块的第 4 章。
这是一个真实项目的上下文工程记录:一开始要在微调和上下文工程之间做关键抉择,后面接着是 KV 缓存优化、把文件系统当上下文这些实战经验。
关键决策:微调还是上下文工程
Menlo AI 碰上了每个 AI 产品团队起步时都要纠结的问题:花几周去微调一个专属模型,还是直接基于前沿大模型,轻快地做上下文工程?
打个比方,把一位通才医生培养成专科专家,有两条路。微调是让他去专科深造:拿海量专业病例喂模型,让它专项学习,直接改内部权重。新技能被内化成一种本能,可反馈周期按周算,一旦底层模型换代,之前的投入就很不值钱。上下文工程是给他一套临床指南:不改通才本身,每次干活前发一套完美的指南。模型没真成专家,但每次任务里都表现得像那么回事。迭代快、门槛低、适应性强。
Menlo 选了上下文工程。对绝大多数想转 AI 的团队,我的建议也是默认从上下文工程起步,迭代更快、门槛更低,能很快攒出原型去验证。
KV 缓存命中率:北极星指标
Agent 在多轮循环里反复提交又长又大部分重复的上下文,直接推高了延迟和成本。Menlo 觉得,有一个指标最该盯死,就是 KV 缓存命中率,它是生产级 Agent 最重要的单一指标。
LLM 处理文本时,会把对前面每个 Token 的理解缓存下来。推理引擎用前缀匹配:第一次调用时完整算一遍前缀并缓存,第二次调用发现开头一致,就直接加载缓存,只对新增内容做增量计算。
缓存命中率高,就意味着又快又便宜。输入 10000 Token,其中 9000 命中缓存,成本能从 3 美分掉到 0.57 美分,省下 81%。
KV 缓存工作机制
首次调用:完整计算前缀 Token → 缓存 KV 状态
后续调用:检测前缀是否匹配?
├─ 匹配 → 直接加载缓存,只做增量计算(成本降 81%,延迟大降)
└─ 不匹配 → 重新计算全部(成本全价,延迟高,缓存失效)
图解:KV 缓存命中率是生产级 Agent 的北极星指标。前缀一个字符变了,缓存就全废。五大黄金法则
围绕 KV 缓存,Menlo 总结了五条:
开启与选型:选支持高效 KV 缓存的推理框架,比如 vLLM
保证会话保持:同一用户的会话路由到同一个工作进程
保持前缀稳定:Prompt 前缀里哪怕改一个字符,缓存就失效
上下文只追加:最友好的操作是在末尾追加,任何中间修改都是缓存杀手
明确标记缓存断点:手动插特殊标记,告诉引擎前缀到哪为止
F1 赛车 vs 全地形越野车
两种模式摆在这儿。F1 赛车模式:固定 Prompt 前缀,把 KV 缓存命中率拉到最高,延迟和成本都压到极致,但扩展性差。全地形越野车模式:动态选上下文,扩展性强,代价是牺牲缓存复用。选哪种,看你业务要什么。
文件系统即上下文
现在的模型上下文窗口越开越大,可在真实 Agent 场景里常常还是不够,甚至成了包袱:物理限制、性能衰减(也就是 Context Rot)、成本高。
压缩有个坑:任何不可逆的压缩都冒着语义丢失的风险。Agent 得靠着历史状态做预测,你根本没法确定哪一步的 Observation 在十步之后还关键。
Menlo 的做法是换个思路:不再靠模型上下文存所有历史,而是把文件系统本身当成 Agent 的外部长期记忆。这等于把架构从内存上下文搬到了外部语义存储。
这么干有三个好处。一是文件系统的空间几乎无限,网页、PDF、代码库天生就能往里塞。二是存进去的数据能长期留着,中间产物也能用结构化方式摆好。三是大模型不再被动等上下文喂,而是被给了工具去主动操作文件系统,"上下文"这个词的外延,从 Token 窗口扩成了 Agent 能交互、能读能写的一个持久化世界。
闪电大脑 + 无限硬盘
Transformer 模型强,但计算成本高得吓人;新兴的 SSM 架构(比如 Mamba)速度快,可长距离记忆是短板。这俩刚好能凑成一对:SSM 当闪电大脑,高效处理眼前任务;文件系统当无限硬盘,把长期记忆原样保住。某种程度上,这就是神经图灵机那个老想法在现代技术下的落地。
运行 Agent
本章是 Hermes Engineering 系列第 2 模块的第 5 章。
Agent 要连跑几百轮,上下文早晚会爆。这一章讲三件事:压缩、串行接力、环境管理。Anthropic 的思路是,在不放弃单 Agent 决策流的前提下,想办法绕开上下文窗口那道物理墙。
压缩策略
上下文一溢出,压缩就是第一道防线。但得说清楚,压缩是有损的。一段一万字的对话压成五百字摘要,细节不可能全留住。
Claude Code 里的做法是让模型自己总结历史对话的核心要点:关键决策、还没解决的问题、重要细节,再把那些冗余的工具调用结果清掉,尽量用最小的信息损耗接着干。顺序是先保召回,能留的都先留着,再慢慢提精度,把重复和无关的东西剔掉。
还有一招更持久:结构化笔记。Agent 干活的间隙定期写笔记,把关键内容存到上下文之外的记忆系统里。Claude Code 会维护一个 notes.md,记下任务目标、没干完的事、依赖关系。哪怕上下文窗口整个被清空,AI 也能从笔记里把思路捡回来。
压缩与摘要的精细管理
Menlo 把缩减操作拆成两类,界限划得很死。压缩是可逆、无损的外部化:用轻量指针替掉原始信息,比如拿文件路径代替文件内容、拿 URL 代替网页 HTML。摘要则是有损、不可逆的,只有压缩实在省不下多少时才当最后手段。
有个铁律叫"先卸载再摘要":做摘要之前,先把完整上下文写进日志文件,给这个不可逆操作买份保险。
具体怎么执行?先定一个浅腐烂阈值,大概 128K 到 200K Token,触到这个数就优先压缩,等压缩收益变小了再上摘要。只压旧的 50%,最新的完整工具调用留着当 Few-shot 示例。原因很实在:模型是个强力模仿者,你给它看的要是全是残缺格式,它就以为那是对的。摘要必须基于完整版本,最后几个完整的"行动-观察"对要留着,当作让任务不断线的锚点。
串行接力:Anthropic 的方案
单 Agent 决策是统一的,可上下文窗口就那么大。要求从"写个函数"涨到"开发复杂 Web 应用"时,成千上万行代码分分钟撑爆窗口。多 Agent 并行容易互相打架,单 Agent 串行又不够用。
Anthropic 的解法有点巧:还是一个 Agent,但分两个阶段跑。
第一个是初始化 Agent,只活在项目第一天。它不写业务代码,只搭架子:配服务器环境、建进度打卡表、初始化 Git 仓库,让后面的工作有据可查,把那些藏在脑子里的隐性知识变成白纸黑字的文档。
第二个是编码 Agent,真正干活的那个,在之后成百上千次会话里执行,但被套了严格约束,走增量循环:每次"醒来"领一个任务,写完测试,然后提交。
整章绕不开的一个概念叫 Clean State(干净状态):不管你这一班干了多少,交接前必须保证代码能跑通、文档已更新,达到能合进主分支的标准。烂摊子不能留给下一班,编译报错的代码更不行。
串行接力:一个 Agent,两个阶段
[阶段一] 初始化 Agent(仅项目第一天)
初始化仓库 → 创建进度表 + 环境脚本 → 输出初始化文档
[阶段二] 编码 Agent(成百上千次会话,loop)
读取功能清单 → 领取 passes=false 的任务 → 实现功能 + 写测试
→ 提交代码 → 更新功能清单 → Clean State 合并
外部依赖:文件 / 日志、Git 仓库
图解:Clean State 是跨会话接力的生命线。任何一班 Agent 都不能把烂摊子留给下一班。
外部记忆系统
内部记忆靠不住,那就把记忆挪到模型脑子外面,靠文件和日志去了解项目,而不是靠上下文窗口。
启动序列
对 Agent 来说,每一次会话都像重新开始,得赶紧把项目理解捡回来。标准动作就六步:定位(pwd 确认目录)、回忆(读进度记录和 Git 历史)、领任务(读功能清单找没过的条目)、复原(init.sh 启动环境)、验证(确认基础功能正常)、开工。
功能清单用 JSON 而不是 Markdown,图的就是结构硬:Agent 改起来不容易把格式搞坏。Prompt 里也锁死,只允许它改 passes 字段,测试描述一个字不能动。
端到端测试走 Puppeteer:Agent 拉起开发环境,模拟用户操作,靠截图验证前端界面。光看后端数据库多了一条记录就宣布成功是不够的,得亲眼确认侧边栏变了、输入框清空了这些细节。