copilot的codebase分析

166 阅读5分钟

一、整体流程

关键流程

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:大模型推理

类图

image.png

逻辑图(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:根据配置选择DefaultAgentPromptSweBenchAgentPrompt
  • 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 数量,防止超长。

调用链

  1. Copilot Chat 触发代码库搜索(如 /codebase 查询)。codebaseTool 支持 scopedDirectories 参数,可以指定多个目录或文件,限定搜索范围。
  2. CodebaseTool.invoke 被调用,参数包括查询内容、可选的目录范围等。分两个场景普通场景和agent场景
  3. 如为普通模式,scopedDirectories 接受用户添加的路径
    • 上下文提取:codebaseTool 在执行时,会将这些路径传递给 WorkspaceChunkSearchService,进行代码块(chunk)提取和检索。
    • Chunk 生成:WorkspaceChunkSearchService 会将指定文件/文件夹内容分割成 chunk(代码片段),并根据查询进行相关性排序。
    • Prompt 构建:最终选中的 chunk 会被拼接到 prompt 中,作为 LLM 的输入上下文。
  4. 若为 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_COUNTMAX_TOOL_CHUNK_TOKEN_COUNT 等常量 WorkspaceChunkSearchService.searchFileChunks
2、Prompt 渲染与压缩

agentIntent/AgentPrompt 支持 summarization,当 budget 超限时自动触发摘要/丢弃, 在 prompt 构建阶段自动检测并调用摘要/丢弃逻辑

分步渲染

  • promptRenderer 先渲染高优先级内容(如用户 query、摘要、最相关 chunk)

  • 后续按优先级逐步补充低优先级内容

分布压缩

  • 每渲染一部分内容,实时统计 token 数,若超出 tokenBudget,则动态丢弃或摘要低优先级内容。先摘要低分 chunk,再摘要高分 chunk。采用 LLM 或本地算法对 chunk 进行摘要(如提取主要函数、注释、接口等)。

  • 用摘要内容替换原始 chunk,重新统计 token,支持多轮摘要, 直到满足预算。

代码

  • AgentIntentAgentPrompt、promptRenderer、renderPromptElementJSON 支持分步渲染
  • prompt-tsxPromptSizingPromptElement 动态 token 预算管理相关逻辑
Chunk 检索与裁剪流程
[用户输入/选择文件夹]
        |
        v
[文件遍历] --(分割)--> [Chunk 列表] --(embedding/关键词)--> [相关性排序]
        |                                            |
        +--------------------(token预算裁剪)----------+
                                                     v
                                         [选中 chunk 作为上下文]
Prompt 渲染与压缩流程
[选中 chunk/摘要/用户query]
        |
        v
[PromptRenderer 分步渲染]
        |
        v
[实时统计 token]
        |
        +--(超预算?)--是--> [丢弃/摘要低优先级内容]
        |                  |
        |                  v
        +-------否-------->[输出完整 prompt]
        
   

参考

juejin.cn/post/752323…