老新人入手“context-mode”:一个把AI上下文管理做成“模式切换”的实战复盘
做AI应用开发这么久,我踩过最深的一个坑,就是上下文管理。你不把“上下文”当回事,它就会在关键时刻给你来一记回旋踢——要么AI忘了三十分钟前你交代的约束,生成一堆看似正确实则跑偏的代码;要么上下文越攒越肥,每一轮请求的延迟肉眼可见,token开销哗哗地流。
后来我在某个内部工具里做了一个叫“context-mode”的小方案,本质上就是把“上下文”从一段糊涂账,拆成几种显式的、可以随时切换的“模式”。这篇文章不聊什么高深理论,纯粹是把我从需求拆解、方案设计到落地实现的全过程,以及中间踩过的坑、试错后的补救措施,原原本本写下来。如果你也在做Agent、AI辅助编程插件,或者任何依赖长期记忆的AI产品,这篇能帮你少走不少弯路。
先说清楚“context-mode”这玩意儿能做什么。它可以理解为一个上下文管理中间层,把AI对话、代码生成、长文档处理共用一套“模式化上下文”底座。它解决的问题有三个:第一,AI不会因为上下文太长而“迷失重点”;第二,不同任务类型有不同上下文策略,不用一个上下文模板打天下;第三,上下文可以结构化复用,而不是每次重新灌输。
适合谁来参考?说实话,只要你在做稍微复杂点的AI应用,不管你是只用API调用的初级开发者,还是在搞RAG、Agent框架的进阶玩家,都会用得上。接下来我会用我真实实践中的设计思路和代码片段,带你把这个方案完整拆开。
1. 内容整体设计与思路拆解
1.1 从一次“翻车”现场讲起:为什么要做context-mode
事情起源于某一次用AI重构一个老模块。我一开始把项目背景、编码规范、依赖关系全塞进一个超长Prompt里,让AI先通读再动手改。前两轮还行,第三轮开始它就有点“失忆”了,改着改着弃用了我们约定的错误处理方式,自己发明了一套异常类。我当时的第一反应是“模型不够聪明”,后来回头一查才发现,问题是出在我自己身上——我给AI提供的信息是一大坨无差别的文本。它没有区分“必须严格遵守的规范”“仅供参考的背景知识”“临时插入的需求变更”这几类信息的优先级。模型是概率模型,只要上下文中后面出现了新的内容,前文的约束权重就会被冲淡,它自然会偏向最近看到的信息。
这个场景其实特别典型。做AI应用的人都会遇到一个两难:上下文给少了,AI缺乏足够背景,回答质量断崖式下跌;给多了,不仅费用涨、延迟高,还可能引入干扰噪声。核心矛盾在于,上下文不是一个单一的“量”的概念,它是一个“结构”的概念。不同的任务阶段、不同的任务类型,AI需要关注的信息范围完全不同。正因为想通了这一点,我才决心做一个“context-mode”:把上下文的管理权利从模糊的“把它全部拼起来”改成清晰的“按模式切换”。
1.2 context-mode的核心思路:把上下文拆成“模式”而不是堆成“长串”
传统的上下文管理,最粗暴的做法就是把所有历史记录拼接起来,按时间顺序一股脑发给模型。这种做法有两个致命缺陷:一是历史越长,噪声越多,模型提取关键信息的难度呈指数级上升;二是有些信息是“状态”而不是“历史”,例如某次对话中用户更正过一个偏好:“不要用Python的typing模块”。这条信息必须长期生效,但它不应该永远占据Prompt中显眼的位置,更不该被后来一大段无关闲聊淹没。
“context-mode”的思路是用一组并列的上下文槽位,取代单个持续增长的上下文窗口。每一个模式对应一组结构化的上下文内容,比如:
- System Context(系统级上下文):全局不变的规则、项目背景、模型行为约束。
- Task Context(任务级上下文):当前任务的目标、交付物、验收标准、限制条件。
- Conversation Context(会话级上下文):对话中的临时状态、用户偏好、已经确认的决策。
- Episodic Context(片段级上下文):一段较长的历史记录,主要用于回溯,但不是每次请求都完整带入。
这四个模式不是互斥的,而是分层嵌套的。每个模式有自己的生命周期和持久化策略,系统可以根据当前任务类型动态决定把哪些模式合并进最终的Prompt。你可以把这种设计理解成一个“衣柜整理术”——以前你把春夏秋冬的衣服全堆在一个衣柜里,每次找衣服都要从头翻一遍;现在你给它打了隔断,分了区,当下是什么季节,直接打开对应那一格就行。模型要处理的信息量立刻小了很多,信噪比也提升了。
1.3 方案选型:为什么选用“规则+模板”而不是全交给模型
在设计过程中,我纠结过一个问题:要不要引入一个LLM来动态决定“当前应该使用哪种上下文模式”?听起来很智能,但是深入想了几天之后还是放弃了。原因有二:
第一,递归调用LLM来管理LLM的上下文,一旦判断出错,错误会被放大,而且排查起来极难。第二,成本和延迟不可控,每一次请求前还要再额外调一次模型,等于让整个系统的响应时间翻倍。最后我选的是“规则+模板”的轻量方案——用一个明确的规则引擎(其实就是一些小函数)来决定上下文模式的切换,每个模式有固定的模板结构和填充字段,简单直接,可审计,可回退。
这套思路的实际维护成本也比较低。因为规则是显式的,团队成员review代码时一眼就能看懂“什么时候走精简模式”“什么时候走详细模式”,不需要像看待黑盒一样去猜模型行为。我认为这个决策是整个项目后期能顺利推进的关键。
2. 核心细节解析与实操要点
2.1 数据结构设计:Mode的实体定义与状态流转
context-mode的数据结构是整套方案的地基。我最早设计时走了一些弯路,一开始只定义了一个字符串字段存模式名,后来发现远远不够。经过几轮迭代,最终我定义了一个模式对象,包含四个核心字段:
- mode_type:模式类型,对应System、Task、Conversation、Episodic四种。
- payload:上下文内容,用字典结构保存,而不是字符串,这样可以在填充时支持字段级覆盖。
- expires_at:过期时间,用于处理临时上下文,比如一个任务完成之后,相关上下文自动清理。
- priority:优先级权重,当不同模式的上下文内容冲突时(例如任务级要求忽略某条系统级规范),以高优先级为准。
初始的时候,状态流转我设计得比较复杂,有八个状态互相转换,后来实际用起来发现根本记不住。我砍掉了大部分状态,只保留三个:active、suspended、archived。Active表示当前请求会带上这个模式;Suspended表示暂时不参与请求,但也没有删除;Archived表示这个模式已经结束使命,只保留索引用于追溯,不进入Prompt。
这种简化的好处很明显:状态少了,心智负担就低了。你在排查问题时只需要问三个问题——这个模式是不是活跃的?它是不是被挂起了?它是不是已经归档了?没有第四种情况。项目上线后,因为状态错乱导致的问题数量几乎降为零。
2.2 核心实现:上下文构建器(Context Builder)的设计
context-mode的枢纽是一个叫Context Builder的模块,它的作用是把当前所有“活跃”模式按照一定策略合并成最终的Prompt上下文。
我实现它的核心代码大致如下(这里展示一个简化版,去掉了一些项目特殊的依赖):
from dataclasses import dataclass, field from typing import Any, Dict, List from enum import Enum from datetime import datetime class ModeType(str, Enum): SYSTEM = "system" TASK = "task" CONVERSATION = "conversation" EPISODIC = "episodic" class ModeStatus(str, Enum): ACTIVE = "active" SUSPENDED = "suspended" ARCHIVED = "archived" @dataclass class ContextMode: mode_type: ModeType payload: Dict[str, Any] status: ModeStatus = ModeStatus.ACTIVE expires_at: datetime | None = None priority: int = 0 class ContextBuilder: def __init__(self): self._modes: Dict[str, ContextMode] = {} def register_mode(self, key: str, mode: ContextMode) -> None: self._modes[key] = mode def suspend_mode(self, key: str) -> None: if key in self._modes: self._modes[key].status = ModeStatus.SUSPENDED def activate_mode(self, key: str) -> None: if key in self._modes: self._modes[key].status = ModeStatus.ACTIVE def build_context(self) -> str: # 过滤过期和挂起内容,所有活跃内容按优先级排序 active_modes = [ m for m in self._modes.values() if m.status == ModeStatus.ACTIVE and (m.expires_at is None or m.expires_at > datetime.now()) ] # 优先级高的排最后,让模型对最新写入的内容更有感知 active_modes.sort(key=lambda m: (m.priority, m.mode_type.value)) sections = [] for mode in active_modes: # 这里可以对内容做一些压缩,比如只保留摘要 formatted = self._format_payload(mode) sections.append(f"<mode:{mode.mode_type.value}>\n{formatted}\n</mode>") return "\n\n".join(sections) def _format_payload(self, mode: ContextMode) -> str: # 支持字符串、列表、字典等不同格式的payload if isinstance(mode.payload, str): return mode.payload if isinstance(mode.payload, list): return "\n".join(str(item) for item in mode.payload) if isinstance(mode.payload, dict): return "\n".join(f"{k}: {v}" for k, v in mode.payload.items()) return str(mode.payload)这里有一个实操细节我要特别强调:排序逻辑。很多人的理解是把最重要的信息放在最前面,防止模型遗忘,但根据我的实验,把“当前任务指令”放在Prompt靠后的位置,模型对它的遵循度明显更高。原因是Transformer模型的注意力机制对位置靠后的token会有更强的短程注意力偏置,这几乎是模型的原生特性。所以在context-mode里,我的策略是“基础规范放前面、任务目标放中间、即时指令放最后”。这个顺序我调了很久,实测下来任务成功率能差出将近十个百分点。
2.3 上下文压缩:不能什么历史都往里塞
如果说模式定义是地基,那上下文压缩就是承重墙。因为无论你怎么设计模式,如果某一个模式下存的内容本身就是海量的,比如Episodic模式要回溯整个项目一个月的日志,那构建出来的Prompt一样会超限。
我做压缩时用了三层策略:
第一层是关键词提取。把原始文本摘要成若干关键词组合,用于快速过滤,避免全量送入模型。第二层是结构化摘要。用一次轻量LLM调用,把零散记录重写为“目标-行动-结果”的三段式摘要,压缩率通常在百分之七十以上。第三层是决策导向过滤。不是所有历史都变成摘要,而是只保留与当前task目标相关的部分,利用的是简单的关键词加权匹配,成本极低。
这里有个取舍问题:每次都调LLM做摘要,虽然效果好,但费用和延迟都是开销。我实际采用的做法是,对会话级上下文做了“渐进式摘要”——对话前期直接存原始文本,超过一定规模之后,触发一次摘要动作,把更早的内容合并成摘要,最近的内容保留原文。这样既保证了短期回忆的精度,又控制了长期记忆的体量。
2.4 上下文模式的切换策略:显式切换与自动切换
实践中我发现,界面上一个“模式切换”按钮远远不够。如果用户每次都要手动点一下才能切换模式,就会增加理解成本,大多数用户根本不会主动去动它。所以要真正让context-mode发挥价值,必须支持两种切换方式的配合:
第一种是显式切换,主要用于特殊场景。比如用户明确说“接下来进入严格审查模式”,系统就把task上下文优先级调高,同时暂时挂起conversation模式。第二种是自动切换,通过一组轻量规则识别任务类型。比如检测到用户消息中包含“重构”“重命名”“抽离函数”等关键词,就自动切换到代码重构模式,加载对应的代码规范、模块结构约束、测试要求等。
别小看这套自动触发的规则,它正是整个方案里最见功力的一部分。规则设计得太死,会频繁误触;太松,又起不到切换效果。我后来积累了一套经验:关键词匹配一定要结合消息长度和位置特征,如果用户在一段长文本中提了一次“重构”,那可能是背景介绍而非任务指令,最近三条消息内出现两次以上“重构”(或“改结构”“依赖关系调整”等近义词),才触发切换。
3. 实操过程与核心环节实现
3.1 落地步骤一:梳理你的上下文仓库到底有哪些“模式”
动手写代码前,我建议你先不要碰技术层面,先做一次“上下文仓库盘点”。具体方法是:找一个已经跑了一段时间的AI应用,把历史Prompt全部导出来,然后逐条归类。你会发现它们实际上已经天然分成了好几类:一类是永远不变的(系统设定),一类是每次提问都略微变化的(当前诉求),一类是会在对话中沉淀下来的(偏好、修正、决策记录)。这三类就是我前面提到的System、Task、Conversation三个模式的原型。
这一步做完之后,你会对自己应用的上下文组成结构有一个完全清晰的认识。我当时做完盘点,发现原来我自以为的“超长Prompt”里,真正对结果产生影响的只有百分之三十的内容,剩下的全是累赘。这就是为什么要先盘点,因为凭空设计模式很容易过度设计,只有顺着现有使用习惯去归纳,才是合理的落地路线。
3.2 落地步骤二:搭建最小可用的模式注册中心
最小可用版本不需要特别复杂,只需要能“注册一个模式”“挂起一个模式”“从所有活跃模式中构建上下文文本”这三件事。我上面给出的ContextBuilder代码就是这个最小闭环。把核心类写完之后,可以先用一个单一的交互场景试试:
builder = ContextBuilder() # 注入系统级模式 builder.register_mode( "project_rules", ContextMode( mode_type=ModeType.SYSTEM, payload={ "语言": "Python 3.11", "错误处理": "统一使用自定义异常,禁止裸抛Exception", "日志": "使用logging模块,禁止print", }, priority=100, ), ) # 任务级模式 builder.register_mode( "current_task", ContextMode( mode_type=ModeType.TASK, payload={ "目标": "重构用户认证模块,提取装饰器统一鉴权", "验收标准": "所有接口函数加上@require_auth装饰器", "限制": "不要改动数据库表结构", }, priority=50, ), ) # 临时偏好 builder.register_mode( "user_preference", ContextMode( mode_type=ModeType.CONVERSATION, payload={"偏好": "函数注释风格使用Google docstring"}, priority=10, expires_at=... # 可以设置过期时间 ), ) # 构建真正的Prompt context_text = builder.build_context()这个最小版本跑通之后,你立刻能感觉到区别:Prompt不再是沿着时间轴堆砌,而是按信息类型分类陈列。模型对规则的遵循率肉眼可见地变高。我第一次跑通时的一个感受是:原来AI并不是“记性差”,而是我没给它一个清晰的分类索引,这就像问一个博学的人问题,你得告诉他“用哪个文件夹里的知识回答”。context-mode做的就是这个分类和索引工作。
3.3 落地步骤三:模式继承与覆盖机制
实际使用中,用户经常会说“我这个任务比较特殊,前面的规则先不适用”。这种情况下,如果强行把所有模式塞进去,就会出现规则冲突。我在项目中实验了几个覆盖策略,最后觉得比较合理的是“基于优先级与声明来源的双重覆盖”。
具体规则是:当两个模式的内容同时涉及同一个具体主题时,优先使用高priority值模式;如果priority相同,优先使用“在本次任务中更晚创建的模式”。这个策略比较符合直觉——新指令如果优先级同样高,那后说的算数。从实现角度看,它也用不着复杂逻辑,只需要在build_context排序后,对重复主题做一个倒序覆盖合并即可。
这里有一个非常常见的坑:你不要对任务级模式做字段级深层合并。比如系统模式说“使用RESTful风格写API”,任务模式说“把现有函数改成HTTP接口”,它们可能都包含“接口”这个主题,如果你做的是简单字符串拼接,两条都会写进Prompt,模型会困惑,甚至可能重复实现。后来我对payload为字典的模式做了一件事:允许声明“_replace”字段,声明后该模式会在构建时覆盖掉其他低优先级同名字段,这也是很多配置系统里常见的“覆写”概念。
3.4 参数选择:优先级权重如何定
我在试过很多轮之后,推荐一套比较沉稳的初始参数:System模式priority 1000,Task模式priority 500,Conversation模式priority 100,Episodic模式priority 10。为什么差距拉这么大?因为System模式必须无条件生效,如果Task模式也可以挑战它,那系统级约束相当于虚设。Conversation模式相对要弱一些,它承载的是“用户偏好”而非“系统要求”,但它一般比较新鲜,如果不给它一定的权重,它很容易被长上下文中更早的信息淹没。Episodic模式最低,它只是背景参考,任何时候都不应该压制当前任务的关键目标。
如果你手头有不同的场景,这三层级的比例关系可以按如下思路调节:如果你的应用是强流程式的(比如表单填写、步骤校验),可以调高Task模式的权重;如果你是做闲聊型、个性化陪伴应用,Conversation模式的权重反而要提得更高一些。如果你拿不准怎么调,就先用我上面那组比例跑,再对着失败case微调。
3.5 持久化:模式不能只活在内存里
只要你的AI应用需要跨会话使用经验和偏好,context-mode就必须解决持久化问题。我把模式的持久化架构分了两种:
第一是文件型持久化。适用于配置类和规则类模式。把Mode结构体序列化为JSON或YAML存到项目目录下,启动时自动加载。这类内容不能存放在代码文件里,因为频繁修改代码会导致Git历史爆炸。
第二是数据库持久化,适合会话级上下文和片段级上下文。每轮对话结束后,把变更过的模式写入数据库,下一次会话启动时按用户或任务ID拉取。我建议对payload字段做JSONB存储(如果你用PostgreSQL),方便后续按Key做条件更新。
这里要注意一个关键点:不要每轮对话都全量存一次模式,而是存“增量事件”。比如用户时说了一句“以后别用单引号了”,你记录的是“偏好更新事件:字符串引号风格改为双引号”,而不是把整份prompt再存一遍。这会极大降低存储压力和回放成本,而且后面做上下文检索时也更友好。
3.6 一些调试技巧:怎么直观看见“模式”被如何使用
刚开始调试context-mode时,最难的一点是“看不见”。你看不到当前模式加载了哪些内容,也没法判断模型执行时是不是真的参考了模式里的字段。我后来加了一个调试模式:在context text的每个模式块外面包上HTML注释(如果是API场景,调试时换成<|context_debug|>隐藏标记),然后在响应中回传“本次请求激活了哪几个模式”。这样你可以在应用后台上明确看到:这条回答是基于Task模式+System模式生成的,Conversation模式被挂起了。
这一步对优化帮助极大。我曾经发现某个接口连续十几次回答质量都很差,开了调试模式后发现,激活的模式根本不是我以为的那几个——一个本该挂起的临时测试模式一直在后台加载,污染了参考信息。如果没有调试工具,我根本定位不到这个隐蔽bug。
4. 常见问题与排查技巧实录
4.1 模式“串味”:跨任务上下文干扰
这是使用context-mode后遇到最多的问题,典型表现是:你在A任务里让AI学会了某种代码风格,切到B任务后,它还在沿用A任务的风格,即使你已经声明“现在切换到B项目”。根因是某些模式的信息没有被正确隔离,例如你在Conversation模式中存入了A任务中形成的习惯,但这个模式并没有在切换时被挂起或归档。
排查方法很简单:检查当前激活的模式列表和它们各自的payload。如果发现Conversation模式中残留了上个任务的偏好描述,那在切换任务时就要把该模式下与新任务无关的字段做一次“剪枝”,使用增量事件方式清理上下文。我的经验是,一个好的工程规范是:当任务状态变为archived时,该任务相关的所有Conversation模式下的字段必须标记为过期,而不是停留在active状态等待自然衰减。
4.2 优先级过高导致用户修正被忽略
有一次我遇到一个诡异的现象:用户明确跟AI说“这次按老方案来,不用重构”,但AI依然执行了重构。查了很久才发现,因为重构是Task模式的字段,它的priority远高于Conversation模式,所以即使Conversation模式中有了用户的否决意见,在合并时也直接被覆盖了。这是一个典型的“优先级压死人”案例。
解决方案是在ContextBuilder里加了一个“最近输入优先保护机制”:如果用户最后一条消息中包含了与某个模式字段方向相反的关键词,系统自动把该字段临时标记为“superseded”,该字段在本次构建中直接被跳过。注意这不是让用户覆盖掉系统级规范,而是对任务级与偏好级冲突的一种调停逻辑。这个机制上线后,类似“用户说了Ta不照做”的冲突case直接减了大半。
4.3 Prompt长度失控
很多开发者在接入context-mode之后,还是发现Prompt越来越长。常见原因很隐蔽:有些人把模式内容本身的重组逻辑写成了递归——把一个模式作为另一个模式的payload传递,构建时嵌套展开,导致体积指数膨胀。
我的建议是设置一道“健康检查”边界:在build_context之后,如果文本超过模型上下文窗口的一半,就强制触发一次压缩。这里的压缩不是直接把后面的内容扔掉,而是把低优先级的模式先转为摘要模式,只保留主题句和结论句。这有点像人脑的记忆机制:考前复习资料越到临近考试越要精简提纲,而不是越整理越厚。
另外一个有实效的经验是,给不同模式设置“token预算”。比如System模式预算2000 token,Task模式预算1000 token,Conversation模式预算500 token,超了就强制概括。这比笼统地说“控制一下长度”要可操作得多。
4.4 模型完全不遵守系统模式约束
有的朋友跑通context-mode后跑来问我:“明明系统模式放在最前面了,为什么模型还是忽略它?”我看了看他们的代码,发现问题出在格式化方式上:他们把系统模式的内容和任务内容用同样的标题方式混合在一起,模型根本分不清哪个是“系统级指令”哪个是“参考信息”。
要让模型区分不同模式的指令级别,就得在文本结构上做文章。我用的方式是用XML风格标签明确包裹每个模式,并在System模式开头加上一句显式的指令:This is the highest priority context. Follow these rules no matter what.。虽然听起来有点“笨”,但对主流模型非常有效。你可以理解成:模型没有读心术,它只能按照文本格式的“视觉凸显性”来判断优先级。我们在用context-mode时,是在用结构化的方式降低了模型的推断成本。
4.5 会话恢复后上下文不连续
“上下文模式”跨会话恢复后,AI常常会表现得“失忆”——它能记住你的偏好文本,但在执行具体任务时态度前后不一致,特别像那种“背熟了规则却不会应用”的状态。我排查下来核心原因是:只恢复了模式数据,没恢复模式之间的关联关系。比如你之前的任务模式中有一个前提条件“用户是管理员”,这个前提条件同时被系统模式的权限判断字段引用了。如果你只恢复task模式而没有同步系统模式中的关联数据,上下文之间的逻辑链条就断了。
所以我在持久化中增加了一个“模式关联表”,记录不同模式之间的引用依赖。恢复时不是单点拉取,而是“按依赖关系级联恢复”。这个机制保证了跨会话切换时上下文始终是自洽的,AI不会拿着互相矛盾的上下文去生成内容。
5. 进阶玩法:当context-mode遇到Agent工作流
5.1 同一任务内的多阶段模式动态调整
如果你做过Agent类应用,一定会遇到这样的场景:一个任务需要经过“拆解目标—收集信息—编写方案—生成代码—测试验证”多个阶段。不同阶段需要的上下文重点是完全不同的。我在最开始设计context-mode时,只按“任务类型”区分模式,后来发现不够,实际运行时“同一任务的不同阶段”也需要不同上下文视图。
我在项目里做了一个“阶段模式”的概念——本质上是对同一个Task模式做阶段性切面。比如在编码阶段,“限制条件”字段要突出显示;而在测试阶段,“测试覆盖要求”字段要加到最前面。这不需要新建一个模式,而是对同一个payload做字段排序和展示权重调整。用一句话总结就是:context-mode既要管横向的分类,也要管纵向的阶段。
5.2 与RAG的配合:把检索结果装进上下文模式里
在大多数RAG应用里,检索出来的文档片段几乎总是被当作一团“背景知识”拼到Prompt尾部。这种简单处理会导致检索结果和任务指令之间没有层次关系,模型有时会被不相关的检索片段带偏。context-mode的解法是,把检索结果封装为一个特殊的Reference模式,它的priority介于System和Conversation之间,并且可以设置“只允许引用与任务目标相关的段落”这一指令。
这样设计的好处很明显:模型不再把检索片段当作自由发挥的素材,而是当作一个需要按引用规则使用的知识库。我实测下来,答案的事实一致性和对检索结果的溯源率都有明显提升。
5.3 裁剪未来扩展:给模式加“观察者”接口
最后聊一个我在后期迭代中加上的特性——观察者接口。context-mode作为一个集中管理上下文的中间层,天然适合做“上下文可视化与监控”。我实现了一个简单的订阅机制:任何模式被切换、挂起、归档时,都会触发一个事件,事件会推送到监控看板,展示当前系统内各模式的实时状态。这个小功能本身不难,但在团队协作或排查问题时非常有用,它能让你一眼看出“现在系统同时活跃了哪些上下文模式”,而不是靠翻聊天记录去猜AI当前到底“在想什么”。
如果你后续要做各类第三方工具集成,这个观察者接口也可以作为标准插件机制,供外部系统感知上下文状态。我自己的经验是,任何中间层系统,只要具备可控的透明性,它的可维护性和被接受度都会大幅上升。context-mode在这方面算是走了一条正确的路。
我在实际使用中还有一个体会:不要一上来就把context-mode做成通用平台。先找一个具体业务场景(比如代码生成助手),把那一个场景打磨顺,你积累的构建策略和调试经验,再迁移到其他场景时才能真正派上用场。工具的价值不在于它有多少模式,而在于它能不能在正确的时间把正确的模式呈现给模型。