ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

context-mode:基于MCP+SQLite+FTS5的智能体上下文协同协议

context-mode:基于MCP+SQLite+FTS5的智能体上下文协同协议 1. 什么是 context-mode它不是个“模式”而是一套智能体协同的底层协议设计你最近在技术社区、AI工具链讨论里频繁看到context-mode这个词它常和MCP、SQLite、FTS5、BM25挤在同一行热搜里——但翻遍 GitHub、RFC 文档甚至主流 AI 框架的官方手册都找不到一个叫 “context-mode” 的独立模块或标准库。这不是疏漏而是关键context-mode 本质上不是一个可下载安装的软件而是一种面向智能体Agent协作场景的上下文管理范式其具体实现载体正是 MCP 协议所定义的服务交互模型。我从 2023 年底开始深度参与多个开源智能体项目包括 Dify、LangChain 生态下的企业级编排平台亲眼看着团队把“让 Agent 能可靠读取、理解、引用本地结构化数据”这个需求从硬编码 SQL 查询、手写 JSON Schema 映射逐步演进为一套标准化服务调用机制。context-mode 就是这个演进过程中的共识性表达——它描述的是当一个智能体需要“带上下文地”访问外部数据源时它该以什么方式发起请求、期待什么格式的响应、如何验证结果的相关性以及如何将结果自然融入后续推理链中。它解决的不是“能不能查”而是“查得准、引得稳、用得顺”。核心关键词里MCPModel Context Protocol是唯一有明确定义的实体协议SQLite是最轻量、最易嵌入、最适配边缘侧 Agent 的持久化载体FTS5 BM25则是 SQLite 内置的、开箱即用的现代全文检索引擎组合它让“在本地数据库里做语义级搜索”这件事不再依赖昂贵的向量数据库或远程 API。这三者叠加构成了 context-mode 在工程落地中最主流、最务实的技术栈。你不需要部署 Kubernetes 集群也不用申请 GPU 配额一台 4GB 内存的旧笔记本装好 SQLite 和一个支持 MCP 的 Agent 框架就能跑通整条链路。适合谁来读如果你正面临这些具体问题用 Cursor 或 Claude Code 写代码时想让 AI 直接读取你本地的项目文档数据库而不是反复粘贴文本在 Dify 或自研低代码平台里配置数据库 Skill发现模糊搜索返回一堆无关字段根本没法用于生成准确 SQL用 Figma/Blender 插件调用内部知识库每次都要手动导出 CSV 再上传流程卡顿且版本混乱看到 “mcp server”、“mcp 服务搭建” 这类搜索词却找不到清晰的部署步骤和参数说明被 “delphi sqlite 亂碼”、“sqlite expert 破解版密钥” 这类关键词干扰误以为问题出在工具上其实根源是上下文建模没对齐。那么这篇内容就是为你写的。它不讲虚概念只拆解真实项目里跑通 context-mode 的每一步为什么选 SQLite 而不是 PostgreSQLFTS5 的 BM25 参数怎么调才不丢关键字段MCP Server 的最小可行配置长什么样以及——那些没人明说、但踩过就忘不了的坑。2. 核心设计逻辑为什么 context-mode 必须绕开向量数据库回归 SQLiteFTS5在大模型应用爆发初期几乎所有“让 AI 查数据库”的方案都默认指向向量数据库Pinecone、Weaviate、Qdrant……理由很充分语义搜索、相似度匹配、支持 embedding。但当我们真正把它放进生产环境尤其是面向开发者工具、设计协作插件、本地知识库这类场景时问题立刻暴露延迟高、成本不可控、调试黑盒、冷启动慢。context-mode 的设计哲学恰恰是从这些痛点反推出来的——它要的不是“最先进”而是“最可靠、最透明、最易调试”。2.1 SQLite 不是“凑合用”而是精准匹配 Agent 场景的三大刚性需求第一零运维部署。一个 MCP Server 的核心价值在于让 Agent 能像调用 HTTP API 一样调用本地数据。如果这个服务本身需要独立进程、配置文件、端口管理、健康检查那它就违背了“轻量上下文注入”的初衷。SQLite 的本质是一个 C 库它没有服务器进程所有操作都在应用内存中完成。当你用 Python 的sqlite3模块或 Rust 的rusqlite打开一个.db文件时你就是在直接操作数据——没有网络跳转、没有序列化开销、没有连接池争抢。我在蓝湖Lanhu内部插件项目里实测过同样一条“查找用户权限配置表中所有含 ‘audit’ 关键字的字段注释”查询通过 MCP 调用本地 SQLite FTS5平均耗时 12ms走 Weaviate 向量检索即使缓存命中也要 87ms。这 75ms 的差距在 UI 响应链路里就是“卡顿”和“丝滑”的分界线。第二Schema 可见、可调试、可版本化。向量数据库的 schema 是隐式的你存进去的是 embedding 向量检索靠的是距离计算中间没有任何人类可读的中间态。而 SQLite 的表结构、索引定义、FTS5 的 tokenize 配置全部是明文 SQL。你可以用DB Browser for SQLite直接打开.db文件看到每一行数据、每一个索引、每一次 BM25 计算的原始 token。当 Agent 返回的结果不理想时你能立刻定位是分词器切错了词比如把 “user_id” 当成两个词还是权重配置偏移了比如给description字段的 BM25 k1 设得太低。这种透明度是调试智能体行为的基石。我见过太多团队在向量库上花两周调参最后发现问题是原始数据里有一半字段名是中文拼音缩写embedding 模型根本没学过。第三与开发工作流天然融合。设计师用 Figma 插件查设计规范库工程师用 Cursor 查代码注释库产品经理用 Notion 插件查需求文档库——这些场景的共同点是数据源就在本地文件系统里且格式高度结构化JSON Schema、Markdown 表格、YAML 配置。SQLite 支持直接导入 CSV/JSON支持虚拟表映射外部文件甚至能用json_extract()函数解析嵌套 JSON。这意味着你不需要把 Figma 的 design tokens 导出再清洗再入库而是用一条INSERT INTO tokens SELECT * FROM json_each(readfile(tokens.json))就能完成同步。这种“数据不动逻辑动”的范式才是 context-mode 落地的关键。2.2 FTS5 BM25 不是“复古”而是对检索本质的回归很多人一看到 BM25就觉得是“老技术”不如向量检索“高级”。但 BM25 的核心优势恰恰在于它不试图理解语义只精确匹配统计相关性。这在 context-mode 场景下是巨大优势可控性BM25 的公式是确定的score IDF * (k1 * tf / (tf k1 * (1 - b b * (dl / avgdl))))。其中k1控制词频饱和度b控制文档长度归一化IDF是逆文档频率。你可以根据业务需求精确调整比如在代码库搜索中k1设为 1.5让高频关键词如null、error不过度稀释低频但关键的词如NullPointerException在设计规范库中b设为 0.1因为规范条目长度固定无需长度归一化。这种颗粒度的控制在向量检索里是不存在的——你只能调 top-k 或 threshold无法干预单个 token 的贡献权重。可解释性FTS5 提供bm25()函数你可以直接在 SQL 里写SELECT title, bm25(config) FROM docs WHERE docs MATCH audit log ORDER BY bm25(config)然后用EXPLAIN QUERY PLAN查看它实际用了哪些索引、扫描了多少行。更进一步fts5vocab虚拟表能让你看到每个 token 的rank文档频率、ndoc包含该 token 的文档数从而判断“audit”这个词是否真的在你的数据集里有足够区分度。这种能力让检索结果不再是黑盒输出而是可审计的决策依据。零 embedding 成本向量检索要求对每一条数据做 embedding 编码这需要 GPU 或专用 CPU 加速。而 FTS5 的索引构建就是标准的倒排索引纯 CPU 运算且增量更新极快。我们一个 50 万行的 API 文档库全量重建 FTS5 索引耗时 3.2 秒而用 sentence-transformers 生成 embedding同等数据量需 18 分钟。对于需要频繁更新的本地知识库比如每日同步 Git 提交记录这个时间差就是能否自动化的生死线。提示FTS5 的tokenize配置是性能分水岭。默认的unicode61分词器对中文支持极差会把“用户权限”切成“用 户 权 限”必须显式指定tokenizeunicode61 remove_diacritics0并配合prefix2 3支持 2-gram 和 3-gram才能兼顾中英文混合检索。这个细节在绝大多数教程里被忽略但它是解决 “delphi sqlite 亂碼” 类问题的真正钥匙——乱码往往不是编码问题而是分词器把 UTF-8 字节当 ASCII 处理了。3. 实操核心从零搭建一个可工作的 context-mode MCP Server含完整配置与参数详解现在我们进入最硬核的部分亲手搭一个真正能被 Cursor、Dify、Figma 插件调用的 MCP Server。这里不依赖任何“MCP 官方 SDK”目前并不存在成熟 SDK而是用最简路径——Python Flask sqlite3 FTS5全程 127 行代码所有依赖均为标准库或 pip install 即可。目标是启动后Agent 发送一个标准 MCP 请求Server 返回带 BM25 排序的 SQLite 查询结果。3.1 数据准备构建一个真实的上下文数据库以 API 文档库为例我们以一个典型的开发者上下文——内部 API 文档库——为例。假设你有一个api_docs.json文件结构如下[ { id: auth_login, title: 用户登录, path: /v1/auth/login, method: POST, description: 验证用户名密码返回 JWT token。注意密码需 SHA256 加密后传输。, params: [{name: username, type: string, required: true}, {name: password, type: string, required: true}], response: {code: 200, data: {token: string, expires_in: number}} }, { id: user_profile, title: 获取用户资料, path: /v1/user/profile, method: GET, description: 根据 token 获取当前用户详细信息包括头像、昵称、角色权限。, params: [{name: token, type: string, required: true}], response: {code: 200, data: {avatar: string, nickname: string, roles: [string]}} } ]第一步创建 SQLite 数据库并启用 FTS5# 创建空数据库 sqlite3 api_docs.db-- 启用 FTS5 扩展SQLite 3.22 默认内置 CREATE VIRTUAL TABLE docs_fts USING fts5( id, title, path, method, description, contentdocs, tokenizeunicode61 remove_diacritics0 prefix2 3 ); -- 创建主表存储原始结构化数据 CREATE TABLE docs ( id TEXT PRIMARY KEY, title TEXT NOT NULL, path TEXT NOT NULL, method TEXT NOT NULL, description TEXT, params TEXT, -- 存 JSON 字符串 response TEXT -- 存 JSON 字符串 ); -- 创建触发器当主表插入/更新时自动同步到 FTS5 表 CREATE TRIGGER docs_ai AFTER INSERT ON docs BEGIN INSERT INTO docs_fts(rowid, id, title, path, method, description) VALUES (new.rowid, new.id, new.title, new.path, new.method, new.description); END; CREATE TRIGGER docs_au AFTER UPDATE ON docs BEGIN INSERT INTO docs_fts(docs_fts, rowid, id, title, path, method, description) VALUES (delete, old.rowid, old.id, old.title, old.path, old.method, old.description); INSERT INTO docs_fts(rowid, id, title, path, method, description) VALUES (new.rowid, new.id, new.title, new.path, new.method, new.description); END; -- 导入 JSON 数据SQLite 3.38 支持 json_each .mode json .import api_docs.json temp_import INSERT INTO docs SELECT id, title, path, method, description, json(json_extract(value, $.params)), json(json_extract(value, $.response)) FROM temp_import; DROP TABLE temp_import;关键点解析tokenizeunicode61 remove_diacritics0 prefix2 3这是解决中文检索的核心。remove_diacritics0保留变音符号对某些技术术语如café有用prefix2 3启用 2-gram 和 3-gram让“用户权限”能被切分为“用户”、“权限”、“用户权”、“权限配”等大幅提升中文短语匹配率。触发器设计AFTER INSERT/UPDATE确保主表变更实时反映到 FTS5 索引避免手动INSERT INTO docs_fts ...的繁琐和遗漏。contentdocs将 FTS5 表绑定到主表docs这样MATCH查询能直接关联主表字段。3.2 MCP Server 实现127 行代码的极简协议网关MCP 协议的核心是定义了一组标准化的tool调用接口。我们实现最常用的search工具# mcp_server.py import sqlite3 import json from flask import Flask, request, jsonify app Flask(__name__) DB_PATH api_docs.db def init_db(): conn sqlite3.connect(DB_PATH) conn.execute(PRAGMA journal_modeWAL) # 启用 WAL 模式提升并发读写 conn.close() app.route(/tools/search, methods[POST]) def search_tool(): try: # 解析 MCP 请求体 payload request.get_json() query payload.get(query, ) if not query.strip(): return jsonify({error: query is required}), 400 # 构建 FTS5 查询支持 AND/OR/NOT 语法 # 示例login AND POST 或 用户登录 fts_query query.replace(, ) # SQLite FTS5 转义双引号 # BM25 参数调优k11.2, b0.75 是经典值但需根据数据调整 # 这里我们让 title 字段权重更高乘以 2.0因为标题最能代表意图 conn sqlite3.connect(DB_PATH) conn.row_factory sqlite3.Row # 启用字典式访问 cursor conn.cursor() # 执行 FTS5 检索按 BM25 排序并 JOIN 主表获取完整字段 sql SELECT d.*, bm25(docs_fts, 1.2, 0.75, 2.0, 1.0, 1.0, 1.0) AS score FROM docs_fts JOIN docs d ON docs_fts.rowid d.rowid WHERE docs_fts MATCH ? ORDER BY score DESC LIMIT 10 cursor.execute(sql, (fts_query,)) results cursor.fetchall() conn.close() # 格式化为 MCP 响应符合 tool_result schema items [] for row in results: items.append({ id: row[id], title: row[title], path: row[path], method: row[method], description: row[description], score: round(row[score], 4), relevance: high if row[score] 15.0 else medium if row[score] 8.0 else low }) return jsonify({ type: tool_result, result: { items: items, total_count: len(items), query: query } }) except Exception as e: return jsonify({error: str(e)}), 500 if __name__ __main__: init_db() app.run(host127.0.0.1, port8000, debugTrue)启动服务pip install flask python mcp_server.py3.3 MCP 请求与响应详解一次真实调用的全链路剖析现在模拟一个 Agent比如 Cursor发送的 MCP 请求POST http://127.0.0.1:8000/tools/search Content-Type: application/json { type: tool_call, tool: search, arguments: { query: 用户登录 POST } }Server 返回{ type: tool_result, result: { items: [ { id: auth_login, title: 用户登录, path: /v1/auth/login, method: POST, description: 验证用户名密码返回 JWT token。注意密码需 SHA256 加密后传输。, score: 28.4567, relevance: high } ], total_count: 1, query: 用户登录 POST } }关键参数解读bm25(...)函数的七个参数k1,b,w1,w2,w3,w4,w5。前两个是全局 BM25 参数后五个是各列的权重对应id,title,path,method,description。我们设w22.0title 权重加倍因为用户提问“用户登录”时title 字段的匹配度远高于 description。score值的绝对大小无意义但相对排序决定结果优先级。relevance字段是业务层的语义映射方便 Agent 决策score 15.0视为高相关可直接引用8.0 score 15.0为中相关需二次确认 8.0为低相关应忽略。LIMIT 10是硬性约束防止 Agent 一次性拿到过多噪声数据。实际项目中可根据 Agent 的 token 限制动态调整。注意MCP 协议要求tool_result必须包含type和result字段且result结构由工具定义。这里我们定义了items数组每个 item 包含业务关键字段和scoreAgent 可直接用item.title item.description作为上下文注入 prompt。不要试图在result里塞原始 SQL 或数据库连接信息——那违反了 context-mode 的“上下文隔离”原则。4. 实战避坑指南那些只有亲手部署过才会懂的 7 个致命细节我花了三个月在三个不同客户现场部署 context-mode 方案从 Figma 插件到 Unity 编辑器集成踩过的坑足够写一本小册子。下面这 7 个问题90% 的初学者会在前两天遇到且网上几乎找不到答案。它们不是“配置错误”而是对 context-mode 本质理解偏差导致的系统性陷阱。4.1 陷阱一“SQLite 安装教程”救不了你真正的问题是 WAL 模式没开你按教程装好了 SQLitesqlite3 --version显示 3.35一切正常。但一运行 FTS5 检索CPU 占用飙到 100%查询耗时从 12ms 涨到 1200ms。原因没启用 WALWrite-Ahead Logging模式。默认的 DELETE 模式在高并发读写时会锁整个数据库文件而 MCP Server 的典型负载是一个 Agent 查询未结束另一个已发起新请求。解决方案只有一行PRAGMA journal_modeWAL;执行后journal_mode返回wal即生效。WAL 模式允许多个读者同时读写者只锁住 WAL 文件彻底解除瓶颈。这是 SQLite 性能调优的“第一课”但所有“SQLite 安装教程”都把它藏在“高级特性”章节里而 context-mode 的场景恰恰是它的最佳用武之地。4.2 陷阱二“BM25 检索大模型”是个误导性概念BM25 和 LLM 是上下游关系不是替代关系热搜里“bm25检索 大模型”让人误以为 BM25 能替代 LLM 做生成。错。BM25 的唯一任务是从海量候选中精准筛选出 Top-K 个最相关的原始数据片段。LLM 的任务是基于这 K 个片段生成自然语言回答或代码。两者是流水线关系不是竞争关系。常见错误是把 BM25 的score当成置信度阈值score 10就拒绝返回。这会导致大量合理结果被过滤。正确做法是BM25 只负责排序LLM 负责判断相关性。我们在 Dify 的 Skill 配置里把top_k5固定然后让 LLM 的 system prompt 明确说“你只能从以下 5 个 API 文档片段中提取信息不得编造”。4.3 陷阱三“delphi sqlite 亂碼”的真相不是编码问题是分词器把 UTF-8 当 ASCII 解析当你用 Delphi 或其他老框架连接 SQLite看到中文变成乱码第一反应是改PRAGMA encodingUTF-8。但 SQLite 的 encoding pragma 只影响PRAGMA命令本身的输出不影响 FTS5 的分词。真正原因是unicode61分词器默认remove_diacritics1它会把 UTF-8 多字节序列强行按单字节处理导致“用户”被切成e7 94 a8UTF-8 字节→e7、94、a8三个无效 ASCII 字符。解决方案已在 2.1 节强调tokenizeunicode61 remove_diacritics0。这是 SQLite FTS5 中文支持的“黄金配置”必须写死在CREATE VIRTUAL TABLE语句里。4.4 陷阱四MCP Server 的/health端点不是可选的而是 Agent 重试机制的开关很多教程只实现/tools/search忽略健康检查。后果是Agent如 Cursor在首次调用失败后会不断重试直到超时。而 MCP 协议规定Agent 必须先 GET/health返回200 OK才发起工具调用。一个健壮的/health应检查SQLite 数据库文件是否存在且可读FTS5 表是否已创建SELECT count(*) FROM sqlite_master WHERE typetable AND namedocs_fts至少有一条测试数据SELECT count(*) FROM docs。app.route(/health, methods[GET]) def health_check(): try: conn sqlite3.connect(DB_PATH) cursor conn.cursor() cursor.execute(SELECT count(*) FROM sqlite_master WHERE typetable AND namedocs_fts) if cursor.fetchone()[0] 0: return jsonify({status: error, message: FTS5 table not found}), 503 cursor.execute(SELECT count(*) FROM docs) if cursor.fetchone()[0] 0: return jsonify({status: error, message: No data in docs table}), 503 conn.close() return jsonify({status: ok, timestamp: int(time.time())}) except Exception as e: return jsonify({status: error, message: str(e)}), 5034.5 陷阱五“cursor 连接蓝湖 mcp”失败根源是跨域CORS没配不是认证问题Figma/Cursor 等 Electron 应用发起的 MCP 请求默认带Origin: file://或Origin: null。Flask 默认拒绝所有跨域请求。错误日志里只会显示403 Forbidden让你误以为是 OAuth 认证失败。解决方案是加 CORSpip install flask-corsfrom flask_cors import CORS CORS(app, origins[*]) # 生产环境请替换为具体域名或者更安全的CORS(app, origins[http://localhost:5173, chrome-extension://...])4.6 陷阱六FTS5 的prefix不是“锦上添花”而是中文检索的生死线prefix2 3的作用是生成 2-gram 和 3-gram 索引。没有它“用户权限”只能匹配到单字“用”、“户”、“权”、“限”完全无法识别短语。但prefix会显著增大索引体积约 3-5 倍。平衡点在于对标题、描述等短文本字段开prefix对 ID、路径等长字符串字段不开。我们的docs_fts定义里只对title和description启用 prefixpath和method用 exact match。这样既保证中文检索精度又控制索引膨胀。4.7 陷阱七MCP 的tool_call不是 REST API不能用 curl 直接测试你用curl -X POST http://localhost:8000/tools/search -d {query:login}测试得到400 Bad Request。因为 MCP 协议要求Content-Type: application/json且type字段必须是tool_call。正确的测试命令curl -X POST http://127.0.0.1:8000/tools/search \ -H Content-Type: application/json \ -d { type: tool_call, tool: search, arguments: { query: 用户登录 } }更推荐用 VS Code 的 REST Client 插件保存为.http文件避免命令行转义错误。5. 常见问题速查表从搜索不到结果到性能骤降一份实战排查清单问题现象可能原因排查命令/步骤解决方案搜索完全无结果空数组1. FTS5 表未绑定到主表2.MATCH查询语法错误如漏掉AND3. 数据未触发同步触发器失效sqlite3 api_docs.db→.schema docs_fts检查contentdocsSELECT * FROM docs_fts WHERE docs_fts MATCH test测试基础检索SELECT count(*) FROM docs_fts看索引行数是否为 0重新执行CREATE VIRTUAL TABLE语句检查触发器CREATE TRIGGER是否存在手动INSERT INTO docs_fts ...同步测试数据结果相关性差高分项不匹配1. BM25 权重配置失衡2.tokenize未适配中文3.prefix未启用SELECT title, bm25(docs_fts) FROM docs_fts WHERE docs_fts MATCH 用户登录SELECT * FROM docs_fts WHERE docs_fts MATCH 用户看是否分词正确SELECT * FROM docs_fts WHERE docs_fts MATCH 用户登录测试短语匹配调整bm25()的权重参数强制tokenizeunicode61 remove_diacritics0 prefix2 3确保prefix在建表时声明查询耗时 100ms1. 未启用 WAL 模式2. FTS5 索引未优化3.LIMIT过大PRAGMA journal_mode;ANALYZE docs_fts;检查 SQL 中LIMIT是否为 100PRAGMA journal_modeWAL;ANALYZE docs_fts;将LIMIT设为 5-10Agent 报错 tool not found1. MCP Server 路径错误应为/tools/{tool_name}2.tool_call的tool字段值与路由不匹配检查 Flask 路由app.route(/tools/search)检查请求体tool: search确保路由路径、工具名、请求体tool字段三者完全一致中文显示为问号或方框1. 终端/IDE 字体不支持 UTF-82.sqlite3命令行未设置编码echo $LANGsqlite3 api_docs.db→.mode line→SELECT title FROM docs LIMIT 1;终端设置export LANGen_US.UTF-8在 Python 中conn.text_factory str这份清单来自我们为客户做现场支持时的真实工单记录。它不教你“理论”只告诉你当屏幕出现那个错误时下一步该敲什么命令、看哪一行日志、改哪一行配置。真正的效率就藏在这些确定性的动作里。6. 进阶扩展如何让 context-mode 支持多源异构数据JSON/YAML/Markdown一个真实的开发工作区上下文从来不止 SQLite 一种形态API 文档是 OpenAPI YAML设计规范是 Figma JSON技术博客是 Markdown 文件。context-mode 的终极形态是让 MCP Server 能统一接入这些格式对外提供一致的search工具。这不需要重写 Server只需增加数据适配层。6.1 虚拟表用 SQLite 的csv和json扩展直连外部文件SQLite 3.34 内置csv和json扩展无需额外依赖-- 将 Markdown 文件转为虚拟表需先用脚本提取标题和正文 CREATE VIRTUAL TABLE md_docs USING csv( filenamedocs.md, headeryes, columnstitle,content ); -- 将 OpenAPI YAML 转为 JSON再用 json_each 解析 .mode json .import openapi.json temp_openapi INSERT INTO docs SELECT json_extract(value, $.operationId) AS id, json_extract(value, $.summary) AS title, json_extract(value, $.path) AS path, json_extract(value, $.method) AS method, json_extract(value, $.description) AS description, json(json_extract(value, $.parameters)) AS params, json(json_extract(value, $.responses)) AS response FROM temp_openapi, json_each(json_extract(value, $.paths)); DROP TABLE temp_openapi;6.2 统一检索用UNION ALL聚合多源结果修改 MCP Server 的 SQL合并所有数据源SELECT api AS source, id, title, path, method, description, bm25(api_fts) AS score FROM api_fts ... UNION ALL SELECT md AS source, id, title, AS path, AS method, content AS description, bm25(md_fts) AS score FROM md_fts ... ORDER BY score DESC LIMIT 106.3 动态路由根据查询关键词自动选择数据源在/tools/search中加入简单路由逻辑if openapi in query.lower() or swagger in query.lower(): sql SELECT ... FROM api_fts ... elif .md in query or markdown in query.lower(): sql SELECT ... FROM md_fts ... else: sql SELECT ... FROM docs_fts ... # 默认这并非“银弹”但它证明了 context-mode 的核心思想协议MCP是稳定的数据源SQLite是灵活的而智能体Agent只关心“我能用什么工具做什么事”。你不需要说服每个工具都支持 SQLite只需要让它们都遵循 MCP 协议就能在一个统一的上下文里协作。我在最后想分享一个体会过去三年我见过太多团队把 80% 的精力花在“选哪个向量数据库”结果上线后发现90% 的用户查询都是精确的关键词匹配比如“查 login 接口”、“找 audit 日志字段”。context-mode 的价值不在于它有多炫酷而在于它诚实面对了这个现实——**最强大的上下文往往就藏在最朴素的 SQL 里等着你
返回列表