资讯动态

context-mode 实战:从上下文管理到遗忘策略的完整落地指南

发布时间:2026/10/8 16:55:33 来源:尧图企业网站定制
做项目的人应该都有过这种经历需求文档里只躺着一个关键词比如 context-mode没有上下文没有验收标准。你问产品经理他说你懂的就是要有上下文的感觉你问技术负责人他说反正就是让系统能记住之前的状态。我在一个智能助手项目里恰好就被这个需求卡了两个星期——context-mode 看起来只是个简单的概念扯出来的却是上下文管理、状态机设计、窗口压缩、缓存策略一整串问题。这篇文章把我从概念理解到代码落地的完整过程记录下来尤其把那些文档里不会写的坑展开讲讲希望对正在做类似功能的同学有实际帮助。先交代项目背景一个面向企业内部的知识问答助手用户会连续提问系统需要结合对话历史、用户身份、当前页面场景等信息给出更贴合的答案。需求方给这个功能起的名字就叫 context-mode。我一开始以为这只是给对话加个历史记录真正动手之后发现这里面的设计空间比想象中大得多而且很多决策直接决定了产品体验的上限。所以这篇文章既讲是什么也讲怎么做更会把哪些地方容易翻车这件事说透。1. 先搞明白context-mode 到底是个什么东西1.1 从需求方那句模糊的要有上下文感觉说起需求方的原话是希望系统能记住我说过什么、做过什么然后根据这些来调整回答。 这句话拆开看有两个关键词记住和调整。记住是存储问题调整是决策问题两个缺一不可。如果只做存储不做决策那做出来的是一个日志系统如果只做决策不收信息那还是一个无状态接口。context-mode 的实质是把历史信息转化成当前行为的一整套机制。我最初犯的错误是把 context 简单等同于对话历史。后来在真实场景里才发现对话历史只是 context 里最浅的一层。真正影响回答质量的 context 还包括很多用户身份与偏好是谁在问他的职责范围是什么喜欢什么样的表达风格环境信息当前在哪个页面、用什么设备、大概什么时间段任务状态事情进行到哪一步了之前确认过哪些结论还有哪些悬而未决外部数据知识库里相关的文档片段、业务系统里的实时数据这些东西共同决定了用户当前这句话应该被怎么理解。理解偏了后面生成得再漂亮都是错的。有一个类比我觉得特别贴切context-mode 就像一个老练的柜员。你第一次去柜台办事他要问一堆问题第二次去他记得你上次办过什么直接说您上次那个业务还需要继续吗第三次去他扫一眼客户信息还没开口就知道你要什么。这个记住 调整的过程就是 context-mode 要做的事。1.2 不同领域里的 context-mode形态完全不同我在前期调研时发现一个有意思的现象context-mode 这个词在不同领域里指的东西差别非常大但大家都叫它 context-mode。这里整理一个对照表领域context-mode 的表现形态核心机制典型例子AI 对话系统多轮对话上下文理解上下文窗口管理、注入、压缩ChatGPT 的会话记忆功能IDE / 编辑器感知当前编辑文件的上下文代码语义分析、选中片段、相关代码检索Cursor 的代码库问答移动端系统上下文操作模式状态机切换、操作菜单按需展示Android 的 ActionMode传统企业软件界面状态与业务上下文联动状态保持、表单草稿、跨页面参数传递ERP 系统的上下文菜单这个表说明了一件事context-mode 没有统一的标准实现但所有形态都有一个一致的核心目标——让系统根据当前的境况做出差异化的响应。想明白这一点设计思路就清晰了不管最后用什么技术实现都要回答三个问题上下文从哪来、存在哪、怎么用。后面所有方案设计都是围绕这三个问题展开的。1.3 为什么 context-mode 最近成了高频需求这两年 context-mode 相关需求集中出现背后的原因不难理解。一方面大模型普及之后长上下文成了产品差异化的卖点各家都在做记忆、做个性化用户对系统应该记得我的预期被不断拉高。另一方面智能体和自动化工具越来越多系统需要理解用户所处的复杂场景才能做出正确决策对上下文感知能力的要求自然水涨船高。还有一个容易被忽略的诱因上下文管理的成本在快速下降。十多年前做上下文感知系统要自建知识图谱和推理引擎成本高得吓人今天向量数据库、嵌入模型、大模型推理都变便宜了做一个能用的 context-mode 比从前容易太多。门槛降低需求自然爆发。但门槛降低不等于做好容易真正让 context-mode 好用的往往是那些不起眼的细节——过滤什么、保留多少、什么时候忘掉。这些后面我会逐个展开。2. 设计 context-mode 的第一步先画边界2.1 两种根本不同的模式携带上下文 vs 感知上下文动手写代码之前我先做了一次需求拆解把模糊的要有上下文感觉拆成了两个完全不同的实现方向。第一种是携带上下文carrying context。系统把用户明确提供的信息、或者历史对话里出现过的关键信息传递到下一次决策中。典型场景是多轮对话用户先问帮我订周五去上海的机票再补一句要靠窗的位置——后一句话本身信息不完整必须结合前一句才能被正确理解。这种模式相对简单本质是一个带状态的数据流难点在于确定哪些信息值得传递、以什么形式传递。第二种是感知上下文perceiving context。系统主动从环境里捕捉信息自动判断当前应该进入什么状态不依赖用户明确表达。典型场景是智能助手根据用户访问的页面、停留时长、操作行为主动推断意图并调整回答。这种模式难在信息获取和意图判断很容易做出自作聪明的效果用户反而反感。注意我强烈建议先确定你要做的是哪一种不要两头兼顾。我见过太多项目希望一个 context-mode 既做显式上下文传递又做隐式上下文感知结果状态管理混乱、误判率居高不下、维护成本爆炸。稳妥的路径是从携带上下文开始跑通之后再逐步叠加感知能力。像我做企业知识问答助手最终落地的方案就是以携带上下文为主体只额外做了少量基于页面事件的环境感知这样系统行为是可预期的出问题也容易定位。2.2 上下文数据模型怎么建确定形态之后下一步是建立上下文的数据模型。这一小步直接决定后面所有代码的复杂度。我的建议是用一个统一的结构承载所有上下文而不是为每种上下文单独建类否则后期扩展和维护都会很痛苦。我在项目里用的核心结构是这样的Python 伪代码from dataclasses import dataclass, field from typing import Any, Dict, Optional import time dataclass class ContextItem: 单个上下文条目 key: str # 上下文的唯一标识例如 user.preference.seat value: Any # 上下文的值 source: str # 来源dialog / user_profile / page_event / knowledge_base timestamp: float # 记录时间用于过期判断 ttl: Optional[int] None # 有效期秒None 表示长期有效 priority: int 0 # 优先级冲突时决定谁覆盖谁 dataclass class ContextBucket: 一个作用域下的上下文集合 scope_id: str # 作用域用户ID / 会话ID / 页面ID items: Dict[str, ContextItem] field(default_factorydict) def set(self, key: str, value: Any, source: str, ttl: Optional[int] None, priority: int 0) - None: self.items[key] ContextItem( keykey, valuevalue, sourcesource, timestamptime.time(), ttlttl, prioritypriority ) def get(self, key: str) - Optional[Any]: item self.items.get(key) if item is None: return None if item.ttl is not None and time.time() - item.timestamp item.ttl: del self.items[key] # 过期即清理 return None return item.value这个结构有几个设计要点值得展开说说。第一所有上下文都带时间戳和 TTL。没有时间戳的上下文是最大的隐患你根本不知道一条信息是什么时候产生的自然也无法判断它现在还成不成立。用户上午说了一句我喜欢简洁的回答下午系统还拿这个偏好去套新问题得出的回答就可能让人莫名其妙。加了 TTL 之后短期上下文比如临时操作状态默认 5 分钟失效长期偏好比如用户身份可以设很长的 TTL 甚至不设过期。这个设计看起来简单但它把信息的新鲜度变成了一个显式可管理的属性排查问题的时候价值巨大。第二用 scope_id 做隔离。不同用户、不同会话、不同页面的上下文绝不能混在一起。我见过有人把所有上下文集放进一个全局字典测试时没问题一上生产数据就串了用户 A 的偏好跑到了用户 B 的回答里这是非常严重的事故。隔离是 context-mode 的第一安全要求涉及多租户的系统尤其要在这一层做好约束宁可在存储上多花点空间也不能让上下文跨作用域流动。第三source 字段留作审计与调试。当用户质问你为什么这么回答的时候你能直接追溯到是哪条上下文影响了决策。这个字段平时不起眼排障时却是救命稻草。我后面讲排查方法时会再提到没有来源标注的上下文系统基本等于出了问题只能靠猜。另外这个模型只是存储层的一个简化示意实际生产里还需要考虑持久化、并发写入和容量上限这些在后面的性能部分会详细讲。2.3 上下文生命周期五个阶段缺一不可context-mode 不只是把上下文存下来就完事而是要管理好它的完整生命周期。我总结为五个阶段采集、存储、注入、更新、过期。采集从对话、页面事件、用户操作等渠道获取原始信息规整成标准格式。采集阶段最容易犯的错是把所有信息都收进来不做过滤导致噪声大量堆积系统还没开始用就被垃圾信息淹没了。存储写入对应作用域的上下文桶做好隔离和过期标记。这一步的重点是写入策略——遇到已有的 key是覆盖、追加还是丢弃需要有一套清晰规则。注入系统做决策前从上下文桶里筛选相关条目拼入提示词或决策输入。筛选比写入更重要后面会专门讲。更新新信息到来时根据优先级和置信度决定是否覆盖旧值。没有更新机制的上下文系统很快就会充满过时信息。过期定期清理失效上下文防止桶无限膨胀。遗忘策略做得好不好直接决定长期体验。这里最容易踩的坑是只注入不更新。很多实现把上下文当只读缓存用户每次提问都注入同样的历史信息既浪费上下文窗口又可能因为信息过期给出错误回答。我建议把更新逻辑做成显式的至少在任务完成、关键信息确认这些节点强制刷新一次上下文。比如用户重新选定了某个配置旧的配置信息必须立刻失效而不是等 TTL 慢慢到期。3. 落地实现把 context-mode 写进你的应用3.1 最核心的难题上下文窗口放不下怎么办在 AI 应用场景里做 context-mode绕不开一个硬约束上下文窗口是有限资源。以常见的 8K token 模型为例一次最多能处理 8000 个 token折合汉字大概三四千字而企业用户的对话历史动辄几万 token。如果把所有历史一股脑塞进去第一个问题是超出窗口限制直接被截断第二个问题是上下文被塞满后模型注意力被大量无关信息稀释关键信息反而抓不住。解决这个问题业界主流的做法是三个思路组合使用滑动窗口、摘要压缩、检索召回。三者解决的问题不一样滑动窗口解决最近的信息要完整保留摘要压缩解决旧信息用最小体积保存要点检索召回解决跨会话、跨文档的相关信息怎么捞回来。在 8K token 的预算下我常用的大致分配方案是这样的区块预算占比说明系统提示词10%角色设定、规则说明核心上下文25%用户身份、当前任务状态、关键偏好最近对话窗口40%最近 1-2 轮完整对话原文历史摘要 检索结果25%滚动摘要或命中的知识片段这个比例不是金科玉律实际项目里要根据模型能力和业务特点调整但它体现了分层管理的核心思想不是所有上下文都重要必须按优先级分配稀缺资源。如果模型窗口更大比如到了 32K 或者 128K比例可以调整但先保核心、再保最近、最后补长尾这个顺序基本不变。我在项目里按照这个思路写了一个上下文组装器核心逻辑如下import tiktoken def count_tokens(text: str) - int: encoder tiktoken.encoding_for_model(gpt-3.5-turbo) return len(encoder.encode(text)) def assemble_context(system_prompt: str, core_context: dict, recent_messages: list, history_summary: str, retrieved_chunks: list, token_budget: int 8000) - str: parts [] used 0 # 1. 系统提示词固定优先注入 parts.append(system_prompt) used count_tokens(system_prompt) # 2. 核心上下文控制在预算 35% 以内 core_text format_core_context(core_context) if used count_tokens(core_text) token_budget * 0.35: parts.append(core_text) used count_tokens(core_text) # 3. 最近对话原文保留完整信息 recent_text format_messages(recent_messages[-2:]) if used count_tokens(recent_text) token_budget * 0.75: parts.append(recent_text) used count_tokens(recent_text) # 4. 历史摘要 检索结果挤占剩余空间 remaining token_budget - used - 200 # 预留回答空间 candidate history_summary \n \n.join(retrieved_chunks) if count_tokens(candidate) remaining: candidate truncate_by_tokens(candidate, remaining) parts.append(candidate) return \n\n.join(parts)代码里的format_core_context、format_messages、truncate_by_tokens是几个辅助函数作用分别是格式化核心参数字典、把最近消息列表渲染成文本、按 token 数截断文本逻辑都不复杂就不展开贴了。这个组装函数的核心思想是先保核心、再保最近、最后补长尾并且始终预留 200 token 给模型生成回答避免输入把窗口占满导致输出被截断。我在项目初期犯过这个错组装器算得刚刚好结果模型一句话没说完就断了后来才加上这个预留空间。我想特别解释一下为什么最近对话要保留完整原文而不是直接上摘要因为用户最近一两轮对话里往往藏着最关键意图如果在这里压缩丢失的信息量远比收益大。反而更早的历史用摘要或检索代替就足够。另外要注意这个预算分配里 200 token 的预留值是针对短回答场景的如果你的业务需要模型输出长文预留空间要相应加大比如留 500 到 1000 token。3.2 上下文注入让模型分清背景和问题上下文注入里有一个非常关键的细节很多人第一次做的时候会忽略不要让模型直接看到未经组织的原始上下文。直接把一堆历史记录贴在提示词前面模型很容易困惑分不清哪些是背景、哪些是当前指令、哪些是需要回答的问题。我在项目里总结了一种注入格式效果很稳定——在提示词里明确标注每一部分的身份【当前用户】张三研发部后端工程师偏好技术性深入的回答 【当前任务】正在排查接口超时问题已确认发生在网关层 【对话历史摘要】前两轮讨论过使用 Redis 缓存优化查询性能 【最近对话】 用户那我们把缓存失效时间设置成多久合适 助手建议先设置 5 分钟观察命中率再调整 【相关文档】《API 网关超时配置指南》中关于 read_timeout 的说明... 请基于以上上下文回答用户的最新问题用户说你觉得这个方案有没有风险这样组织的好处有两个第一模型清楚知道哪些是事实背景、哪些是待答问题答案的准确性明显提升第二调试时你能直接看到注入内容的完整构成一旦回答出错可以快速定位是哪个上下文片段导致的问题。这里还要提醒一点不要把所有上下文都塞进提示词里让模型自己悟。模型虽然有很强的推理能力但不代表它擅长从一堆杂乱信息里自动找到关键点。你把上下文结构组织得越清晰模型就越容易给出符合预期的回答。这个投入产出比非常高值得花时间打磨。3.3 上下文压缩与检索的实操细节压缩这一环我推荐两种方式配合使用。第一种是滚动摘要。每次上下文快装满时把旧对话交给模型生成一段结构化摘要用摘要替换原始内容。我在实现里用了这样的方式def compress_history(messages: list, max_tokens: int) - str: 把历史消息压缩成结构化摘要 compress_prompt ( 请把以下对话历史压缩成结构化摘要保留关键事实、用户偏好、 已确认的决策和未解决的问题。使用字段facts, decisions, preferences, open_issues。\n\n format_messages(messages) ) summary llm_complete(compress_prompt, max_tokensmax_tokens) return summary这里有一个实实在在的教训压缩摘要时一定要保留未解决的问题open_issues。我吃过一次亏摘要里只记了事实和决策把用户吐槽的问题漏掉了下一轮系统完全忘记用户的不满给出的回答让用户觉得你根本没在听我说话。未解决问题是上下文中优先级最高的一类必须最先保住。我后来甚至在摘要格式里把 open_issues 放在最前面确保模型在生成摘要时优先关注它。第二种是向量检索。把历史对话和知识库切块做嵌入每次提问时用当前问题检索最相关的内容片段。这种方法适合上下文跨度大、知识面广的场景比如企业知识问答。检索时有一个参数值得注意top-k 的选择。我实测下来k 取 4 到 6 效果比较平衡太少会漏关键信息太多会引入噪声。另外检索出的片段要按相关度重新排序后再注入提示词直接按数据库返回顺序拼进去效果往往不是最好的。3.4 把模块串起来会话型 context-mode 的完整流程把上面的模块串起来一条完整的会话型 context-mode 处理链路是这样的用户发来新提问系统按照用户 ID 和会话 ID 加载对应的 ContextBucket从桶里筛选核心上下文身份、偏好、任务状态从对话存储里取出最近两轮对话原文历史过长则先做滚动摘要压缩结合知识库检索结果按预算组装提示词调用模型生成回答回答完成后把本次交互写回上下文桶和对话存储清理过期失效的上下文条目这个流程看起来不复杂但实现时要特别小心并发问题。一个典型场景用户在同一时间发出两个请求两个请求都读到了旧上下文、各自生成回答后一个写入的上下文更新覆盖了前一个导致先请求产生的上下文影响丢失。解决办法是给上下文写入加锁或者采用乐观锁策略——读取时记录版本号写入时检查版本是否一致不一致就重试。我一开始图省事没做并发控制上线后偶尔出现用户明明说了两件事系统只记得后一件的诡异现象查了很久才定位到是并发覆盖。4. 典型应用场景与变体4.1 企业知识问答助手身份上下文怎么用我做的项目本质上就是这个场景。除了前面讲的上下文组装有一个容易忽视的点用户身份在上下文中的权重。企业知识问答里同一个问题不同身份的用户应该得到不同的回答。新员工问怎么申请云服务器回答应该侧重申请流程和合规要求资深工程师问同样的问题回答应该侧重技术参数、权限细节和高级用法。这就是 context-mode 的价值所在。我在实现时把用户身份信息放到核心上下文区并给了它很高的优先级确保它不会被后续对话挤掉。实操中还有一个细节用户的部门、职级这类信息一定要通过数据接口实时获取不能缓存在本地太久。这类信息可能在管理端被修改缓存时间长一点就会出现用户已经调岗了系统还按旧岗位回答的尴尬。我们的做法是身份类上下文设置天级别的 TTL并且在涉及权限确认的关键操作时强制刷新。这个细节做不做直接影响系统的可信度——用户发现自己信息变了系统没跟上对产品的信任会瞬间掉一个档次。4.2 IDE 与编程助手代码上下文的特殊性在 IDE 和编程助手场景里context-mode 的关注点完全不同。这里的核心不是对话历史而是代码语义上下文当前打开的文件、光标所在的函数、相关的调用链、项目的技术栈配置。做编程助手的人常说的上下文感知核心是在解决一个问题把大仓库的源码压缩进一个小窗口。Cursor、Copilot 这类工具在实现上高度依赖检索——把代码库切片、做索引、根据光标位置动态检索相关代码片段。这个思路和对话场景的向量检索本质一样只是数据源从对话变成了代码。这里有一个编程场景独有的坑代码上下文对时效性极其敏感。你刚改了某个函数签名下一个补全请求如果还引用旧的签名生成结果就完全错了。所以代码场景里上下文必须和编辑器的保存事件绑定、实时更新不能用 TTL 懒过期策略。这也是为什么 Cursor 这类工具会把当前文件内容单独作为一个高优先级上下文而不是依赖全局代码索引。如果你在做类似工具这个实时性设计一定要放在架构层面考虑而不是事后补救。4.3 移动端交互Android 的 Contextual Action Mode如果你在做移动端context-mode 还有一个完全不同的含义Android 里的 Contextual Action Mode上下文操作模式。长按列表项弹出来的上下文操作栏就是它的典型代表。这个模式的实现思路很值得借鉴本质是一种受控的状态切换长按触发startActionMode()进入上下文模式模式内显示专用的操作栏ActionMode隐藏常规导航用户选择操作或按返回键模式退出UI 恢复它要解决的核心问题是在特定操作语境下不让无关界面元素干扰用户。这跟 AI 场景的 context-mode 理念相通——都是根据当前处于什么场景决定展示什么、执行什么。工程上的提醒Android 的 ActionMode 坑不少。屏幕旋转等配置变化时 ActionMode 会被销毁需要手动恢复还有 ActionMode 和列表长按事件的状态同步问题。如果做类似交互建议把 ActionMode 的进入和退出封装成状态机避免在 Activity 里散落一堆 start/stop 调用否则状态很容易错乱。5. 踩坑实录context-mode 的常见问题与排查5.1 上下文污染系统记忆了不该记的东西这是 context-mode 最典型的问题。用户在对话里无意说了一句这个功能真难用系统就把难用当成长期评价记下来后续回答都带着歉意的口吻反复解释或道歉。这就是上下文污染——把一次性的情绪表达当成了长期偏好。排查思路是给上下文加来源标注和置信度。情绪化表达、单次事件写成低优先级、短 TTL 的临时条目只有多次重复出现的行为模式才升级为长期偏好。我在实现里加了一个观察窗口同一个偏好至少被观测到 2 到 3 次且间隔超过一定时间才写入长期上下文桶。这样既保留了有用的个性化信息又过滤掉了噪声。比如用户说一次我比较喜欢表格形式这只算临时表达如果三次提问都要求用表格系统才会把偏好表格展示写入长期偏好。这个门槛的取值需要根据产品调性来定要求高准确率就调高门槛要求快速个性化就调低门槛。5.2 上下文过期旧任务还在干扰新任务另一个高频问题是上下文过期用户已经结束上一个任务系统还沉浸在旧任务里对新任务的理解出现偏差。比如用户先问华东区的部署进度怎么样得到回答后紧接着说现在说说华南区吧——如果系统还带着华东区的上下文做假设答非所问几乎是必然的。解决办法是在上下文里加入任务边界标记。当系统检测到用户切换了任务主题就把旧任务相关的上下文降权甚至清除。检测的方法可以是关键词匹配、Embedding 相似度比对或者让模型显式判断用户是否开启了新任务。我实测下来用 Embedding 相似度判断主题切换的准确率不错而且实现简单。具体做法是维护一个当前任务主题向量每次新提问也计算一个向量两者相似度低于某个阈值就判定发生了任务切换。这个方法不完美但已经能覆盖绝大多数场景成本也很低。5.3 性能与内存失控上下文桶无限膨胀context-mode 最容易翻车的性能问题是上下文桶无限膨胀。不设上限的 ContextBucket 在长会话场景下会越积越多每次注入都要遍历全部条目延迟节节攀升token 消耗也在同步上涨。我的做法是给每个作用域的 ContextBucket 设置最大条目数比如 200 条超过上限时按最低优先级 最久未使用的规则淘汰。存储层要做分层热数据放 Redis 或内存冷数据落数据库。实践下来上下文存储同样遵循二八定律——日常用得上的上下文其实只有一小部分把有限资源留给高频条目才是正解。另外持久化要控制频率不需要每条上下文变更都写库可以做一个简单的脏标记每 30 秒或者每次会话结束时批量落库一次能省下不少不必要的 I/O。5.4 排查方法一个 debug 接口解决八成问题排查工具上我强烈建议做一个上下文可视化面板。哪怕是开发环境里最简单的 JSON 输出只要能看清当前会话的上下文桶里到底有什么调试效率就能上一个台阶。我维护了一个 debug 接口GET /debug/context/{session_id}它返回当前会话完整的上下文清单包括每条上下文的 key、value、来源、时间戳、TTL 和优先级。排查的通用思路是先看上下文桶有没有混入不该有的内容再看注入到提示词的内容是否被模型正确理解。大部分 context-mode 的 bug 都出在这两处要么上下文本身不对要么注入方式不对。还有一个非常实用的小技巧在模型生成回答时把模型实际看到的完整提示词完整记录到日志里。很多问题只看输入输出很难定位但拿到完整提示词后立刻就清楚了——比如系统提示词被截断了、历史摘要和检索内容顺序错了、核心上下文压根没注入进去这些都能一眼看出来。我后来养成了习惯凡是涉及 context-mode 的改动都要顺手看一眼这份日志能省掉大量来回猜的时间。6. 项目复盘几个值得长期坚持的体会6.1 会遗忘的 context-mode 才是好 context-mode做过一轮之后我对 context-mode 有了一个跟最初完全不同的理解。这个功能的核心其实不是记住而是遗忘。一个永不过期的上下文系统会随时间积累大量噪声让系统变得越来越迟钝。定期遗忘、按需遗忘、任务切换时主动遗忘这些遗忘策略做得好不好直接决定用户的长期体验。用户最怕的其实不是系统记不住而是系统记错了还自以为记住了。我后来在设计评审时都会把遗忘策略和记忆策略放在同等重要的位置去评审这个习惯帮我挡掉了好几个隐患。6.2 可观测性先行复杂逻辑后置我是在 debug 面板写完以后才真正看清自己系统的行为。在那之前很多问题靠猜。所以如果你准备做 context-mode我的真诚建议是第一件事不是写上下文组装逻辑而是先把上下文内容可视化做出来。有了这个工具后面所有调试工作都会顺畅很多。这听起来像废话但我见过太多团队先闷头写逻辑、上线后遇到问题才回头补观测工具代价高得多。可视化面板可以很简陋哪怕只是在日志里把 ContextBucket 的完整内容打出来也比什么都没有强。6.3 相关性永远大于数量做 context-mode 的人要始终把相关性筛选当作第一要务。塞进上下文窗口的每一段无关信息都在稀释模型对关键信息的注意力。宁可少放不可乱放。我在项目后期做了一轮上下文瘦身把很多感觉有用但实际没用的条目砍掉之后回答准确率反而提升了不少——这个结果让全组都很惊讶也让我对少即是多有了更深的体会。判断一条上下文该不该进窗口可以考虑一个问题如果这条信息不出现回答结果会不会受影响不会那就不要放。6.4 给上下文加版本号最后分享一个小技巧给上下文结构加版本号。当上下文结构升级比如新增字段、改变某些字段的语义时旧版本的数据可能导致模型理解混乱。我的做法是在 ContextBucket 上记录 schema_version每次结构变更后对旧数据做一次迁移迁移失败的条目直接清除。这个小习惯帮我避免了好几次上线后行为异常的事故成本很低收益很高。尤其是团队多人协作的时候有人改了上下文结构但没通知大家版本号能第一时间暴露出问题而不是等线上反馈。这篇文章是我实际项目里的记录不是标准答案。每个项目的 context-mode 都会有不同的约束和权衡但核心思路是一致的先定义边界再建数据模型最后持续打磨遗忘和筛选这两个环节。如果你正在做类似的功能希望这些经验和代码能帮你少踩几个坑也欢迎实践中有新的发现回来交流。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑