Gemini CLI 深度源码解析:从零到一理解 AI 命令行代理的设计与实现
本文基于 Gemini CLI v0.21.0 源码进行深度分析,带你从架构设计、核心原理到实现细节,全方位理解这个 Google 开源的 AI 命令行代理工具。
目录
- [什么是 Gemini CLI?](#什么是 Gemini CLI? "#1-%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%BF%B0%E4%BB%80%E4%B9%88%E6%98%AF-gemini-cli")
- 整体架构设计
- 核心模块详解
- [记忆系统:让 AI "记住" 你的偏好](#记忆系统:让 AI "记住" 你的偏好 "#4-%E8%AE%B0%E5%BF%86%E7%B3%BB%E7%BB%9F%E8%AE%A9-ai-%E8%AE%B0%E4%BD%8F-%E4%BD%A0%E7%9A%84%E5%81%8F%E5%A5%BD")
- [上下文工程:如何管理有限的 Token 窗口](#上下文工程:如何管理有限的 Token 窗口 "#5-%E4%B8%8A%E4%B8%8B%E6%96%87%E5%B7%A5%E7%A8%8B%E5%A6%82%E4%BD%95%E7%AE%A1%E7%90%86%E6%9C%89%E9%99%90%E7%9A%84-token-%E7%AA%97%E5%8F%A3")
- [工具系统:AI 如何执行实际操作](#工具系统:AI 如何执行实际操作 "#6-%E5%B7%A5%E5%85%B7%E7%B3%BB%E7%BB%9Fai-%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C%E5%AE%9E%E9%99%85%E6%93%8D%E4%BD%9C")
- [MCP 协议:标准化的 AI 工具扩展](#MCP 协议:标准化的 AI 工具扩展 "#7-mcp-%E5%8D%8F%E8%AE%AE%E6%A0%87%E5%87%86%E5%8C%96%E7%9A%84-ai-%E5%B7%A5%E5%85%B7%E6%89%A9%E5%B1%95")
- 通信协议与流式响应
- [Hook 系统:可扩展的生命周期钩子](#Hook 系统:可扩展的生命周期钩子 "#9-hook-%E7%B3%BB%E7%BB%9F%E5%8F%AF%E6%89%A9%E5%B1%95%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90")
- [UI 层:终端中的 React 应用](#UI 层:终端中的 React 应用 "#10-ui-%E5%B1%82%E7%BB%88%E7%AB%AF%E4%B8%AD%E7%9A%84-react-%E5%BA%94%E7%94%A8")
- 使用指南
- 总结与思考
1. 什么是 Gemini CLI?
1.1 简单来说
Gemini CLI 是 Google 开源的一个 AI 命令行代理(AI Agent)。你可以把它想象成一个住在你终端里的智能助手,它能:
- 理解你的自然语言指令:比如"帮我修复这个 bug"、"给这个函数加上单元测试"
- 自动执行操作:读写文件、运行命令、搜索代码
- 记住你的偏好:你喜欢用 TypeScript、偏好 4 空格缩进等
- 持续对话:可以恢复之前的会话继续工作
1.2 技术栈一览
| 类别 | 技术 | 说明 |
|---|---|---|
| 语言 | TypeScript 5.3+ | 核心开发语言 |
| 运行时 | Node.js 20+ | 最低版本要求 |
| UI 框架 | React 19 + Ink | 终端中的 React |
| 包管理 | npm workspaces | Monorepo 结构 |
| 构建工具 | esbuild | 快速打包 |
| 测试框架 | Vitest | 单元测试 |
| AI SDK | @google/genai | Gemini API 客户端 |
| 扩展协议 | MCP SDK v1.23 | 工具扩展支持 |
1.3 项目结构
bash
gemini-cli/
├── packages/
│ ├── cli/ # 前端 UI 层 - 用户交互界面
│ ├── core/ # 核心业务逻辑 - AI 调用、工具执行
│ ├── a2a-server/ # Agent-to-Agent 服务器
│ └── vscode-ide-companion/ # VS Code 插件
├── bundle/ # 打包后的可执行文件
├── scripts/ # 构建和自动化脚本
└── integration-tests/ # 集成测试
2. 整体架构设计
2.1 分层架构图
gemini.tsx] end subgraph "UI 层 - packages/cli" B --> C[AppContainer
React 应用容器] C --> D[Composer
输入组件] C --> E[MessageDisplay
消息展示] C --> F[ToolCallDisplay
工具调用展示] end subgraph "服务层 - packages/core" D --> G[GeminiClient
对话管理器] G --> H[GeminiChat
API 交互] G --> I[ToolScheduler
工具调度器] G --> J[ContextManager
上下文管理] end subgraph "工具层" I --> K[内置工具
read/write/edit/shell] I --> L[MCP 工具
外部扩展] end subgraph "外部服务" H --> M[Gemini API
REST + SSE] L --> N[MCP Server
Stdio/SSE] end style A fill:#e1f5fe style M fill:#fff3e0 style N fill:#fff3e0
2.2 核心设计原则
项目采用了几个关键的设计原则:
1. 前后端分离
packages/cli:负责用户界面、输入处理、显示渲染packages/core:负责业务逻辑、API 调用、工具执行
2. 流式处理
- 使用 JavaScript 的
AsyncGenerator实现流式响应 - 用户可以实时看到 AI 的输出,而不是等待完整响应
3. 插件化工具系统
- 内置工具通过统一的
Tool接口注册 - 外部工具通过 MCP 协议动态发现和调用
4. 分层记忆
- 全局记忆:用户级别的偏好设置
- 项目记忆:项目级别的约定
- 会话记忆:当前对话的上下文
3. 核心模块详解
3.1 启动流程
让我们跟随代码,看看当你在终端输入 gemini 时发生了什么:
关键代码位置:
- 入口文件:
packages/cli/src/gemini.tsx - 配置加载:
packages/cli/src/config/config.ts - 应用容器:
packages/cli/src/ui/AppContainer.tsx
3.2 GeminiClient - 对话管理的核心
GeminiClient 是整个系统的"大脑",它协调了对话的方方面面:
typescript
// packages/core/src/core/client.ts
export class GeminiClient {
private chat?: GeminiChat; // 实际的 API 交互
private sessionTurnCount = 0; // 会话轮次计数
private loopDetector: LoopDetectionService; // 循环检测
private compressionService: ChatCompressionService; // 上下文压缩
// 最大轮次限制,防止无限循环
private static MAX_TURNS = 100;
}
主要职责:
| 职责 | 说明 |
|---|---|
| 对话初始化 | 创建 GeminiChat 实例,设置系统提示 |
| 消息发送 | 处理用户输入,调用 API |
| 工具调用协调 | 当 AI 请求工具时,协调执行 |
| 上下文压缩 | 当 token 超限时,压缩历史 |
| 循环检测 | 防止 AI 陷入无限工具调用循环 |
| 会话恢复 | 支持从之前的会话继续 |
3.3 Turn - 一次对话轮次
每次用户发送消息到收到完整回复,被称为一个 "Turn":
事件类型定义:
typescript
// packages/core/src/core/turn.ts
export enum GeminiEventType {
Content = 'content', // 文本内容
ToolCallRequest = 'tool_call_request', // 工具调用请求
ToolCallResponse = 'tool_call_response', // 工具调用响应
Thought = 'thought', // AI 的思考过程
Finished = 'finished', // 完成
Error = 'error', // 错误
ChatCompressed = 'chat_compressed', // 上下文被压缩
LoopDetected = 'loop_detected', // 检测到循环
// ...
}
4. 记忆系统:让 AI "记住" 你的偏好
4.1 记忆的层次结构
Gemini CLI 实现了一个三层记忆系统,让 AI 能够记住从全局偏好到项目特定约定的各种信息:
~/.gemini/GEMINI.md"] --> B["项目记忆
project/GEMINI.md"] B --> C["子目录记忆
project/src/GEMINI.md"] end subgraph "记忆内容示例" D["全局偏好
- 喜欢 TypeScript
- 偏好 4 空格缩进"] E["项目约定
- 使用 ESLint
- 测试用 Vitest"] F["模块特定
- 组件用函数式
- 状态用 hooks"] end A --- D B --- E C --- F style A fill:#e8f5e9 style B fill:#e3f2fd style C fill:#fce4ec
4.2 记忆文件格式
记忆存储在 Markdown 文件中,便于人类阅读和编辑:
markdown
# GEMINI.md - 项目记忆文件
## 项目概述
这是一个 React + TypeScript 前端项目。
## 编码约定
- 使用函数式组件,不用类组件
- 状态管理使用 React hooks
- 样式使用 Tailwind CSS
## 构建和测试
- 构建命令:`npm run build`
- 测试命令:`npm test`
- Lint 命令:`npm run lint`
## Gemini Added Memories
- 用户偏好使用 async/await 而不是 .then()
- 日志使用 console.log 而不是 alert
4.3 记忆发现机制
核心代码解析:
typescript
// packages/core/src/utils/memoryDiscovery.ts
async function getGeminiMdFilePathsInternal(
currentWorkingDirectory: string,
includeDirectoriesToReadGemini: readonly string[],
userHomePath: string,
// ...
): Promise<string[]> {
// 1. 查找全局记忆文件
const globalMemoryPath = path.join(homedir(), '.gemini', 'GEMINI.md');
// 2. 从当前目录向上查找项目根目录
const projectRoot = await findProjectRoot(currentWorkingDirectory);
// 3. 收集路径上的所有 GEMINI.md 文件
// 顺序:全局 -> 项目根 -> 子目录(越近优先级越高)
}
4.4 保存记忆
当你让 AI "记住" 某些事情时,会调用 MemoryTool:
typescript
// packages/core/src/tools/memoryTool.ts
export class MemoryTool extends BaseDeclarativeTool {
// 保存事实到记忆文件
async performAddMemoryEntry(fact: string): Promise<void> {
// 1. 读取当前 GEMINI.md 内容
const content = await fs.readFile(memoryPath, 'utf-8');
// 2. 找到 "## Gemini Added Memories" 部分
// 3. 添加新的记忆项
const newContent = addMemoryEntry(content, fact);
// 4. 写回文件
await fs.writeFile(memoryPath, newContent);
}
}
5. 上下文工程:如何管理有限的 Token 窗口
5.1 Token 的概念
在与 AI 对话时,每条消息都会消耗 "Token"。Token 大致可以理解为:
- 英文:大约 4 个字符 = 1 个 Token
- 中文:大约 1-2 个字符 = 1 个 Token
每个模型都有 Token 限制:
typescript
// packages/core/src/core/tokenLimits.ts
export function tokenLimit(model: Model): TokenCount {
switch (model) {
case 'gemini-1.5-pro':
return 2_097_152; // 200 万 Token
case 'gemini-2.5-pro':
case 'gemini-2.5-flash':
return 1_048_576; // 100 万 Token
default:
return 1_048_576;
}
}
5.2 上下文组成
5.3 上下文管理策略
系统提示] --> E[总上下文] B[对话历史
Messages] --> E C[用户记忆
GEMINI.md] --> E D[环境上下文
日期/OS/目录] --> E end E --> F{Token 数量} F -->|小于50%限制| G[正常继续] F -->|大于50%限制| H[触发压缩] H --> I[保留最近 30%] H --> J[压缩旧历史为状态快照] I --> K[新的对话历史] J --> K
5.4 对话压缩的实现
当上下文过长时,系统会自动压缩旧的对话历史:
typescript
// packages/core/src/services/chatCompressionService.ts
export const DEFAULT_COMPRESSION_TOKEN_THRESHOLD = 0.5; // 50% 时触发
export const COMPRESSION_PRESERVE_THRESHOLD = 0.3; // 保留最近 30%
export class ChatCompressionService {
async compress(chat: GeminiChat, ...): Promise<{
newHistory: Content[] | null;
info: ChatCompressionInfo;
}> {
// 1. 检查是否需要压缩
if (tokenCount < 0.5 * tokenLimit(model)) {
return { newHistory: null, compressionStatus: 'NOOP' };
}
// 2. 确定分割点(保留最近 30%)
const splitPoint = findCompressSplitPoint(
history,
1 - 0.3 // 压缩前 70%
);
// 3. 使用 AI 生成状态快照
const summary = await this.generateStateSnapshot(historyToCompress);
// 4. 组合新历史
return {
newHistory: [
{ role: 'user', parts: [{ text: summary }] },
{ role: 'model', parts: [{ text: 'Got it!' }] },
...historyToKeep // 保留的最近历史
],
compressionStatus: 'COMPRESSED'
};
}
}
5.5 状态快照格式
压缩后的状态快照包含关键信息:
xml
<state_snapshot>
<overall_goal>
实现用户认证功能
</overall_goal>
<key_knowledge>
- Build Command: `npm run build`
- Testing: Tests run with `npm test`
- 使用 JWT 进行认证
</key_knowledge>
<file_system_state>
- CWD: `/home/user/project/src`
- READ: `package.json`, `auth/login.ts`
- MODIFIED: `auth/jwt.ts`
- CREATED: `auth/__tests__/jwt.test.ts`
</file_system_state>
<recent_actions>
- 创建了 JWT 验证函数
- 运行测试,3 个通过,1 个失败
- 修复了 token 过期验证的 bug
</recent_actions>
<current_plan>
1. [DONE] 实现 JWT 生成
2. [DONE] 实现 JWT 验证
3. [IN PROGRESS] 修复测试失败
4. [TODO] 集成到登录流程
</current_plan>
</state_snapshot>
6. 工具系统:AI 如何执行实际操作
6.1 工具的概念
工具(Tool)是 AI 与外部世界交互的方式。当 AI 需要读文件、执行命令时,它会"调用工具":
6.2 内置工具列表
| 工具名 | 功能 | 类型 | 需确认 |
|---|---|---|---|
read_file |
读取文件内容(支持文本、图片、PDF) | Read | 否 |
write_file |
创建或覆写文件 | Write | 是 |
edit |
编辑文件的特定部分 | Write | 是 |
shell |
执行 Shell 命令 | Execute | 是 |
grep |
在文件中搜索文本 | Read | 否 |
glob |
匹配文件路径模式 | Read | 否 |
ls |
列出目录内容 | Read | 否 |
web_fetch |
获取网页内容 | Read | 否 |
web_search |
执行网络搜索 | Read | 否 |
memory |
保存信息到记忆 | Write | 否 |
6.3 工具的生命周期
6.4 工具基类设计
所有工具都继承自 BaseDeclarativeTool:
typescript
// packages/core/src/tools/tools.ts
export abstract class BaseDeclarativeTool<TParams, TResult> {
constructor(
readonly name: string, // 工具名称
readonly displayName: string, // 显示名称
readonly description: string, // 描述(给 AI 看)
readonly kind: 'Read' | 'Write' | 'Execute', // 类型
readonly schema: FunctionDeclaration, // 参数 schema
readonly requiresConfirmation: boolean // 是否需要确认
) {}
// 验证参数
protected abstract validateToolParamValues(params: TParams): string | null;
// 创建执行实例
protected abstract createInvocation(params: TParams): ToolInvocation;
}
// 工具调用实例接口
export interface ToolInvocation<TParams, TResult> {
params: TParams;
getDescription(): string;
toolLocations(): ToolLocation[];
shouldConfirmExecute(signal: AbortSignal): Promise<ToolCallConfirmationDetails | false>;
execute(signal: AbortSignal, updateOutput?: Function): Promise<TResult>;
}
6.5 工具调用示例
以 read_file 为例,看看一次完整的工具调用:
typescript
// 1. AI 请求调用工具
{
name: "read_file",
args: {
file_path: "/path/to/file.ts",
should_read_entire_file: true
}
}
// 2. 验证参数
// - 检查路径是否存在
// - 检查是否有权限读取
// 3. 执行读取
const content = await fs.readFile(filePath, 'utf-8');
// 4. 返回结果
{
llmContent: [{ text: content }], // 给 AI 看的内容
returnDisplay: {
type: 'markdown',
content: '```typescript\n' + content + '\n```'
}
}
7. MCP 协议:标准化的 AI 工具扩展
7.1 什么是 MCP?
MCP(Model Context Protocol)是一个开放协议,用于标准化 AI 模型与外部工具之间的通信。就像 USB 让各种设备能够连接电脑一样,MCP 让各种工具能够接入 AI。
SQL 查询] D[API 工具
REST 调用] E[自定义工具
任何功能] end A <-->|Stdio| C A <-->|SSE| D A <-->|HTTP| E style A fill:#e3f2fd style C fill:#fff3e0 style D fill:#fff3e0 style E fill:#fff3e0
7.2 MCP 支持的传输方式
本地进程] B[SSE
Server-Sent Events] C[HTTP
Streamable] end subgraph "适用场景" D[本地工具
高性能] E[远程服务
实时推送] F[Web API
通用兼容] end A --> D B --> E C --> F
typescript
// packages/core/src/tools/mcp-client.ts
// 1. Stdio 传输 - 通过标准输入/输出与本地进程通信
const transport = new StdioClientTransport({
command: 'node',
args: ['./my-mcp-server.js'],
});
// 2. SSE 传输 - 通过 Server-Sent Events
const transport = new SSEClientTransport(
new URL('https://mcp-server.example.com')
);
// 3. HTTP Streamable 传输
const transport = new StreamableHTTPClientTransport(
new URL('https://api.example.com/mcp')
);
7.3 MCP 服务器配置
在 ~/.gemini/settings.json 中配置:
json
{
"mcpServers": {
"my-database": {
"command": "npx",
"args": ["@my-org/db-mcp-server"],
"env": {
"DATABASE_URL": "postgres://..."
}
},
"github": {
"url": "https://github-mcp.example.com",
"auth": {
"type": "oauth"
}
}
}
}
7.4 MCP 客户端实现
typescript
// packages/core/src/tools/mcp-client.ts
export enum MCPServerStatus {
DISCONNECTED = 'disconnected',
CONNECTING = 'connecting',
CONNECTED = 'connected',
DISCONNECTING = 'disconnecting'
}
export class McpClient {
private client: Client | undefined;
private status: MCPServerStatus = MCPServerStatus.DISCONNECTED;
async connect(): Promise<void> {
this.updateStatus(MCPServerStatus.CONNECTING);
// 创建连接
this.client = await connectToMcpServer(
this.serverName,
this.serverConfig,
this.debugMode
);
// 监听工具更新(动态工具发现)
const capabilities = this.client.getServerCapabilities();
if (capabilities?.tools?.listChanged) {
this.client.setNotificationHandler(
ToolListChangedNotificationSchema,
async () => {
await this.refreshTools(); // 动态更新工具列表
}
);
}
this.updateStatus(MCPServerStatus.CONNECTED);
}
async discoverTools(): Promise<DiscoveredMCPTool[]> {
const response = await this.client.listTools({});
return response.tools.map(tool => new DiscoveredMCPTool(tool));
}
}
8. 通信协议与流式响应
8.1 与 Gemini API 的通信
Gemini CLI 使用 REST + SSE 的混合通信方式:
(包含历史、工具、配置) Note over API: 开始生成响应 loop 流式响应 (SSE) API-->>CLI: data: {"text": "正在"} API-->>CLI: data: {"text": "思考"} API-->>CLI: data: {"text": "..."} end alt 需要调用工具 API-->>CLI: data: {"functionCall": {...}} CLI->>CLI: 执行工具 CLI->>API: POST(包含工具结果) end API-->>CLI: data: {"finishReason": "STOP"}
8.2 SSE 解析实现
typescript
// packages/core/src/code_assist/server.ts
async *requestStreamingPost<T>(
method: string,
req: object,
): Promise<AsyncGenerator<T>> {
const res = await this.client.request({
url: this.getMethodUrl(method),
method: 'POST',
params: { alt: 'sse' }, // 请求 SSE 格式
responseType: 'stream',
body: JSON.stringify(req),
});
// 解析 SSE 数据流
const rl = readline.createInterface({
input: res.data as NodeJS.ReadableStream,
});
let bufferedLines: string[] = [];
for await (const line of rl) {
if (line.startsWith('data: ')) {
bufferedLines.push(line.slice(6).trim());
} else if (line === '') {
// 空行表示一个完整的事件
if (bufferedLines.length > 0) {
yield JSON.parse(bufferedLines.join('\n')) as T;
bufferedLines = [];
}
}
}
}
8.3 请求格式
发送给 Gemini API 的请求结构:
typescript
interface GenerateContentRequest {
model: string; // 模型名称
contents: Content[]; // 对话历史
systemInstruction?: Content; // 系统提示
tools?: Tool[]; // 可用工具
toolConfig?: {
functionCallingConfig: {
mode: 'AUTO' | 'ANY' | 'NONE' // 工具调用模式
}
};
generationConfig?: {
temperature?: number; // 温度(创意度)
topP?: number; // Top-P 采样
topK?: number; // Top-K 采样
maxOutputTokens?: number; // 最大输出 Token
thinkingConfig?: {
thinkingBudget: number; // 思考 Token 预算
}
};
}
9. Hook 系统:可扩展的生命周期钩子
9.1 Hook 的概念
Hook 允许你在 AI 执行的关键节点插入自定义逻辑,比如:
- 在工具执行前审批
- 在模型调用前/后记录日志
- 在会话开始/结束时执行清理
9.2 可用的 Hook 事件
typescript
// packages/core/src/hooks/types.ts
export enum HookEventName {
SessionStart = 'SessionStart', // 会话开始
SessionEnd = 'SessionEnd', // 会话结束
BeforeAgent = 'BeforeAgent', // 代理执行前
AfterAgent = 'AfterAgent', // 代理执行后
BeforeTool = 'BeforeTool', // 工具执行前
AfterTool = 'AfterTool', // 工具执行后
BeforeModel = 'BeforeModel', // 模型调用前
AfterModel = 'AfterModel', // 模型调用后
PreCompress = 'PreCompress', // 上下文压缩前
Notification = 'Notification', // 通知事件
BeforeToolSelection = 'BeforeToolSelection' // 工具选择前
}
9.3 Hook 执行流程
9.4 配置 Hook
在 ~/.gemini/settings.json 中配置:
json
{
"hooks": {
"BeforeTool": [
{
"matcher": "shell",
"command": "/path/to/approve-shell.sh",
"timeout": 5000
}
],
"SessionStart": [
{
"command": "echo 'Session started' >> ~/gemini.log"
}
]
}
}
9.5 Hook 输入/输出格式
typescript
// Hook 接收的输入(通过 stdin)
interface HookInput {
session_id: string; // 会话 ID
transcript_path: string; // 对话记录路径
cwd: string; // 当前工作目录
hook_event_name: string; // 事件名称
timestamp: string; // 时间戳
// ... 事件特定的数据
}
// Hook 返回的输出(通过 stdout)
interface HookOutput {
continue?: boolean; // 是否继续执行
decision?: 'allow' | 'deny' | 'ask' | 'block'; // 决定
reason?: string; // 原因
systemMessage?: string; // 要添加的系统消息
suppressOutput?: boolean; // 是否抑制输出
}
10. UI 层:终端中的 React 应用
10.1 Ink - 终端中的 React
Gemini CLI 使用 Ink 库在终端中渲染 React 组件。这意味着 UI 代码和普通的 React 应用非常相似:
tsx
// packages/cli/src/ui/components/Composer.tsx
export function Composer(): JSX.Element {
const [input, setInput] = useState('');
const { sendMessage } = useUIActions();
const handleSubmit = useCallback(() => {
sendMessage(input);
setInput('');
}, [input, sendMessage]);
return (
<Box flexDirection="column">
<Text color="cyan">› </Text>
<TextInput
value={input}
onChange={setInput}
onSubmit={handleSubmit}
/>
</Box>
);
}
10.2 UI 组件结构
标题栏] E --> G[MessageList
消息列表] E --> H[Composer
输入框] E --> I[Footer
状态栏] end subgraph "消息类型" G --> J[UserMessage
用户消息] G --> K[GeminiMessage
AI 回复] G --> L[ToolCallDisplay
工具调用] G --> M[ThoughtDisplay
思考过程] end
10.3 关键 Context
| Context | 作用 |
|---|---|
SettingsContext |
应用设置和配置 |
SessionContext |
当前会话状态 |
UIActionsContext |
UI 操作(发送消息、执行工具等) |
VimModeContext |
Vim 模式支持 |
MouseContext |
鼠标交互 |
StreamingContext |
流式响应状态 |
10.4 主题系统
Gemini CLI 支持 24+ 种终端主题:
typescript
// packages/cli/src/ui/themes/
export interface Theme {
name: string;
colors: {
primary: string;
secondary: string;
background: string;
text: string;
error: string;
warning: string;
success: string;
// ...
};
}
11. 使用指南
11.1 安装
bash
# 使用 npm
npm install -g @google/gemini-cli
# 或者直接运行
npx @google/gemini-cli
11.2 首次配置
bash
# 首次运行会引导你完成认证
gemini
# 支持的认证方式:
# 1. Google 账号 OAuth(推荐)
# 2. API Key
11.3 基本使用
bash
# 交互模式
gemini
# 单次查询
gemini "这个函数是做什么的?"
# 指定模型
gemini --model gemini-2.5-pro "解释这段代码"
# 恢复上次会话
gemini --resume latest
11.4 常用命令
在交互模式中,可以使用这些命令:
| 命令 | 功能 |
|---|---|
/help |
显示帮助 |
/clear |
清空当前会话 |
/memory |
编辑记忆文件 |
/model |
切换模型 |
/settings |
打开设置 |
/quit 或 Ctrl+C |
退出 |
11.5 记忆文件配置
创建项目记忆文件 GEMINI.md:
markdown
# 项目说明
这是一个 Next.js 14 项目,使用 App Router。
## 技术栈
- Next.js 14
- TypeScript
- Tailwind CSS
- Prisma (PostgreSQL)
## 开发规范
- 组件放在 `src/components/`
- API 路由放在 `src/app/api/`
- 使用 Zod 进行数据验证
## 常用命令
- `npm run dev` - 启动开发服务器
- `npm run build` - 构建生产版本
- `npm run test` - 运行测试
12. 总结与思考
12.1 架构亮点
| 亮点 | 说明 |
|---|---|
| 清晰的分层设计 | UI 层和业务逻辑层完全分离,便于测试和维护 |
| 优雅的流式处理 | 使用 AsyncGenerator 实现流式响应,体验流畅 |
| 强大的扩展性 | MCP 协议支持任意工具扩展,Hook 系统允许自定义逻辑 |
| 智能的上下文管理 | 三层记忆系统 + 自动压缩,充分利用 Token 窗口 |
| 完善的安全机制 | 敏感操作需确认,策略引擎控制工具权限 |
12.2 可以借鉴的设计模式
| 模式 | 在项目中的应用 |
|---|---|
| 工厂模式 | 工具的创建和注册 |
| 策略模式 | 模型路由、压缩策略 |
| 观察者模式 | 事件系统、Hook 触发 |
| 装饰器模式 | 日志包装、录制包装 |
| 适配器模式 | MCP 工具适配 |
12.3 对 AI 应用开发的启示
附录:核心文件速查表
| 功能 | 文件路径 |
|---|---|
| 应用入口 | packages/cli/src/gemini.tsx |
| 应用容器 | packages/cli/src/ui/AppContainer.tsx |
| 对话客户端 | packages/core/src/core/client.ts |
| API 交互 | packages/core/src/core/geminiChat.ts |
| 工具调度 | packages/core/src/core/coreToolScheduler.ts |
| 工具基类 | packages/core/src/tools/tools.ts |
| 工具注册 | packages/core/src/tools/tool-registry.ts |
| 记忆发现 | packages/core/src/utils/memoryDiscovery.ts |
| 记忆工具 | packages/core/src/tools/memoryTool.ts |
| 上下文压缩 | packages/core/src/services/chatCompressionService.ts |
| System Prompt | packages/core/src/core/prompts.ts |
| MCP 客户端 | packages/core/src/tools/mcp-client.ts |
| Hook 类型 | packages/core/src/hooks/types.ts |
| Token 限制 | packages/core/src/core/tokenLimits.ts |
- 本文基于 Gemini CLI v0.21.0 源码分析,作者通过深入阅读源码编写而成。如有任何疑问或建议,欢迎交流讨论!
- 作者【前端领秀】一个喜欢探索前端领域AI赋能的开发者,喜欢我的可以关注我,私信我邀请进入技术群,我会时刻分享最新前沿AI技术;
