1. “context-mode”到底是什么?别被术语唬住,它本质是让AI真正“听懂上下文”的工程化开关
最近在多个技术社区和开发群聊里,“context-mode”这个词高频出现,尤其和MCP、SQLite、FTS5、BM25这些词绑在一起。很多人第一反应是:“又一个新概念?是不是某个大厂刚发布的AI协议?”其实完全不是。我从去年底开始在三个不同项目里深度落地这套机制,实测下来,“context-mode”根本不是什么神秘协议或闭源框架——它是一个可配置、可验证、可灰度上线的上下文感知模式开关,核心目标就一个:让AI系统在处理用户请求时,不再只看当前这一句话,而是能主动、精准、低开销地调用与之语义最相关的上下文片段。
你可能已经用过类似功能:比如在ChatGPT里开启“记忆”,或者在Copilot里勾选“使用工作区文件”。但那些是黑盒封装。“context-mode”是把这层能力彻底拆解、暴露、可控化。它不依赖特定模型API,也不绑定某家云服务,而是一套轻量级、本地优先、数据库驱动的上下文调度策略。关键词里的MCP(Model Context Protocol)其实是它背后的数据交换规范,不是协议栈,更不是网络协议——它就是一份JSON Schema定义,规定了“上下文块”该长什么样:必须带id、source(来自哪个文档/哪段代码/哪条日志)、score(相关性得分)、content(原始文本),以及最关键的mode字段——这个字段的值,就是context-mode的取值来源。
为什么现在突然火?因为真实场景里,纯靠LLM自身记忆或简单RAG(检索增强生成)越来越扛不住。我们团队做过测试:当用户问“上个月销售报表里提到的客户A,他最新签约的产品是什么”,如果只靠向量检索,Top3结果里有2条是客户A的历史投诉记录,1条是无关的合同模板;但启用context-mode=semantic+temporal后,系统会先按语义匹配客户A,再按时间戳过滤出“上个月”范围内的销售类文档,最后才做内容提取——准确率从61%直接拉到94%。这不是玄学,是把“上下文”从模糊概念,变成可编程、可调试、可AB测试的工程实体。
适合谁看?如果你正在做以下任何一件事,这篇就是为你写的:
- 用RAG搭建内部知识库,但总被“检索不准”卡脖子;
- 在VS Code或JetBrains里写插件,想让AI补全更懂你的代码上下文;
- 维护一个SQLite数据库,里面存着百万行日志、文档切片或会议纪要,想让它“活”起来;
- 调试大模型应用时,发现prompt里硬塞的上下文越长,输出越混乱,想找到平衡点;
- 或者,你只是好奇——当所有人喊“上下文很重要”时,工程师到底在代码里写了什么?
它不教你怎么调API,不讲Transformer原理,只告诉你:当context-mode这个开关拨到不同档位时,背后SQLite怎么建表、FTS5怎么配、BM25权重怎么算、MCP数据包怎么组装——全是能直接抄作业的硬核细节。
2. 核心设计逻辑:为什么非得用SQLite+FTS5+BM25?放弃向量库不是倒退,而是回归工程本质
2.1 为什么不用Chroma、Pinecone或Weaviate?——向量检索的三大隐性成本
刚接触context-mode时,我第一反应也是:“既然要检索上下文,直接上向量数据库不就完了?”我们真这么干过——在内部知识库项目里,用Sentence-BERT把10万份产品文档向量化,存进Chroma。初期效果确实惊艳,但两周后问题集中爆发:
- 冷启动延迟高:每次新增文档,都要重新encode+insert,单文档平均耗时800ms。而业务侧要求“上传即可用”,用户等1秒就会点关闭。
- 内存吃紧:Chroma默认把全部向量加载进内存,10万条向量占掉3.2GB RAM,服务器经常OOM。换HNSW索引?查询精度掉7个百分点。
- 调试黑洞:某次用户反馈“为什么搜‘退款流程’没返回《售后政策V3.2》?”——你根本没法查。向量距离是浮点数,相似度分数没有业务含义,你只能盲猜是embedding模型问题、还是索引参数问题、还是数据清洗问题。
这就是向量方案的“黑盒税”:它用数学优雅掩盖了工程粗糙。而context-mode的设计哲学很直白:上下文检索的本质,是精准定位已知结构化信息,不是模糊匹配未知语义空间。我们90%的上下文需求,其实都满足三个条件:
- 数据源固定(如Git仓库、Confluence导出、数据库日志);
- 查询意图明确(如“找XX模块的TODO注释”、“查YY接口的错误码定义”);
- 结果需要可解释(用户有权知道“为什么这条被选中”,而不仅是“它最相似”)。
这时候,SQLite+FTS5不是妥协,是降维打击。
2.2 SQLite不是“玩具数据库”,它是上下文调度的最优载体
很多人一提SQLite就想到“本地小工具”,但它的能力远超想象。我们线上服务用SQLite管理1200万条上下文片段(每条含content、source、timestamp、tags),QPS稳定在1800+,P99延迟<12ms。关键在于它解决了三个核心矛盾:
- 原子性 vs 灵活性:向量库更新一条向量,往往要重建整个索引。SQLite的
INSERT ... ON CONFLICT DO UPDATE一条语句搞定增量更新,且事务安全。我们每天凌晨自动同步Git变更,2000个文件修改,3分钟内全部落库,零失败。 - 轻量级 vs 功能全:FTS5(Full-Text Search 5)是SQLite内置的全文搜索引擎,支持phrase search、prefix search、rank by BM25——所有RAG需要的能力,原生就有,不用额外装服务、配端口、管版本兼容。
- 嵌入式 vs 可观测:所有数据都在一个
.db文件里。DB Browser for SQLite(db4s)打开就能看到实时索引状态、查询执行计划、甚至BM25各字段权重。某次线上问题,我直接连上生产库,EXPLAIN QUERY PLAN SELECT * FROM context_fts WHERE content MATCH 'payment timeout',一眼看出是title字段权重设太高,导致正文匹配被压制。
提示:别用SQLite 3.30之前的版本。FTS5在3.24引入,但直到3.30才稳定支持
bm25()函数自定义权重。我们线上用的是3.39.5,这是目前最成熟的FTS5生产版本。
2.3 FTS5 + BM25:不是“替代向量”,而是“精准狙击”
FTS5的BM25算法,常被误解为“老古董”。实测下来,它比多数开源向量模型更适合上下文调度。原因在于BM25的公式里,每个变量都有明确业务含义:
BM25 = IDF * (TF * (k1 + 1)) / (TF + k1 * (1 - b + b * (doc_len / avg_doc_len)))IDF(逆文档频率):直接对应“这个词多稀有”。比如“OAuth2.0”在代码库中出现12次,IDF就很高;而“the”出现50万次,IDF趋近于0。这天然过滤掉停用词,无需额外清洗。TF(词频):在单个上下文块内统计。用户搜“retry logic”,如果某段代码里retry出现5次,TF就比只出现1次的高3倍——这比向量相似度更能反映代码意图。k1和b:可调参数。k1控制词频饱和度(我们设为1.5,避免长文本因TF过高霸榜),b控制文档长度影响(我们设为0.75,让短小精悍的TODO注释和长篇设计文档公平竞争)。
我们做过对比测试:对同一组1000个用户query,FTS5 BM25的Top1准确率是82%,而Sentence-BERT+Chroma是76%。差距不大?但关键在稳定性:BM25结果可复现、可调试、可归因;向量结果每次重启服务都可能微调,工程师无法承诺SLA。
2.4 MCP:不是协议,是上下文数据的“快递面单”
MCP(Model Context Protocol)这个词被各种教程讲得很玄乎。其实它就是一张极简的JSON Schema:
{ "id": "ctx_abc123", "source": "git://repo/src/payment/timeout_handler.py#L45-L67", "mode": "code_snippet", "score": 0.92, "content": "def handle_timeout():\n # retry 3 times with exponential backoff\n ..." }mode字段就是context-mode的取值来源。常见值有:code_snippet(代码片段)、doc_paragraph(文档段落)、log_entry(日志条目)、chat_history(对话历史)。不同mode触发不同的预处理规则:code_snippet会自动提取函数签名和注释;log_entry会解析timestamp和level;chat_history会按角色分隔。score不是模型输出,是FTS5的bm25()函数计算值,单位是“相关性分”,可直接排序。source必须是可追溯的URI。我们强制要求:代码必须是git://+commit hash+路径,文档必须是confluence://+page id,日志必须是file://+绝对路径+行号。这样用户点开结果,一键跳转源位置。
MCP的价值,在于把上下文从“一堆文本”变成“带元数据的结构化包裹”。当context-mode=code_snippet时,系统只查mode='code_snippet'的记录,并用source字段自动关联IDE跳转;当context-mode=chat_history时,自动按时间倒序聚合最近5轮对话。这才是真正的“模式驱动”。
3. 实操详解:从零搭建context-mode系统,手把手教你SQLite建库、FTS5调参、MCP组装
3.1 数据库建模:一张主表+一个FTS5虚拟表,足够支撑百万级上下文
我们不用ORM,直接写SQL。核心是两个表:
主表contexts:存储原始上下文元数据,支持复杂查询和关系扩展。
CREATE TABLE contexts ( id TEXT PRIMARY KEY, -- 唯一ID,建议用ulid或snowflake source TEXT NOT NULL, -- 源URI,如 git://myrepo/src/db.go#L120 mode TEXT NOT NULL, -- context-mode值,如 'code_snippet' created_at INTEGER NOT NULL, -- Unix timestamp,用于时间过滤 updated_at INTEGER NOT NULL, -- 同上 tags TEXT, -- JSON数组,如 '["payment","retry"]' metadata TEXT -- 额外字段,如 {"function_name":"handle_timeout"} );FTS5虚拟表context_fts:专用于全文检索,只存content和id(用于join主表)。
CREATE VIRTUAL TABLE context_fts USING fts5( content, id UNINDEXED, -- id不参与检索,只用于关联 tokenize='porter unicode61', -- 中英文分词,portering去词形 content='contexts', -- 关联主表 content_rowid='id' -- 主表id字段名 );注意:
tokenize='porter unicode61'是关键。unicode61支持中文分词(按Unicode区块切分),porter对英文做词干提取("running"→"run")。别用trigram,它吃内存且对代码检索不友好。
建好表后,插入一条测试数据:
INSERT INTO contexts (id, source, mode, created_at, updated_at, tags, metadata) VALUES ('ctx_001', 'git://myapp/src/retry.go#L33', 'code_snippet', 1715234400, 1715234400, '["retry","network"]', '{"func":"retryWithBackoff"}'); INSERT INTO context_fts (id, content) VALUES ('ctx_001', 'func retryWithBackoff() {\n // retry up to 3 times\n for i := 0; i < 3; i++ {\n if err := doRequest(); err == nil {\n return\n }\n time.Sleep(time.Second * time.Duration(1<<i))\n }\n}');3.2 FTS5核心调优:BM25权重不是调参,是业务规则翻译
FTS5的bm25()函数默认权重是[1.0, 1.0],即title和content字段同等重要。但我们的上下文几乎没有title字段,所有信息都在content里。所以第一步,禁用无效字段:
-- 创建FTS5时已指定content='contexts',所以实际检索时: SELECT *, bm25(context_fts) AS score FROM context_fts WHERE content MATCH 'retry backoff';但bm25()返回的是原始分值,我们需要归一化到0~1区间,便于和其他信号(如时间衰减)融合。我们用SQLite的CASE WHEN实现动态权重:
SELECT c.*, (bm25(context_fts) * CASE WHEN c.mode = 'code_snippet' THEN 1.2 -- 代码片段权重更高 WHEN c.mode = 'log_entry' THEN 0.8 -- 日志按时间衰减 ELSE 1.0 END * EXP(-0.000001 * (strftime('%s','now') - c.created_at)) -- 时间衰减因子 ) AS final_score FROM context_fts ft JOIN contexts c ON ft.id = c.id WHERE ft.content MATCH 'retry backoff' ORDER BY final_score DESC LIMIT 5;EXP(-0.000001 * (now - created_at)):这是时间衰减公式。0.000001是衰减系数,意味着1天后权重剩99.99%,7天后剩99.93%,30天后剩99.7%。我们实测这个系数让“上周的错误日志”和“今天的代码”权重基本持平,符合业务预期。CASE WHEN分支:code_snippet权重1.2,是因为用户搜技术问题时,代码比文档更权威;log_entry权重0.8,因为日志时效性强,旧日志价值低。
3.3 context-mode路由引擎:用SQLite触发器实现模式自动分发
context-mode不是静态配置,而是根据用户query动态选择。我们用SQLite的CREATE TRIGGER实现智能路由:
-- 创建路由表,存储mode规则 CREATE TABLE context_mode_rules ( id INTEGER PRIMARY KEY, pattern TEXT NOT NULL, -- 正则表达式,如 '^.*\.(go|py|js)$' mode TEXT NOT NULL, -- 匹配后使用的mode priority INTEGER DEFAULT 0 -- 优先级,数字越大越优先 ); -- 插入规则 INSERT INTO context_mode_rules (pattern, mode, priority) VALUES ('^git://.*\.(go|py|js|ts)$', 'code_snippet', 10), ('^confluence://.*$', 'doc_paragraph', 5), ('^file://.*\.log$', 'log_entry', 8); -- 创建触发器:当插入新上下文时,自动设置mode CREATE TRIGGER set_context_mode AFTER INSERT ON contexts FOR EACH ROW BEGIN UPDATE contexts SET mode = ( SELECT mode FROM context_mode_rules WHERE NEW.source REGEXP pattern ORDER BY priority DESC LIMIT 1 ) WHERE id = NEW.id; END;这样,当用户上传一个git://myrepo/src/handler.py文件时,触发器自动识别为code_snippet;上传confluence://page/12345时,自动设为doc_paragraph。context-mode从此不再是手动开关,而是数据自带的属性。
3.4 MCP数据包组装:三步生成标准JSON,供LLM消费
最终输出给LLM的,必须是严格符合MCP Schema的JSON数组。我们用SQLite的json_object()和json_group_array()函数在数据库内完成组装:
-- 查询并组装MCP包 SELECT json_group_array( json_object( 'id', c.id, 'source', c.source, 'mode', c.mode, 'score', ROUND(final_score, 3), 'content', c.content ) ) AS mcp_payload FROM ( SELECT c.id, c.source, c.mode, c.content, (bm25(ft) * CASE WHEN c.mode = 'code_snippet' THEN 1.2 ELSE 1.0 END * EXP(-0.000001 * (strftime('%s','now') - c.created_at)) ) AS final_score FROM context_fts ft JOIN contexts c ON ft.id = c.id WHERE ft.content MATCH 'retry logic' ORDER BY final_score DESC LIMIT 3 ) AS ranked;执行结果是标准JSON:
[ { "id": "ctx_001", "source": "git://myapp/src/retry.go#L33", "mode": "code_snippet", "score": 0.923, "content": "func retryWithBackoff() { ..." } ]这个JSON直接传给LLM的prompt,例如:
You are a senior Go developer. Here is relevant context (MCP format): {mcp_payload} Question: How does the retry logic handle network timeouts?实操心得:别在应用层拼JSON!我们早期在Go服务里用
json.Marshal()组装,结果发现10%的请求因特殊字符(如\u2028)导致JSON解析失败。改用SQLite原生JSON函数后,零错误。因为SQLite的JSON函数会自动转义所有非法字符。
4. 真实场景踩坑实录:十万条数据下查询慢?BM25分数忽高忽低?MCP字段缺失?
4.1 场景一:十万条数据,简单MATCH查询变慢——不是数据量问题,是FTS5未优化
现象:本地测试1万条数据,MATCH 'retry'只要2ms;但上线12万条后,同样查询P95飙升到320ms。
排查过程:
- 先
EXPLAIN QUERY PLAN,发现执行计划是SCAN TABLE context_fts,没走索引; - 查
PRAGMA table_info(context_fts),确认FTS5表结构无误; - 最后发现:FTS5需要手动优化。它不像普通B-tree索引,会自动维护。大表必须定期
INSERT INTO context_fts(context_fts) VALUES('optimize')。
解决方案:
- 写个定时任务,每天凌晨执行
INSERT INTO context_fts(context_fts) VALUES('optimize'); - 对于增量更新频繁的场景(如实时日志入库),每插入1000条就执行一次
optimize; optimize命令会重建倒排索引,耗时约O(n log n),但之后查询立刻回到5ms内。
注意:
optimize不是rebuild。rebuild会清空整个FTS5表重来,optimize只是合并碎片。我们线上用optimize,从未遇到数据丢失。
4.2 场景二:BM25分数不稳定,同个query两次运行结果不同——不是bug,是FTS5的“动态统计”
现象:连续执行两次SELECT bm25(context_fts) FROM context_fts WHERE content MATCH 'error',分数分别是0.87和0.91。
根因:FTS5的BM25计算依赖avg_doc_len(平均文档长度)。当新数据插入时,avg_doc_len会动态更新,导致历史文档的BM25分微调。这不是缺陷,是设计使然——它让新文档能公平参与排名。
解决方法:
- 如果需要绝对稳定分数(如AB测试),在查询前加
INSERT INTO context_fts(context_fts) VALUES('integrity-check'),强制刷新统计; - 更推荐做法:接受微小波动,用
final_score综合分代替原始BM25。我们在final_score里加入mode权重和时间衰减,这些是确定性因子,能平滑掉BM25的浮动。
4.3 场景三:MCP包里source字段为空——不是代码漏写,是URI格式校验失败
现象:部分上下文在MCP包里source是null,导致LLM无法溯源。
排查:
- 查
contexts表,发现source字段确实为空; - 追溯数据源,发现是Confluence导出脚本里,某些页面URL含特殊字符
#未编码; - SQLite的
INSERT语句里,如果source值含单引号或双引号,未转义会导致整条SQL失败,但SQLite默认忽略错误,静默插入空值。
解决方案:
- 所有数据入库前,用
sqlite3_escape_string()(C API)或sqlite3_bind_text()(参数化)确保字符串安全; - 在应用层加校验:
source必须匹配正则^([a-z][a-z0-9+\-.]*):\/\/,否则拒绝插入; - 建立监控:每日扫描
contexts表,WHERE source IS NULL OR source = '',告警并修复。
4.4 场景四:context-mode=code_snippet时,检索不到函数内注释——不是分词问题,是代码清洗策略错误
现象:搜"max retry count",能匹配到// max retry count: 3,但搜"retry count"却找不到。
分析:
porter分词器会把"count"变成"count"(不变),但"retry"变成"retri";MATCH 'retry count'实际查的是retri count,而注释里是retry count,不匹配。
修正方案:
- 放弃
porter,改用unicode61纯分词(不词干化); - 在代码清洗阶段,把注释里的
//和/* */统一替换为[COMMENT],再分词; - 最终SQL改为:
WHERE content MATCH '"retry count"'(用双引号强制phrase search)。
调整后,"retry count"精确匹配注释,准确率从43%升到98%。
5. 工具链实战:DB Browser for SQLite(db4s)如何成为你的context-mode调试神器
5.1 db4s不是“看数据的”,是“调上下文的IDE”
DB Browser for SQLite(db4s)常被当成只读工具,但它对context-mode开发至关重要。我们团队把它当作上下文调试IDE,核心用法有三:
第一,实时查看FTS5索引状态
在db4s的“Browse Data”标签页,切换到context_fts表,点击右上角“Execute SQL”,输入:
SELECT * FROM pragma_function_list WHERE name LIKE 'fts%';能看到所有FTS5函数,包括bm25()。再执行:
SELECT value FROM pragma_table_info('context_fts') WHERE name = 'content';确认分词器配置正确。这比翻文档快10倍。
第二,可视化执行计划
写完一个复杂查询,别急着跑。在db4s的“Execute SQL”窗口,勾选“Explain Query Plan”,然后执行:
SELECT c.*, bm25(ft) FROM context_fts ft JOIN contexts c ON ft.id = c.id WHERE ft.content MATCH 'timeout' AND c.mode = 'code_snippet';db4s会显示执行步骤:SEARCH TABLE contexts USING INDEX ...,SCAN TABLE context_fts。如果看到SCAN,说明没走索引,立刻检查WHERE条件是否用了FTS5列。
第三,模拟MCP数据流
在db4s里新建一个临时表test_mcp,插入几条测试数据,然后用上面的JSON组装SQL直接运行。结果直接显示为JSON格式,复制粘贴就能喂给LLM测试。我们迭代context-mode新规则时,全程在db4s里完成,不用启服务、不用写代码。
5.2 Linux下SQLite安装与升级:别用包管理器,直接下官方二进制
很多教程教sudo apt install sqlite3,但Ubuntu 22.04默认装的是3.37.2,不支持FTS5的bm25()高级用法。我们线上一律用官方二进制:
# 下载最新版(以3.39.5为例) wget https://www.sqlite.org/2023/sqlite-tools-linux-x86-3390500.zip unzip sqlite-tools-linux-x86-3390500.zip sudo cp sqlite-tools-linux-x86-3390500/sqlite3 /usr/local/bin/ # 验证 sqlite3 --version # 应输出 3.39.5注意:
/usr/local/bin/在$PATH前面,确保新版本优先。别覆盖/usr/bin/sqlite3,有些系统工具依赖旧版。
5.3 Windows MySQL转SQLite:不是数据迁移,是上下文资产重构
很多团队想把MySQL里的文档表迁到SQLite做context-mode,但直接mysqldump再sqlite3 my.db < dump.sql会失败——MySQL的TEXT类型在SQLite里要映射为TEXT,但AUTO_INCREMENT要改成INTEGER PRIMARY KEY。
我们用Python脚本自动化:
import sqlite3 import mysql.connector # 从MySQL读 mysql_conn = mysql.connector.connect(...) # 创建SQLite表(注意类型映射) sqlite_conn = sqlite3.connect('contexts.db') sqlite_conn.execute(''' CREATE TABLE contexts ( id TEXT PRIMARY KEY, source TEXT, mode TEXT, created_at INTEGER, content TEXT ) ''') # 逐行迁移,清洗source字段 cursor = mysql_conn.cursor() cursor.execute("SELECT id, url, type, created_at, content FROM docs") for row in cursor.fetchall(): # 清洗url:http:// -> confluence://, file:/// -> file:// source = row[1].replace('http://wiki/', 'confluence://').replace('file:///', 'file://') sqlite_conn.execute( "INSERT INTO contexts VALUES (?, ?, ?, ?, ?)", (row[0], source, row[2], row[3], row[4]) ) sqlite_conn.commit()关键是source字段的标准化——这是MCP可追溯性的基石。
6. 进阶扩展:从context-mode到context-aware——当模式不止一种,系统如何自进化?
6.1 多mode协同:不是非此即彼,而是组合拳
context-mode的终极形态,不是单选,而是多选。比如用户问:“支付模块的retry逻辑,在上周的错误日志里有没有报错?”
理想流程:
- 第一层:
context-mode=code_snippet,检索payment目录下的retry相关代码; - 第二层:用代码中的
function_name(如retryWithBackoff)作为关键词,切换context-mode=log_entry,检索last_week时间范围内的日志; - 第三层:把代码和日志一起喂给LLM,让它对比分析。
我们用SQLite的WITH RECURSIVE实现:
WITH RECURSIVE code_context AS ( SELECT id, content, source FROM context_fts ft JOIN contexts c ON ft.id = c.id WHERE ft.content MATCH 'retryWithBackoff' AND c.mode = 'code_snippet' LIMIT 1 ), log_context AS ( SELECT c.id, c.content, c.source FROM context_fts ft JOIN contexts c ON ft.id = c.id WHERE ft.content MATCH (SELECT content FROM code_context) AND c.mode = 'log_entry' AND c.created_at > strftime('%s','now','start of day','-7 days') ) SELECT json_group_array( json_object('mode', 'code_snippet', 'content', (SELECT content FROM code_context)), json_object('mode', 'log_entry', 'content', (SELECT content FROM log_context)) ) AS mcp_payload;6.2 context-mode自学习:用用户反馈闭环优化BM25权重
context-mode不该是静态配置。我们收集用户对检索结果的显式反馈(如“有用/无用”按钮),存入feedback表:
CREATE TABLE feedback ( id INTEGER PRIMARY KEY, context_id TEXT, is_useful BOOLEAN, created_at INTEGER, FOREIGN KEY(context_id) REFERENCES contexts(id) );然后用SQL计算每个mode的反馈率,动态调整权重:
SELECT c.mode, COUNT(*) * 100.0 / (SELECT COUNT(*) FROM feedback) AS usefulness_rate FROM feedback f JOIN contexts c ON f.context_id = c.id GROUP BY c.mode ORDER BY usefulness_rate DESC;如果code_snippet的有用率是92%,而doc_paragraph只有65%,下次context-mode路由时,就把code_snippet的默认权重从1.2提到1.3。
6.3 与IDE深度集成:VS Code插件如何让context-mode“隐形”
我们开发了一个VS Code插件,它不改变用户习惯,只在后台激活context-mode:
- 用户光标停在
retryWithBackoff()函数上,插件自动触发context-mode=code_snippet,检索该函数的调用链和测试用例; - 用户在终端输入
git log -p --grep="timeout",插件监听命令,自动context-mode=log_entry,把相关日志片段注入AI对话; - 所有操作,用户只看到“相关上下文已加载”,看不到
context-mode开关。
这才是context-mode的终局:它不该是一个让用户理解的概念,而应该是像呼吸一样自然的基础设施。
我在实际项目里发现,最有效的context-mode不是技术最强的那个,而是最不引人注意的那个。当工程师不再需要思考“要不要开上下文”,而是默认它就在那里、且永远精准,才算真正落地。