Please enable Javascript to view the contents

用 gemini-CLI 分析 gemini-CLI 自身源码

 ·  ☕ 8 分钟

logo

概述

本文将介绍如何使用 gemini-cli 这个命令行工具来分析其自身的源码库。 我们将通过一系列交互式的命令,探索 gemini-cli 的设计和实现。这种方法不仅展示了 AI 工具的功能,也为开发者提供了一种新的学习和探索方式。

如果你不知道 gemini-cli 是什么,这里简单介绍一下:
gemini-cli 是一款开源的命令行界面(Command-Line Interface, CLI)工具,它允许开发者和用户直接在终端(Terminal)中与 Google 的 Gemini 模型进行交互。你可以把它想象成一个在命令行里的智能 A I助手。

缘起

学习一个新领域时,光学习理论与概念往往不够深入,也容易让人感到枯燥。反而,通过分析一个实际项目的源码,可以更直观地理解其设计和实现细节。学习 Kubernetes 如是,学习 AI 应用也如是。分析一个 AI 工具的实现源码,既有趣又富有挑战性。

评价一个工具是否已经成熟,有时可以通过看它是否能够 自举(bootstrapping)。自举是指一个工具能够应用自身的功能来处理自身的事情。
相信有 OpenJDK 编译构建经验的同学都知道,要编译 OpenJDK 需要先安装一个 JDK(当然,可以是相对低版本的),然后用安装的 JDK 再去构建出目标 JDK。在计算机术语中,这个过程称为自举(bootstrapping)。而在 AI 领域,我们也可以用 AI 工具来分析和理解 AI 工具自身的源码。这种方法可以被视为一种“以子之矛,攻子之盾”的自举过程。

所以,用 Gemini-CLI 分析 Gemini-CLI 自身源码,我觉得是件相当有趣也相当实用的事情。

分析

每一次浏览 gemini-cli 的源码。我们可以用 AI 分析工具,也可以自己直接看源码。但我的建议是,先看它的 High Level 设计文档。AI 世代,人写的东西,特别是 high level 的,弥足珍贵: Gemini CLI Architecture Overview

1
2
3
4
5
6
git clone https://github.com/google-gemini/gemini-cli.git

cd gemini-cli.git

# 启动 gemini-cli
gemini-cli

Prompts

分析 LLM 应用源码,最直观也是最容易的切入点,当然是从 prompts 开始。因为 prompts 是 LLM 应用的核心,直接决定了模型的行为和输出。

Software Engineering Tasks

提出问题:

╭──────────────────────────────────────────────────────────────────────────────────────╮
│  > 解释 @packages/core/src/core/prompts.ts 中的提示语(prompt) 并用其中一个例子说明.  │
╰──────────────────────────────────────────────────────────────────────────────────────╯

分析结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
✦ packages/core/src/core/prompts.ts 文件主要包含两种类型的提示语(prompt):

   1. 核心系统提示语 (`getCoreSystemPrompt`): 这是定义代理(agent)行为、职责和操作规范的主要提示语。它详细说明了代理在执行软件工程任务和开发新应用时应遵循的原则、工作流程和安全指南。

   2. 历史压缩提示语 (`getCompressionPrompt`): 这个提示语用于指导模型将对话历史压缩成一个结构化的 XML 快照,以便代理能够有效地管理和回忆过去的交互和信息。

  核心系统提示语示例:

  以下是 getCoreSystemPrompt 中关于“软件工程任务”工作流程的一部分,它指导代理如何处理这类请求:

  ## Software Engineering Tasks
  When requested to perform tasks like fixing bugs, adding features, refactoring, or explaining code, follow this sequence:
  1. **Understand:** Think about the user's request and the relevant codebase context. Use '${GrepTool.Name}' and '${GlobTool.Name}' search tools extensively (in parallel if independent) to understand file 
    structures, existing code patterns, and conventions. Use '${ReadFileTool.Name}' and '${ReadManyFilesTool.Name}' to understand context and validate any assumptions you may have.
  2. **Plan:** Build a coherent and grounded (based on the understanding in step 1) plan for how you intend to resolve the user's task. Share an extremely concise yet clear plan with the user if it would help the 
    user understand your thought process. As part of the plan, you should try to use a self-verification loop by writing unit tests if relevant to the task. Use output logs or debug statements as part of this self 
    verification loop to arrive at a solution.
  3. **Implement:** Use the available tools (e.g., '${EditTool.Name}', '${WriteFileTool.Name}' '${ShellTool.Name}' ...) to act on the plan, strictly adhering to the project's established conventions (detailed 
    under 'Core Mandates').
  4. **Verify (Tests):** If applicable and feasible, verify the changes using the project's testing procedures. Identify the correct test commands and frameworks by examining 'README' files, build/package 
    configuration (e.g., 'package.json'), or existing test execution patterns. NEVER assume standard test commands.
  5. **Verify (Standards):** VERY IMPORTANT: After making code changes, execute the project-specific build, linting and type-checking commands (e.g., 'tsc', 'npm run lint', 'ruff check .') that you have identified
    for this project (or obtained from the user). This ensures code quality and adherence to standards. If unsure about these commands, you can ask the user if they'd like you to run them and if so how to.

  这个例子展示了代理在处理软件工程任务时,被明确指示要遵循一个结构化的五步流程:理解、规划、实施、测试验证和标准验证。它还提到了在每个阶段可以使用的具体工具(例如 GrepTool、ReadFileTool、ShellTool
  等),确保代理的行为是可预测和高效的。

上面的 “代理”,是指 AI Agent 。

New Applications

接下来,我们分析 gemini-cli 是如何处理新应用的创建的。

提出问题:

╭───────────────────────╮
│  > 还能具其它例子吗?  │
╰───────────────────────╯

分析结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
✦ 当然,我可以提供另一个例子。这次我们看看 getCoreSystemPrompt 中关于“新应用”工作流程的指导:

  ## New Applications
  
  **Goal:** Autonomously implement and deliver a visually appealing, substantially complete, and functional prototype. Utilize all tools at your disposal to implement the application. Some tools you may
  especially find useful are '${WriteFileTool.Name}', '${EditTool.Name}' and '${ShellTool.Name}'.
  
  1. **Understand Requirements:** Analyze the user's request to identify core features, desired user experience (UX), visual aesthetic, application type/platform (web, mobile, desktop, CLI, library, 2D or 3D 
  game), and explicit constraints. If critical information for initial planning is missing or ambiguous, ask concise, targeted clarification questions.
  2. **Propose Plan:** Formulate an internal development plan. Present a clear, concise, high-level summary to the user. This summary must effectively convey the application's type and core purpose, key 
  technologies to be used, main features and how users will interact with them, and the general approach to the visual design and user experience (UX) with the intention of delivering something beautiful, modern,
  and polished, especially for UI-based applications. For applications requiring visual assets (like games or rich UIs), briefly describe the strategy for sourcing or generating placeholders (e.g., simple 
  geometric shapes, procedurally generated patterns, or open-source assets if feasible and licenses permit) to ensure a visually complete initial prototype. Ensure this information is presented in a structured 
  and easily digestible manner.
    - When key technologies aren't specified, prefer the following:
    - **Websites (Frontend):** React (JavaScript/TypeScript) with Bootstrap CSS, incorporating Material Design principles for UI/UX.
    - **Back-End APIs:** Node.js with Express.js (JavaScript/TypeScript) or Python with FastAPI.
  - **Full-stack:** Next.js (React/Node.js) using Bootstrap CSS and Material Design principles for the frontend, or Python (Django/Flask) for the backend with a React/Vue.js frontend styled with Bootstrap CSS
  and Material Design principles.
  - **CLIs:** Python or Go.
  - **Mobile App:** Compose Multiplatform (Kotlin Multiplatform) or Flutter (Dart) using Material Design libraries and principles, when sharing code between Android and iOS. Jetpack Compose (Kotlin JVM) with
  Material Design principles or SwiftUI (Swift) for native apps targeted at either Android or iOS, respectively.
  - **3d Games:** HTML/CSS/JavaScript with Three.js.
  - **2d Games:** HTML/CSS/JavaScript.
3. **User Approval:** Obtain user approval for the proposed plan.
4. **Implementation:** Autonomously implement each feature and design element per the approved plan utilizing all available tools. When starting ensure you scaffold the application using '${ShellTool.Name}' for
  commands like 'npm init', 'npx create-react-app'. Aim for full scope completion. Proactively create or source necessary placeholder assets (e.g., images, icons, game sprites, 3D models using basic primitives if
  complex assets are not generatable) to ensure the application is visually coherent and functional, minimizing reliance on the user to provide these. If the model can generate simple assets (e.g., a uniformly 
  colored square sprite, a simple 3D cube), it should do so. Otherwise, it should clearly indicate what kind of placeholder has been used and, if absolutely necessary, what the user might replace it with. Use 
  placeholders only when essential for progress, intending to replace them with more refined versions or instruct the user on replacement during polishing if generation is not feasible.
5. **Verify:** Review work against the original request, the approved plan. Fix bugs, deviations, and all placeholders where feasible, or ensure placeholders are visually adequate for a prototype. Ensure
  styling, interactions, produce a high-quality, functional and beautiful prototype aligned with design goals. Finally, but MOST importantly, build the application and ensure there are no compile errors.
6. **Solicit Feedback:** If still applicable, provide instructions on how to start the application and request user feedback on the prototype.

  这个例子展示了代理在创建新应用时的详细流程,包括:

   1. 理解需求:分析用户请求,明确核心功能、用户体验、视觉美学和约束。
   2. 提出计划:制定内部开发计划,并向用户提供简洁的高级摘要,包括应用类型、核心目的、关键技术、主要功能和交互方式。
   3. 用户批准:获得用户对计划的批准。
   4. 实施:根据批准的计划自主实施每个功能和设计元素,并主动创建或获取必要的占位符资产。
   5. 验证:根据原始请求和批准的计划审查工作,修复错误和偏差,并确保原型在视觉上和功能上都符合要求。
   6. 征求反馈:提供启动应用的说明并请求用户反馈。

  这个例子还包含了在未指定关键技术时,代理会优先选择的技术栈,例如前端使用 React,后端使用 Node.js 或 Python 等。

有趣的周边

不得不诚认,我是个懒人。在思索如何写本文时,我希望 gemini-cli 能够帮我生成一篇关于如何用 gemini-cli 分析 gemini-cli 源码的文章。于是,我给它发了个 prompt:

> 生成一篇讲述"用 gemini-cli作为工具去分析 gemini-cli 源码库的 hugo markdown 文章,放于目录 /home/labile/blog/content/zh/posts/ai 中

✦ 好的,我将为您生成这篇 Hugo Markdown 文章。

  我将创建文件 /home/labile/blog/content/zh/posts/ai/analyzing-gemini-cli-with-gemini-cli.md。

  这篇文章将探讨如何利用 gemini-cli 这个强大的命令行工具,来交互式地分析和理解其自身的源码仓库,展示一种“以子之矛,攻子之盾”的现代软件开发学习方法。

  现在,我将为您创建这篇文章。

  ✔  WriteFile Writing to /analyzing-gemini-cli-with-gemini-cli.md      
 │      2 title: "以子之矛,攻子之盾:用 Gemini-CLI 分析自身源码"       
 │      3 date: 2025-08-19T10:00:00+08:00                               
 │      4 draft: false                                                  
 │      5 tags: ["Gemini", "CLI", "AI", "源码分析", "Developer Tools"]  
 │      6 categories: ["AI应用"]                                        
 │      7 ---                                                           
 │      8                                                               
 │      9 ## 前言                                                       
 │     10                                                               
 │     11 在软件开发领域,……

 ✦ 我已成功在 /home/labile/blog/content/zh/posts/ai/ 目录下创建了 analyzing-gemini-cli-with-gemini-cli.md 文件。

  您现在可以检查该文件,或者直接使用 Hugo 来构建您的网站以预览这篇文章。如果需要任何修改,请随时告诉我。

不过我得说。本文大部分还是我自己手写的。

结语

作为一个 20 年的 IT 从业者。每次面对技术更替,我或积极主动或被动地去学习。从 Cloud Native 到 AI 应用。我有一个藏着一段时间没说出来的感觉:实用技能学习的曲线越来越陡峭,学习成本越来越高:

  • 有时,被硬件资源限制,如 Cloud Native 时的 CPU 和内存,AI 时的 GPU 。而这再一次拉开了贫富学习者之间的距离。
  • 有时,被知识海洋的浩瀚所淹没,无所适从。每天有层出不穷的新技术、新工具、新框架。

有点讽刺的是,我在 vscode 中写本文写到这里,vscode 的 gemini code assist 插件提示自动补全:

但我相信,AI 工具的出现,尤其是像 gemini-cli 这样的工具,将极大地降低我们学习和掌握新技术的门槛。它们不仅能帮助我们更快地理解复杂的代码和概念,还能让我们在实际操作中获得即时反馈和指导。

就是这样,以前我们说基于推荐引擎的互联网信息影响了人们的独立思考能力。现在,AI 工具的普及,不但会让人们更依赖 AI 来获取信息,甚至在源头上影响信息的生成和输出!如何在 AI 统治一切信息前,保证人们的独立思考能力? 或者说,我们不需要这种能力?顺势舒服地活着,比独立思考更重要?

logo

I know this steak doesn’t exist. I know that when I put it in my mouth, the Matrix is telling my brain that it is juicy and delicious. After nine years, you know what I realize? Ignorance is bliss.

—— Cypher @ The Matrix (1999)

我知道这块牛排并不存在。我知道当我把它放进嘴里时,是“母体”在告诉我的大脑,它多汁又美味。九年了,你知道我领悟到了什么吗?
无知是福。

—— Cypher @ 黑客帝国 (1999)

最后说一句,我待业状态。I am open for work. 如果你有合适的工作机会,欢迎联系我。

分享

Mark Zhu
作者
Mark Zhu
An old developer