一、整体流程
关键流程
1. Agent 注册与分发(ChatAgentService)
ChatAgentService.register()注册所有agent(如 default、workspace、editor 等)。
- 通过
createAgent创建的agent,分发到ChatParticipantRequestHandler。 - 用户选择 agent 模式,ChatAgentService 根据 agentName 获取对应 agent。
2. 意图识别(AgentIntent)
-
意图选择
ChatParticipantRequestHandler.getResult()会调用selectIntent(),根据请求内容、上下文、命令等选择合适的intent。- 如果有明确的command,则直接用command.intent。
- 否则根据上下文(如编辑器、选择范围等)推断意图(如Generate、Edit等)。
-
意图实例化 通过
IIntentService.getIntent()获取具体的intent实例(如AgentIntent)。 -
意图处理 调用intent的
handleRequest()方法,进入AgentIntent的处理流程。构建prompt或者调用tools
3. AgentPrompt 构建
AgentIntent.handleRequest()调用buildPrompt(),通过PromptRenderer渲染AgentPrompt。AgentPrompt聚合系统消息、用户消息、历史、工具等,A、B文件夹作为上下文变量传递到prompt。
工具调用(ToolCallingLoop & ToolService)
-
AgentIntent通过getAvailableTools()调用ToolService.getEnabledTools(),根据模型能力和配置筛选可用工具。LLM 返回 tool call 请求(如调用“代码搜索”工具)。 -
若需要调用工具,则进入
ToolCallingLoop.run(),负责多轮工具调用的调度与循环,直到满足条件或达到上限。 -
ToolService实现具体工具逻辑(如在 A、B 文件夹中搜索相关代码)。 -
工具结果返回给 LLM,LLM 生成最终回复,放到上下文中。
5. 相关类协作
-
ChatAgentService:agent 注册、分发
-
AgentIntent:意图识别
-
AgentPrompt:prompt 构建
-
ToolCallingLoop:多轮工具调用
-
ToolService:工具实现
-
PromptContext:上下文聚合
-
IntentRequestHandler:意图分发
-
LLM:大模型推理
类图
逻辑图(Mermaid)
flowchart TD
UserInput[用户输入: 查找相关代码]
ChatAgentService
AgentIntent
AgentPrompt
PromptContext
LLM
ToolCallingLoop
ToolService
ToolResult[工具结果]
UserOutput[最终回复]
UserInput --> ChatAgentService
ChatAgentService --> AgentIntent
AgentIntent --> AgentPrompt
AgentPrompt --> PromptContext
AgentPrompt --> LLM
LLM --> ToolCallingLoop
ToolCallingLoop --> ToolService
ToolService --> ToolResult
ToolResult --> ToolCallingLoop
ToolCallingLoop --> AgentPrompt
AgentPrompt --> UserOutput
时序图(Mermaid)
sequenceDiagram
participant User
participant ChatAgentService
participant AgentIntent
participant AgentPrompt
participant PromptContext
participant LLM
participant ToolCallingLoop
participant ToolService
User->>ChatAgentService: 输入“请帮我查找相关代码”
ChatAgentService->>AgentIntent: 识别意图
AgentIntent->>AgentPrompt: 构建Prompt
AgentPrompt->>PromptContext: 聚合上下文(A、B文件夹)
AgentPrompt->>LLM: 发送Prompt
LLM->>ToolCallingLoop: 请求工具调用
ToolCallingLoop->>ToolService: 搜索代码
ToolService-->>ToolCallingLoop: 返回搜索结果
ToolCallingLoop-->>LLM: 工具结果
LLM-->>AgentPrompt: 生成回复
AgentPrompt-->>User: 展示结果
二、prompt工程
AgentPrompt
AgentPrompt 是 agent 模式下的主 prompt 构建器,负责将用户意图、上下文、历史消息、工具信息等整合为最终发送给 LLM 的 prompt。主要在src/extension/prompts/node/agent目录下面。主类定义src/extension/prompts/node/agent/agentPrompt.tsx
相关子组件:
DefaultAgentPrompt,SweBenchAgentPrompt(agentInstructions.tsx)AgentConversationHistory(agentConversationHistory.tsx)SummarizedConversationHistory(summarizedConversationHistory.tsx)AgentUserMessage(agentPrompt.tsx)ChatToolCalls(panel/toolCalling.tsx)
组成部分与功能
- SystemMessage:系统身份、规则、safety提示
- Instructions:根据配置选择
DefaultAgentPrompt或SweBenchAgentPrompt - CustomInstructions:用户自定义指令
- UserMessage:用户输入及上下文
- AgentConversationHistory:历史对话
- SummarizedConversationHistory:摘要历史(可选,支持cache breakpoints)
- ChatToolCalls:工具调用
- AgentUserMessage:当前用户消息的详细结构
关系说明
AgentPrompt聚合了上述所有部分,作为整体prompt的渲染器。AgentPromptProps作为数据传递的载体,贯穿所有子组件。
classDiagram
class AgentPrompt {
+render()
-getAgentCustomInstructions()
-getOrCreateGlobalAgentContext()
}
class DefaultAgentPrompt
class SweBenchAgentPrompt
class AgentConversationHistory
class SummarizedConversationHistory
class AgentUserMessage
class ChatToolCalls
AgentPrompt --> DefaultAgentPrompt
AgentPrompt --> SweBenchAgentPrompt
AgentPrompt --> AgentConversationHistory
AgentPrompt --> SummarizedConversationHistory
AgentPrompt --> AgentUserMessage
AgentPrompt --> ChatToolCalls
prompt构建
prompt构建是基于
TODO补充
三、工具实现(以codebase为例)
CodebaseTool用于在 VS Code 扩展中对整个工作区/代码库进行智能搜索、上下文提取和结果组织,供大模型调用。
-
支持多种调用方式,包括直接查询和“Agent”自动多轮调用。
-
通过
TokenLimit组件和maxChunks参数,严格控制传递给大模型的 token 数量,防止超长。
调用链
- Copilot Chat 触发代码库搜索(如 /codebase 查询)。codebaseTool 支持
scopedDirectories参数,可以指定多个目录或文件,限定搜索范围。 CodebaseTool.invoke被调用,参数包括查询内容、可选的目录范围等。分两个场景普通场景和agent场景- 如为普通模式,scopedDirectories 接受用户添加的路径
- 上下文提取:codebaseTool 在执行时,会将这些路径传递给 WorkspaceChunkSearchService,进行代码块(chunk)提取和检索。
- Chunk 生成:WorkspaceChunkSearchService 会将指定文件/文件夹内容分割成 chunk(代码片段),并根据查询进行相关性排序。
- Prompt 构建:最终选中的 chunk 会被拼接到 prompt 中,作为 LLM 的输入上下文。
- 若为 agent 场景,则走
invokeCodebaseAgent。- 创建 CodebaseToolCallingLoop(继承 ToolCallingLoop)
- run() 进入工具调用循环,支持多轮工具调用
- 每轮都可能重新构建 prompt,动态调整上下文
- 结果通过 ToolCallResultWrapper 渲染
+-------------------+ +---------------------+ +-----------------------------+
| AgentIntent | | CodebaseTool | | ToolCallingLoop |
+-------------------+ +---------------------+ +-----------------------------+
| 解析用户意图 | ----> | 处理codebase查询 | ----> | 工具调用循环,支持多轮调用 |
| 选择合适的Tool | | 组织prompt上下文 | | 控制调用次数/流程 |
+-------------------+ +---------------------+ +-----------------------------+
|
v
+-----------------------------+
| WorkspaceContextWrapper |
+-----------------------------+
| 渲染上下文,Token限制 |
+-----------------------------+
|
v
+-----------------------------+
| WorkspaceContext |
+-----------------------------+
| 组织/渲染代码块上下文 |
+-----------------------------+
|
v
+-----------------------------+
| WorkspaceChunkSearchService |
+-----------------------------+
| 代码块分割、检索、排序 |
+-----------------------------+
token管理
1、Chunk 检索与裁剪
- 过 embedding 距离或关键词匹配,对所有 chunk 进行相关性打分和排序。先截取前k个相关的chunk
- 按相关性降序遍历,累计 token 数,超预算则丢弃低分 chunk。
通过
MAX_CHUNK_TOKEN_COUNT、MAX_TOOL_CHUNK_TOKEN_COUNT等常量WorkspaceChunkSearchService.searchFileChunks
2、Prompt 渲染与压缩
agentIntent/AgentPrompt 支持 summarization,当 budget 超限时自动触发摘要/丢弃, 在 prompt 构建阶段自动检测并调用摘要/丢弃逻辑
分步渲染
-
promptRenderer 先渲染高优先级内容(如用户 query、摘要、最相关 chunk)
-
后续按优先级逐步补充低优先级内容
分布压缩
-
每渲染一部分内容,实时统计 token 数,若超出 tokenBudget,则动态丢弃或摘要低优先级内容。先摘要低分 chunk,再摘要高分 chunk。采用 LLM 或本地算法对 chunk 进行摘要(如提取主要函数、注释、接口等)。
-
用摘要内容替换原始 chunk,重新统计 token,支持多轮摘要, 直到满足预算。
代码
AgentIntent、AgentPrompt、promptRenderer、renderPromptElementJSON支持分步渲染prompt-tsx的PromptSizing、PromptElement动态 token 预算管理相关逻辑
Chunk 检索与裁剪流程
[用户输入/选择文件夹]
|
v
[文件遍历] --(分割)--> [Chunk 列表] --(embedding/关键词)--> [相关性排序]
| |
+--------------------(token预算裁剪)----------+
v
[选中 chunk 作为上下文]
Prompt 渲染与压缩流程
[选中 chunk/摘要/用户query]
|
v
[PromptRenderer 分步渲染]
|
v
[实时统计 token]
|
+--(超预算?)--是--> [丢弃/摘要低优先级内容]
| |
| v
+-------否-------->[输出完整 prompt]