Continue 源码分析:IDE、Agent Loop 与 FIM Autocomplete 如何协作
AI 参与说明(Agent:Codex):本文由 Codex 阅读固定版本源码,并通过 Context7 核对官方架构说明、Agent 模式、Autocomplete 与模型角色文档后整理,使用项目 humanizer-zh 编辑中文正文。资料整理于 2026-10-28;分析采用静态源码核对,未运行完整 Continue、调用模型或测量补全延迟。执行入口为 Codex Desktop;完整模型标识与 reasoning effort 未取得可核验的任务级运行记录。
Continue 把大模型接入开发环境:从编辑器取得代码与任务信息,组织模型请求,再把响应转成回答、补全、文件修改和工具操作。理解它的关键,是沿着一次请求看清模型与程序分别负责什么,以及工具结果怎样成为下一轮决策的依据。
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| Coding Agent | 编码智能体 | 根据任务读写代码、调用开发工具并处理结果的软件助手 |
| Agent Loop | 智能体循环 | 模型提出操作,程序执行并回传结果,模型继续决定下一步 |
| Autocomplete | 自动补全 | 根据光标附近与相关文件内容生成内联代码建议 |
| Core | 核心模块 | Continue 中配置、模型调用、上下文、工具与补全等共享逻辑所在的模块 |
| IDE Adapter | 集成开发环境适配层 | 把文件读取、搜索、终端和编辑等能力接到具体编辑器上的代码;本文用于概括这层职责 |
| Context | 上下文 | 当前请求能交给模型的规则、消息、代码和工具结果 |
| Compaction | 上下文压缩 | 用摘要保留重要状态,为后续请求腾出空间 |
| Tool Call | 工具调用 | 模型返回的工具名称与结构化参数,交由程序检查和执行 |
| FIM(Fill-in-the-Middle) | 中间填充 | 同时提供缺口之前和之后的代码,让模型生成中间部分 |
| MCP(Model Context Protocol) | 模型上下文协议 | 让助手发现并调用外部工具、读取资源等能力的协议 |
| Provider | 提供方 | 将模型能力通过具体接口提供给 Continue 的服务或本地运行环境 |
| RAG(Retrieval-Augmented Generation) | 检索增强生成 | 先检索相关资料,再将资料交给模型生成响应 |
Continue runs the development workflow around a model: it selects context, exposes tools, executes permitted actions, and feeds the results back into the conversation. 这句话概括的是运行职责;各入口的循环位置和文件修改方式仍有差别。
官网已经确认 Continue 加入 Cursor,当前 README 则说明仓库停止积极维护、对所有用户只读,并完成最后的 2.0.0 发布,移除了匿名遥测和认证等。本文的源码结论固定在 commit 5522c6f,不能据此推断 Cursor 的内部实现。官网公告 固定版本 README
Context7 用于定位和交叉核对资料,本文引用落到官方原始页面与固定源码。在线文档仍有旧账号登录步骤,而最终 README 已明确移除认证;涉及当前项目状态时以固定版本为准。CLI Quickstart
从界面到 Core:把编辑器能力接进来
Continue 的 IDE 扩展包含 React 界面、Core 和 IDE Adapter。下面表示逻辑职责与消息流,不表示每个方框都是独立进程。
flowchart TB
gui["React GUI<br/>Chat / Agent Loop"] <-->|"请求与状态"| host["IDE 扩展宿主"]
host <-->|"消息协议"| core["Core<br/>配置、Context、模型、工具、补全"]
host <--> adapter["IDE Adapter<br/>VS Code / JetBrains"]
adapter <--> workspace["文件、搜索、终端、Diff"]
core <--> provider["模型 Provider<br/>云端 API / 本地模型"]
core <--> mcp["MCP Server"]
| 源码位置 | 职责 | 阅读时应留意的边界 |
|---|---|---|
gui/ | 聊天输入、会话状态、工具过程和 IDE Agent Loop 编排 | React 界面承担了实际循环逻辑 |
core/ | 配置、模型、Context、工具、补全与索引 | Core 提供共享服务,循环不全部集中在这里 |
extensions/vscode/ | 对接 VS Code 的文件、编辑器、终端和 Diff | Core 在扩展进程中直接实例化 |
extensions/intellij/ 与 binary/ | Kotlin 插件、React Webview 和 Core 二进制 | 插件与 Core 通过 stdin/stdout 消息通信 |
extensions/cli/ | 命令行交互及独立 Agent Loop | 有自己的工具、权限服务和 MCP 生命周期 |
packages/ | 配置解析、模型 API 适配等共享模块 | IDE 与 CLI 复用能力包,也分别组织运行流程 |
VS Code 初始化时创建 InProcessMessenger、VsCodeMessenger 和 new Core(...)。GUI 请求通过扩展宿主转发;Core 需要读取文件、查询定义或执行命令时,再使用 IDE 接口。JetBrains 把类似消息送给 Core 二进制,因此可以复用 TypeScript 核心逻辑。VS Code 初始化 消息转发 JetBrains 架构说明
Agent Loop:一次修改任务怎样继续推进
以“给登录接口增加限流,并运行相关测试”为例,模型需要先知道接口在哪里,再决定如何修改。Continue 在每轮请求中准备消息、项目规则和可用工具,把文本及 Tool Call 的流式增量写入会话状态。
flowchart TB
input["用户任务与 Context"] --> request["组织消息、规则<br/>与工具定义"]
request --> model["请求模型"]
model --> decision{"响应含 Tool Call?"}
decision -->|"没有"| answer["展示回答并结束本轮"]
decision -->|"有"| policy["检查参数与执行策略"]
policy --> approval{"允许执行?"}
approval -->|"待确认"| wait["等待用户决定"]
wait --> approval
approval -->|"允许"| tool["执行搜索、读文件<br/>修改或命令"]
approval -->|"未获许可"| stop["暂停或按配置<br/>处理拒绝"]
tool --> result["工具结果或执行错误<br/>写回会话"]
result --> request
模型可能先搜索登录入口,读取实现和测试,再提出文件修改,最后运行测试。测试返回的失败信息进入会话后,模型才能据此修正。图中动作是控制流示意,具体工具和确认方式取决于模式及配置。
IDE 源码中的真实调用链是:
streamResponseThunk
→ streamNormalInput:构造规则、消息与工具
→ llm/compileChat:计算预算并裁剪
→ llmStreamChat:接收文本与 Tool Call
→ evaluateToolPolicies:判断执行策略
→ callToolById:分派 GUI 或 Core 工具
→ streamResponseAfterToolCall:写入工具结果
→ streamNormalInput:发起下一轮请求
这段是源码阅读路径,不是可执行命令。streamResponseAfterToolCall 等待当前一轮工具完成,把结果写成 role: "tool" 消息,再继续请求模型。执行结果和失败信息由此改变下一轮 Context。用户拒绝后的续轮受 continueAfterToolRejection 配置影响,图中将这条分支单独保留。IDE 编排 工具结果续轮
Tool availability and execution permission are separate decisions. Chat 不提供工具;Plan 提供只读工具;Agent 可以提供写文件和执行命令的工具。模型提出调用之后,程序仍需检查执行策略;设为 Automatic 的工具可以跳过交互确认,因此不能把流程理解成每个操作都弹一次确认。官方 Agent 原理 模式与工具策略
MCP 扩展这个循环可用的工具与信息来源。Core 将内置工具和 MCP 工具的结果转成可进入会话的内容;MCP Server 提供能力,继续请求模型的决定由 Continue 的 Agent Loop 组织。工具分派
CLI 的循环则在 extensions/cli/src/stream/streamChatResponse.ts。它从历史服务取消息,重新准备 system message 与工具,检查 Context 预算,再请求模型、执行工具并继续。CLI 复用配置、模型适配、消息转换和部分编辑算法,但文件写入不经过 IDE 的 Diff 状态机。CLI 循环
Context:每一轮选择什么,保留多少
模型能看到的内容包括用户输入、选中代码、显式引用、项目规则、历史消息与工具结果。Continue 要把这些内容装进有限的 Context window,同时为模型输出留空间。
普通发送路径先计算 token 预算并裁剪;较长会话还可以通过 Compaction 总结旧历史,保留当前目标、已做决定与重要状态。CLI 在模型请求前及工具返回后检查预算。压缩或裁剪都会改变后续请求实际携带的信息;磁盘上的完整仓库不会自动变成模型可见的 Context。模型消息处理 CLI Compaction
当前官方建议让 Agent 主动探索和搜索文件,通过 .continue/rules 加入项目约定,通过 MCP 取得外部仓库或文档。对于登录限流任务,这意味着先发现真实入口,再读相关实现,而不是凭文件名猜测代码。代码库与文档感知指南
Autocomplete:用 FIM 填充光标处的代码
Autocomplete 有独立的延迟目标与调用链。它主要根据光标前后的代码预测缺口,再把结果作为内联建议交给 IDE。
prefix: function add(a, b) { return
completion: a + b;
suffix: }
这是 FIM 输入与输出的示意,空格和换行随实际文件变化。模型同时获得 prefix 与 suffix,就能根据后续代码约束中间内容。支持原生 FIM 的 Provider 走 streamFim(prefix, suffix);其余路径使用模型专属模板,通过 streamComplete(prompt) 请求生成。生成器实现
CompletionProvider 的流程包括防抖和文件过滤、取得片段、按 token 预算组织请求、查询缓存或调用模型、流式过滤、后处理,再返回建议。补充片段来自 import 相关定义、光标 AST 路径相关定义,以及最近打开、访问或编辑的文件。AST(Abstract Syntax Tree,抽象语法树)用树表示代码结构,光标所在位置可以关联到沿途的语法节点;这些上下文路径会结合 Tree-sitter 与 IDE 的定义查询能力。补全入口 片段收集 官方 Context selection
防抖减少连续输入触发的重复请求;缓存和生成器复用避免重复生成;取消机制使过期请求停止;过滤器处理重复行、括号与停止标记等内容。源码中存在这些优化,并不构成端到端延迟保证。Autocomplete 的片段选择也不能直接等同于每次输入都查询整库向量索引。
代码修改:生成建议之后还要应用与反馈
模型给出修改后,Continue 仍要计算真实文件内容、呈现差异并处理接受或取消。固定版本中有两条主要路径:
| 输入形式 | 处理方式 | 返回给 Agent 的信息 |
|---|---|---|
| 精确 Search and Replace | 重新读文件,验证旧文本匹配,再计算新内容 | 替换结果或匹配失败 |
| 代码块、Diff 或较自由的修改建议 | 尝试确定性应用,必要时由 apply 模型合入原文件 | 应用状态、接受或取消等结果 |
VS Code 的 ApplyManager 保存原文件内容,跟踪应用状态,并交给 Diff 管理器展示修改。精确替换已经算出完整新内容时,可以直接生成 Diff;其他建议则尝试确定性应用或 Unified Diff,必要时进入模型辅助的 apply 流程。因此,文件修改不必每次额外调用模型重写整份文件。ApplyManager 代码块应用
GUI 将最终应用状态反馈到工具结果;自动格式化造成的额外变化也能被反馈,帮助模型避免下一次替换继续使用过期文本。CLI 使用文件系统执行写入,不经过这一 IDE 展示流程。应用状态处理 CLI 编辑工具
模型角色:让不同任务使用合适的接口
Continue 在模型配置中使用 roles 区分任务,运行时按角色选择实例。
| 常用角色 | 职责 |
|---|---|
chat | 对话和 IDE Agent 推理请求 |
autocomplete | 内联代码建议 |
edit | 根据指令生成代码修改 |
apply | 把修改建议应用到文件 |
embed | 为检索生成向量 |
rerank | 对候选检索结果重新排序 |
表格列出本文涉及的常用角色,并非完整 schema。模型适配层处理消息格式、工具参数、流式响应及取消等差异;edit、apply 等路径还存在回退选择。选择远程 Provider 或本地模型,会影响可用能力、成本和数据流向。官方模型角色文档源码 角色选择实现 模型适配基类
旧 Codebase RAG:保留实现与当前推荐路径
官方已经将 @Codebase 标为 Deprecated,迁移说明也涵盖 @Folder。固定版本源码仍有 CodebaseContextProvider,其索引依赖包括 embeddings、fullTextSearch、chunk,仍调用向量检索相关实现。应分别理解“旧入口实现还在”与“当前文档推荐 Agent 主动搜索”。弃用说明 Context Provider
旧管线先按忽略规则遍历文件,利用 Tree-sitter 等方法分块,生成 embedding;向量存入 LanceDB,代码块、元数据和全文索引存入 SQLite。检索时结合向量、全文以及其他文件候选,去重后可选 rerank,最终把相关代码片段、路径与行号加入 Context。向量索引 全文索引 混合检索与重排
索引利用时间戳、内容哈希及目录、分支等标记做增量更新,避免每次重新处理全部文件。但当前索引构建入口在没有选定 embed 模型时会返回空列表,不能据检索层支持跳过向量查询,就推断一定能独立建出全文索引。索引构建入口 增量更新
Local index storage does not imply local embedding inference. 索引存储位置与 embedding Provider 是两个配置维度;是否将代码交给远程模型,仍取决于实际使用的 Provider。
如何沿源码验证这些机制
下面的 Bash 命令只下载和搜索公开源码,需要 Git 与 ripgrep,不安装 Continue,也不会调用模型。本文通过固定源码核对了对应文件与符号;没有在该检出中运行完整应用。
git clone https://github.com/continuedev/continue.git
cd continue
git checkout --detach 5522c6f44ca0ac3528b37244818fbfa39b5af470
rg -n 'new Core|InProcessMessenger' extensions/vscode/src/extension/VsCodeExtension.ts
rg -n 'streamNormalInput|evaluateToolPolicies|callToolById' gui/src/redux/thunks
rg -n 'streamFim|streamComplete' core/autocomplete/generation/CompletionStreamer.ts
rg -n 'while \(true\)' extensions/cli/src/stream/streamChatResponse.ts
预期分别定位到 VS Code 的 Core 装配、IDE Agent 编排、Autocomplete 的接口选择和 CLI 循环。继续阅读时,从 core/core.ts 看服务与消息入口,从 GUI 追踪一次 Tool Call,再进入 Autocomplete。这样能分别回答:Context 从哪里来、哪个模块决定续轮、修改怎样落到文件,以及哪些能力可以跨入口复用。
关联阅读
- Agent 开发中的测试方法:区分任务要求、结果判据与验证证据,帮助判断工具执行后是否完成目标。
- Pi Agent 框架架构:比较模型接口、Agent Loop 与 Coding Agent 的包边界。
- Context7 源码分析:理解文档检索如何经过 MCP 接入当前开发环境。