Skip to content

Core 包解析

概述

packages/core 是 gemini-cli 的核心,包含 Agent 的所有逻辑。

目录结构

packages/core/src/
├── core/           # 核心类
├── tools/          # 工具实现
├── services/       # 服务层
├── agents/         # Agent 系统
├── mcp/            # MCP 集成
├── hooks/          # 扩展钩子
├── policy/         # 策略引擎
├── telemetry/      # 遥测
└── utils/          # 工具函数

核心类

GeminiClient

Agent 的主控制器,负责运行 Agent 循环。

文件core/client.ts

关键职责:

  • 管理对话状态
  • 执行 Agent 循环
  • 调度工具执行
  • 处理用户确认
typescript
// 简化的 GeminiClient 结构
class GeminiClient {
  private chat: GeminiChat
  private tools: ServerTool[]
  private conversation: Message[]

  // 运行 Agent 循环
  async run(userMessage: string): AsyncGenerator<GeminiEvent> {
    this.conversation.push({ role: 'user', content: userMessage })

    while (true) {
      const response = await this.chat.send(this.conversation)

      for (const event of this.processResponse(response)) {
        yield event

        if (event.type === 'ToolCallRequest') {
          const result = await this.executeToolCall(event)
          this.conversation.push(/* result */)
        }
      }

      if (/* 完成 */) break
    }
  }
}

GeminiChat

封装 Gemini API 调用。

文件core/geminiChat.ts

关键职责:

  • 管理 API 连接
  • 处理流式响应
  • Token 计数
typescript
// 简化的 GeminiChat 结构
class GeminiChat {
  private model: GenerativeModel
  private chat: Chat

  async send(contents: Content[]): AsyncGenerator<Chunk> {
    const result = await this.chat.sendMessageStream(contents)

    for await (const chunk of result.stream) {
      yield this.processChunk(chunk)
    }
  }
}

Turn 和事件系统

定义 Agent 运行中的各种事件。

文件core/turn.ts

typescript
// 事件类型
type GeminiEventType =
  | 'Content'          // 文本输出
  | 'ToolCallRequest'  // 工具调用请求
  | 'ToolCallResponse' // 工具执行结果
  | 'Thought'          // 思考过程
  | 'Error'            // 错误
  | 'ChatCompressed'   // 对话压缩
  | 'LoopDetected'     // 循环检测

// 事件基础结构
interface GeminiEvent {
  type: GeminiEventType
  timestamp: number
  data: unknown
}

工具系统

工具接口

文件tools/tool.ts

typescript
interface ServerTool {
  name: string
  schema: FunctionDeclaration
  execute(params: unknown, signal?: AbortSignal): Promise<ToolResult>
  shouldConfirmExecute?(params: unknown): Promise<ConfirmDetails | false>
}

工具实现

read-file.ts 为例:

typescript
// tools/read-file.ts (简化)
export const readFileTool: ServerTool = {
  name: 'read_file',

  schema: {
    name: 'read_file',
    description: '读取文件内容',
    parameters: {
      type: 'object',
      properties: {
        file_path: { type: 'string' },
        offset: { type: 'number' },
        limit: { type: 'number' }
      },
      required: ['file_path']
    }
  },

  async execute({ file_path, offset, limit }) {
    const content = await fs.readFile(file_path, 'utf-8')
    // 处理分页、截断等
    return { content }
  }
}

工具注册

所有工具在启动时注册:

typescript
// 工具列表
const tools: ServerTool[] = [
  readFileTool,
  writeFileTool,
  editFileTool,
  shellTool,
  grepTool,
  globTool,
  webFetchTool,
  // ...
]

服务层

LoopDetectionService

检测 Agent 是否陷入循环。

文件services/loopDetection.ts

typescript
class LoopDetectionService {
  private recentActions: Action[] = []

  onAction(action: Action) {
    this.recentActions.push(action)
    // 保持滑动窗口
  }

  detect(): LoopResult {
    // 检查重复模式
    // 检查最大轮次
    // 检查连续错误
  }
}

ChatCompressionService

当对话过长时压缩历史。

文件services/chatCompression.ts

typescript
class ChatCompressionService {
  async compress(messages: Message[]): Promise<Message[]> {
    const tokenCount = await this.countTokens(messages)

    if (tokenCount < threshold) {
      return messages
    }

    // 找到分割点
    // 总结早期消息
    // 返回压缩后的消息
  }
}

ChatRecordingService

保存和恢复会话。

文件services/chatRecording.ts

typescript
class ChatRecordingService {
  saveCheckpoint(conversation: Conversation) {
    // 保存到文件
  }

  loadCheckpoint(id: string): Conversation {
    // 从文件恢复
  }
}

代码流程

用户输入 "读取 package.json" 的完整流程:

1. CLI 接收输入

2. GeminiClient.run("读取 package.json")

3. 添加到 conversation

4. GeminiChat.send(conversation)

5. Gemini API 返回 ToolCallRequest(read_file)

6. GeminiClient 找到 readFileTool

7. readFileTool.execute({ file_path: "package.json" })

8. 返回文件内容

9. 添加结果到 conversation

10. GeminiChat.send(conversation)

11. Gemini API 返回文本响应

12. 输出给用户

关键设计模式

1. 事件驱动

使用 Generator 函数产生事件流:

typescript
async *run(): AsyncGenerator<GeminiEvent> {
  // 产生事件而不是直接处理
  yield { type: 'Content', data: '...' }
  yield { type: 'ToolCallRequest', data: {...} }
}

2. 依赖注入

服务通过构造函数注入:

typescript
class GeminiClient {
  constructor(
    private chat: GeminiChat,
    private loopDetector: LoopDetectionService,
    private compression: ChatCompressionService
  ) {}
}

3. 接口抽象

工具通过统一接口定义:

typescript
// 所有工具实现相同接口
interface ServerTool {
  name: string
  execute(params: unknown): Promise<ToolResult>
}

学习建议

  1. 从类型开始:先读 turn.ts 理解数据结构
  2. 看简单工具read-file.ts 是最简单的工具
  3. 理解主循环client.ts 的 run 方法是核心
  4. 调试运行:用 console.log 跟踪执行流程

小结

  • Core 包实现了完整的 Agent 逻辑
  • GeminiClient 是主控制器
  • 工具系统设计简洁统一
  • 服务层处理各种辅助功能

下一步

源码走读完成,接下来动手实践:构建迷你 Agent →

通过实际源码学习 AI Agent 开发