跳转到内容

上下文提供者插件模式

上下文提供者插件模式

学习目标

读完本章后,你将能够:

  • 理解上下文提供者在 AI 编程助手中的角色和设计目标
  • 设计双方法模式的 ContextProvider 接口(加载 + 获取)
  • 实现按需加载和懒执行的上下文提供者
  • 构建覆盖代码、文档、外部系统等多种数据源的上下文注入管线

前置知识


核心概念

什么是上下文提供者

上下文提供者(Context Provider)是 AI 编程助手中的一种插件模式,负责将外部数据源的内容注入到 LLM 的对话上下文中。与工具系统(Tool System)不同,上下文提供者是拉取式(pull-based)的:用户主动触发或选择后,提供者返回相关上下文片段,而不是由 LLM 自主调用执行。

与工具系统的区别

维度上下文提供者工具系统
触发方式用户通过 @mention 或子菜单选择LLM 自主决定调用
执行时机在发送给 LLM 之前注入在 LLM 响应过程中调用
输出形式文本片段(ContextItem)结构化结果 + 可能的文本
典型用例打开的文件、代码库、文档、Issues文件编辑、终端命令、搜索
协议getContextItems(query)Function Calling / MCP Tool

接口设计

双方法模式

上下文提供者通常实现两个核心方法:

interface ContextProvider {
// 方法 1:加载子菜单项(用于 @mention 下拉列表)
loadSubmenuItems(config: Config): Promise<SubmenuItem[]>;
// 方法 2:根据查询返回上下文片段
getContextItems(
query: string,
extras: ContextExtras
): Promise<ContextItem[]>;
}

loadSubmenuItems 的职责:

  • 返回该提供者可以提供的上下文列表
  • 用于 GUI 的 @mention 自动补全
  • 通常是轻量级操作(列举文件、列出文档等)

getContextItems 的职责:

  • 根据用户的查询返回相关的上下文片段
  • 可能涉及检索、搜索、嵌入向量匹配等操作
  • 返回的结果会被注入到 LLM 的系统提示或用户消息中

上下文片段结构

interface ContextItem {
content: string; // 实际文本内容,发送给 LLM
name: string; // 片段名称(如文件名、类名)
description: string; // 人类可读的描述
uri?: { filepath: string }; // 可选的来源位置
}

典型提供者分类

代码级提供者

提供者数据源检索方式
当前文件编辑器中当前打开的文件直接读取
选中代码用户选中的代码范围IDE API 获取
代码库整个项目的索引FTS / 向量检索 / Tree-sitter
文件树项目目录结构文件系统遍历
DiffGit 工作区变更git diff 或 IDE API
问题诊断IDE 的诊断信息(错误、警告)IDE diagnostics API
Git 提交Git 提交历史Git CLI 或 libgit2

文档级提供者

提供者数据源检索方式
文档外部文档 URL 集合文档索引 + 向量检索
网页搜索搜索引擎 APIHTTP 请求
URL指定的单个 URL网页抓取 + 提取

外部系统集成提供者

提供者数据源检索方式
GitHub IssuesGitHub APIREST API 查询
GitLab MRGitLab APIREST API 查询
Jira IssuesJira APIREST API 查询
数据库PostgreSQL 等SQL 查询 + 结果格式化
DiscordDiscord APIAPI 查询频道和消息
终端输出最近的终端命令输出终端缓冲读取

生命周期管理

加载阶段

用户打开 IDE
配置加载 → 注册上下文提供者
提供者按需初始化(可能建立连接、加载索引)
GUI 请求 loadSubmenuItems → 构建 @mention 列表

执行阶段

用户输入 @provider_name query
GUI 发送请求到 Core
Core 查找对应的提供者实例
调用 getContextItems(query, extras)
过滤和 Token 预算检查
注入到 LLM 消息中

按需加载模式

对于大型数据源(如代码库索引、文档索引),提供者使用懒执行

  • loadSubmenuItems 只返回轻量级元数据
  • getContextItems 时才触发实际的检索操作
  • 可能涉及异步索引构建(如文档首次访问时的索引建立)

设计权衡

优势

  1. 可扩展性:新数据源只需实现一个接口,无需修改核心代码
  2. 用户控制:用户明确选择注入什么上下文,减少不必要的 Token 消耗
  3. 按需加载:懒执行避免启动时加载所有数据源
  4. 组合性:多个提供者可以同时激活,组合提供丰富的上下文

代价与挑战

  1. Token 预算:每个提供者的输出需要被截断或压缩以适配上下文窗口
  2. 检索相关性:提供者的检索质量直接影响 LLM 的回答质量
  3. 延迟:远程提供者(如 GitHub Issues API)可能引入网络延迟
  4. 一致性:不同提供者返回的格式和质量可能不一致,需要统一处理

替代方案

  • 自动上下文注入:不通过 @mention,而是由系统自动选择相关上下文(如 Autocomplete 中的隐式上下文检索)
  • 工具式获取:让 LLM 通过工具调用主动获取上下文,而非用户选择(Agent 模式)

安全考量

  • 敏感数据过滤:上下文提供者可能暴露代码中的密钥、配置等敏感信息,需要过滤机制
  • 外部 API 认证:GitHub、Jira 等提供者需要安全存储和传递认证凭据
  • 内容大小限制:防止恶意的大响应占用 LLM 上下文

参考来源