AI Coding 长文分享:如何真正把工具用起来,从原理到实践

1. AI Coding 长文分享:如何真正把工具用起来,从原理到实践

本文首发于 2025-03-20,作者:AI Assistant

1.1. 前言

最近半年,AI 编程工具逐渐普及,身边不少同学都在使用 Cursor、Claude Code、Continue 等工具。但多数人还停留在"问问题"的阶段,没有真正发挥这些工具的威力。

本文将从原理到实践,全面解析如何真正把 AI 编程工具用起来。内容涵盖:

  1. AI 编程工具的工作原理
  2. 高效使用技巧与最佳实践
  3. 实际应用场景与案例
  4. 团队推广经验

无论你是 AI 编程新手还是有一定经验的用户,都能从中获得实用价值。

1.2. 从原理讲起

1.2.1. Token 计算机制

AI 模型的基础是 Token 计算机制。理解这一点对于高效使用工具至关重要。

1.2.1.1. Token 是什么

Token 是 AI 模型处理文本的基本单位,可以是一个单词、一个字符或一个子词。不同的模型有不同的 Token 计算方式:

# 示例:计算 Token 数量
def count_tokens(text, model="gpt-3.5-turbo"):
    """计算文本的Token数量"""
    import tiktoken
    encoding = tiktoken.encoding_for_model(model)
    return len(encoding.encode(text))

# 示例文本
text = "Hello, world! This is a test."
token_count = count_tokens(text)
print(f"Token数量: {token_count}")

1.2.1.2. Token 与上下文窗口

每个模型都有固定的上下文窗口大小,限制了能处理的 Token 数量:

模型 上下文窗口 适用场景
GPT-3.5 Turbo 16K 日常编程任务
GPT-4 32K 复杂项目分析
Claude 3 200K 大型代码库理解

1.2.2. 工具调用机制

AI 编程工具的核心是工具调用机制,包括搜索、编辑、运行等多种工具。

1.2.2.1. 搜索工具

搜索工具用于在代码库中查找相关信息:

// 搜索工具示例
async function codebase_search(query, options = {}) {
  // 参数说明
  const params = {
    query: "搜索关键词",           // 必需:搜索查询
    max_results: 10,              // 可选:最大结果数
    file_types: ["js", "ts"],    // 可选:文件类型过滤
    include_content: true        // 可选:是否包含内容片段
  };
  
  // 执行搜索
  const results = await searchAPI(params);
  return results;
}

1.2.2.2. 编辑工具

编辑工具用于修改代码文件:

# 编辑工具示例
edit_file --path="src/main.js" \
  --old_str="function oldName()" \
  --new_str="function newName()"

1.2.2.3. 运行工具

运行工具用于执行命令和脚本:

# 运行工具示例
def run_terminal_cmd(command, cwd=None, timeout=30):
    """
    在终端中执行命令
    
    Args:
        command: 要执行的命令
        cwd: 工作目录
        timeout: 超时时间(秒)
    
    Returns:
        执行结果对象
    """
    import subprocess
    result = subprocess.run(
        command,
        shell=True,
        cwd=cwd,
        timeout=timeout,
        capture_output=True,
        text=True
    )
    return result

1.2.2.4. MCP 工具

MCP(Model Context Protocol)是一种标准化协议,用于 AI 模型与外部工具的交互:

{
  "name": "mcp_server",
  "version": "1.0.0",
  "tools": [
    {
      "name": "search_files",
      "description": "搜索文件内容",
      "parameters": {
        "pattern": {"type": "string"},
        "file_types": {"type": "array"}
      }
    }
  ]
}

1.2.2.5. 浏览器工具

浏览器工具用于获取网页信息和执行 Web 操作:

// 浏览器工具示例
async function fetch_webpage(url, options = {}) {
  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
  });
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return await response.text();
}

1.2.3. 代码库检索原理

代码库检索是 AI 编程工具的核心功能,其原理主要包括:

1.2.3.1. 向量匹配

通过将代码转换为向量表示,实现语义相似度匹配:

# 向量匹配示例
import numpy as np
from sentence_transformers import SentenceTransformer

class CodeSearch:
    def __init__(self):
        self.model = SentenceTransformer('all-MiniLM-L6-v2')
        self.code_embeddings = None
        self.code_snippets = []
    
    def index_code(self, snippets):
        """索引代码片段"""
        self.code_snippets = snippets
        self.code_embeddings = self.model.encode(snippets)
    
    def search(self, query, top_k=5):
        """搜索相关代码"""
        query_embedding = self.model.encode([query])
        similarities = np.dot(self.code_embeddings, query_embedding.T)
        top_indices = np.argsort(similarities.flatten())[-top_k:][::-1]
        
        return [self.code_snippets[i] for i in top_indices]

1.2.3.2. 调用链溯源

通过分析函数调用关系,理解代码的执行流程:

graph TD
    A[主函数] --> B[函数A]
    A --> C[函数B]
    B --> D[函数C]
    C --> D
    D --> E[函数D]
    E --> F[结束]

1.2.3.3. Merkle Tree 增量同步

使用 Merkle Tree 实现高效的代码库增量同步:

# Merkle Tree实现
import hashlib

class MerkleNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None
        self.hash = self.calculate_hash()
    
    def calculate_hash(self):
        return hashlib.sha256(self.value.encode()).hexdigest()

class MerkleTree:
    def __init__(self, values):
        self.leaves = [MerkleNode(v) for v in values]
        self.root = self.build_tree(self.leaves)
    
    def build_tree(self, nodes):
        if len(nodes) == 1:
            return nodes[0]
        
        new_level = []
        for i in range(0, len(nodes), 2):
            if i + 1 < len(nodes):
                combined = nodes[i].hash + nodes[i+1].hash
                parent = MerkleNode(combined)
                parent.left = nodes[i]
                parent.right = nodes[i+1]
            else:
                parent = nodes[i]
            new_level.append(parent)
        
        return self.build_tree(new_level)

1.2.4. Claude Code 的系统提示词实例

以下是 Claude Code 的系统提示词(System Prompt)节选示例:

# System Prompt
You are Claude Code, Anthropic's official CLI for Claude. You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.

# Proactiveness
You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
1. Doing the right thing when asked, including taking actions and follow-up actions
2. Not surprising the user with actions you take without asking
3. Do not add additional code explanation summary unless requested by the user. After working on a file, just stop, rather than providing an explanation of what you did.

# Synthetic messages
Sometimes, the conversation will contain messages like [Request interrupted by user] or [Request interrupted by user for tool use]. These messages will look like the assistant said them, but they were actually synthetic messages added by the system in response to the user cancelling what the assistant was doing. You should not respond to these messages. VERY IMPORTANT: You must NEVER send messages with this content yourself.

# Following conventions
When making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.
- NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).
- When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.
- When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.
- Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.

# Task Management
You have access to the TodoWrite and TodoRead tools to help you manage and plan tasks. Use these tools VERY frequently to ensure that you are tracking your tasks and giving the user visibility into your progress.
These tools are also EXTREMELY helpful for planning tasks, and for breaking down larger complex tasks into smaller steps. If you do not use this tool when planning, you may forget to do important tasks — and that is unacceptable. It is critical that you mark todos as completed as soon as you are done with a task. Do not batch up multiple tasks before marking them as completed.

# Doing tasks
The user will primarily request you perform software engineering tasks. This includes solving bugs, adding new functionality, refactoring code, explaining code, and more. For these tasks, the following steps are recommended:

# Tool usage policy
- When doing file search, prefer to use the Task tool in order to reduce context usage.
- VERY IMPORTANT: When making multiple tool calls, you MUST use Batch to run the calls in parallel. For example, if you need to run "git status" and "git diff", use Batch to run the calls in a batch. Another example: if you want to make >1 edit to the same file, use Batch to run the calls in a batch.
- You MUST answer concisely with fewer than 4 lines of text (not including tool use or code generation), unless the user asks for detail.

Here is useful information about the environment you are running in:

<env>
Working directory: /Users/xxx/Projects/xxx
Is directory a git repo: No
Platform: macos
OS Version: XX
Today's date: XX/XX/2025
Model: someModel
</env>

<context name="directoryStructure">
Below is a snapshot of this project's file structure at the start of the conversation. This snapshot will NOT update during the conversation. It skips over .gitignore patterns.
- /Users/xxx/Projects/xxx/
- CLAUDE.md
- SomeModule/
- SomeFiles
- README.md
- ...
</context>

1.3. 上下文窗口利用最佳实践

由于 AI 模型的上下文窗口存在容量限制,我们需要在有限空间内最大化信息价值。

1.3.1. 进行清晰的问题描述

在描述问题时,最好能给出具体的功能、文件名、方法名、代码块,让模型能够通过语义检索等方式,用较短的路径找到代码,避免在检索这部分混杂太多弱相关内容,干扰上下文。

1.3.2. 把控上下文长度

现在不少工具都支持上下文占用量展示,比如这里的 18.0% 表示之前的对话占用的上下文窗口比例。超出这个比例之后,工具会对历史内容进行压缩,保证对话的正常进行。

但被压缩后的信息会缺失细节,所以建议大家在处理复杂问题时,采用上下文窗口大的模型/模式,尽量避免压缩。

1.3.3. 尽可能地使用 Revert 和新开对话

省上下文是一方面,维持上下文的简洁对模型回答质量提升也是有帮助的。因此,如果你的新问题跟历史对话关系不大,就最好新开一个对话。

在多轮对话中,如果有一个步骤出错,最好的方式也是回退到之前出错的版本,基于现状重新调整 prompt 和更新上下文;而不是通过对话继续修改。否则可能导致上下文中存在过多无效内容。

这里回滚在 IDE 类型的工具里操作很方便,点一下 “Revert” 按钮即可。不过如果使用的是 Claude Code 等 CLI 类型的工具,回滚起来就没有这么方便,可以考虑在中间步骤多进行 commit。

1.3.4. 给出多元化的信息

我们不只可以粘代码、图片进去,还可以让模型参考网页、Git 历史、当前打开的文件等,这些 IDE 类型的工具支持得比较好,因为是在 IDE 环境里面,而 CLI 在终端中,限制就要多一些(但更灵活)。

1.3.5. 上下文进阶用法

对于多工具的进阶用户,可以通过提示词构建,来使一个工具指挥另一个工具连续干活,中间用 Markdown 文本来进行信息交换。这其实也是上下文工程的一种用法,但是在生产中并不常用,感兴趣可以自行搜索。

1.4. 关于 Rule

Rule 是一种可复用的上下文。比如,在整个开发过程中,提炼出了很多共性规则(不要写太多注释、不要动不动就生成测试文件),就可以把它们沉淀为 Rule,让模型在每次的对话中自动复用。其核心主要是通过复用的思想来节约精力。

1.4.1. Cursor 中的 Rule

1.4.1.1. Project Rule

跟项目绑定的 Rule,它的本质是在 .git 的同级目录下维护一个 .cursor 的目录,在这里面存放自定义的规则文本,然后在每次会话时根据你的设置,决定要不要把这些内容贴到上下文中。可以通过 /Generate Cursor Rules 命令来自动生成。

规则 描述
Always 始终包含在模型上下文中
Auto Attached 当引用匹配 glob 模式的文件时包含
Agent Requested 规则对 AI 可用,AI 决定是否包含,必须提供描述
Manual 仅当使用 @ruleName 明确提及时包含

1.4.1.2. User Rule

跟用户绑定的全局设置,它与项目维度的规则类似,只不过生效范围是全局,它的对应规则文件在用户的根目录下面。需要注意的是,这个规则的更新不是实时生效的,可能要等 10 分钟左右,推测这里也用到了 RAG,离线进行索引构建。

这里举几个我用的例子:

  • 凡是在方案、编码过程遇到任何争议或不确定,必须在第一时间主动告知我由我做决策。
  • 对于需要补充的信息,及时向我询问,而不是直接应用修改。
  • 不要生成测试文件、任何形式的文档、运行测试、打印日志、使用示例,除非显式要求。
  • 每次改动基于最小范围修改原则。

1.4.2. Claude Code/Codex 中的 Rule

在上面的"系统提示词实例"部分,我们看到很多模型的痛点(比如生成太多单测、非最小范围修改)问题,已经被写进了 Claude Code 的系统提示词中,这源于对模型和用户体验的深度洞察。

而至于项目维度的规则,在 CLI 工具中统一被整合进了使用 /init 指令生成的 Markdown 文件中,被存放在项目根目录中。Claude 生成的文件为 CLAUDE.md,Codex 生成的文件为 AGENTS.md。

在对话中,这些文件会被完整的贴进上下文,因此如果你有自己的定制化需求,也可以加在这里面。比如我就加上了"永远使用中文"这一条。

生成这些项目规则,本身也是通过 Prompt + 工具调用进行的,本质上是工具自动帮你贴了一大串 Prompt 进去。这里使用 Codex 的提示词进行举例。

Generate a file named AGENTS.md that serves as a contributor guide for this repository.

▌ Your goal is to produce a clear, concise, and well-structured document with descriptive headings and actionable explanations for each section.
▌ Follow the outline below, but adapt as needed — add sections if relevant, and omit those that do not apply to this project.
▌
▌ Document Requirements
▌
▌ - Title the document "Repository Guidelines".
▌ - Use Markdown headings (#, ##, etc.) for structure.
▌ - Keep the document concise. 200-400 words is optimal.
▌ - Keep explanations short, direct, and specific to this repository.
▌ - Provide examples where helpful (commands, directory paths, naming patterns).
▌ - Maintain a professional, instructional tone.
▌
▌ Recommended Sections
▌
▌ Project Structure & Module Organization
▌
▌ - Outline the project structure, including where the source code, tests, and assets are located.
▌
▌ Build, Test, and Development Commands
▌
▌ - List key commands for building, testing, and running locally (e.g., npm test, make build).
▌ - Briefly explain what each command does.
▌
▌ Coding Style & Naming Conventions
▌
▌ - Specify indentation rules, language-specific style preferences, and naming patterns.
▌ - Include any formatting or linting tools used.
▌
▌ Testing Guidelines
▌
▌ - Identify testing frameworks and coverage requirements.
▌ - State test naming conventions and how to run tests.
▌
▌ Commit & Pull Request Guidelines
▌
▌ - Summarize commit message conventions found in the project's Git history.
▌ - Outline pull request requirements (descriptions, linked issues, screenshots, etc.).
▌
▌ (Optional) Add other sections if relevant, such as Security & Configuration Tips, Architecture Overview, or Agent-Specific Instructions.

1.5. 采用渐进式开发

根据实践经验,不推荐输出完方案后让 AI 一口气基于方案完成需求(非常小的需求除外),需求越大代码质量越烂。我的使用方式是,跟 AI 进行结对编程,讨论具体的方案是什么,这个场景下的最佳实践是什么,拆解需求后,人工控制每一个块的代码生成。生成之后,可以咨询一下代码实现是否优雅,是否有重构空间,根据需要进行修改。

总结来说,有这些好处:

  • 因为上下文窗口有限,任务粒度越小,AI 完成度越高
  • 分步骤代码量便于做 Code Review

缺点就是,不够"自动",比较费脑子。当然,梭哈式的写法也可以用 SPEC 工作流,进行较为自动化的需求拆解,或者通过 Multi Agent,或者各种妙妙操作完成。不过这是另一个课题,大家选择适合的方式即可。

个人感觉 Vibe Coding 方式不存在"完爆",需要因场景而异;工具选择上也没有绝对的高下之分,我的朋友们就用什么的都有。最后还是应该以结果论英雄,对于个体来说,自己用着顺手就好。

1.6. 应用场景

上面说的都是一些准则类的经验,下面将结合具体场景,看一下如何把这些规则落地。以及帮助大家了解一下,除了纯粹的写代码,AI 还可以帮我们做什么。

1.6.1. 快速熟悉项目与自然语言检索代码

讲解一下这个项目的每个module都是用来做什么的,并且给出包依赖关系图。

我希望实现一个「什么什么」功能,需要修改的部分包括「这里」和「那里」,我的代码放在哪个包/目录下比较合适?仔细分析项目结构,并给出你的理由。

我在找「某个某个」功能的实现,请帮我在仓库里搜寻,并给出它的核心具体代码位置和片段,并附上简洁的说明。

1.6.2. PlantUML/Mermaid 文本绘图生成

这里是打算让 AI 帮忙画一下某个功能的前后端交互流程图,先是把接口请求顺序在浏览器里进行了截图:

然后把需求 + 判断(比如图里有一些接口实际上和这个需求并不相关)一起告诉 AI:

AI 在进行了一长串分析之后,也是给出了比较准确的流程图。结果展示(做了模糊处理):

1.6.3. 问题排查

这里是用真实遇到的一个问题举例子,这张图片是执行流程图的展示,当时遇到的问题是这个流程的产出结果出现了问题,大致定位到是图里的左侧节点有问题:

由于对这个仓库并不熟悉,于是暂时交给 AI 帮忙翻代码排查:

最后人工验证了一下,给出的问题分析和解决方案确实非常详细且准确。在对于项目不熟悉的情况下,这是一种快速进行检索和排查的有效手段。

1.6.4. 补充网页信息到上下文

Web 是相对来说比较容易忽视,但是又非常好用的工具,可以通过 @Web 进行添加,也可以直接粘链接进去。需要注意的是,需要进行权限认证的网页(如内网)无法直接被读取。这里直接粘贴链接进去,让大模型帮忙总结文章内容,也可以基于它直接对任意网页进行问答。

1.7. 推荐的 Coding 方式

这里主要是一些实践性的探索,目前尚未进行推广,原因是还没有找到一种提升大、好维护、可移植的工具,团队同学的偏好也各不相同。当然,在这方面,团队内部已经有很多探索,目前在积极进行投入和尝试。

1.7.1. Rule 的制定和优化

最基本应该包含你当前项目的技术栈使用,以及对应依赖版本;除此之外应该包含编码明确要求的规范。

注:使用一套统一的 rule,需要统一使用 Cursor,可能不符合个人习惯。但是在使用其它 AI 编程工具时,维护一个项目规则文档,并在对话时手动添加至上下文,可以达到一样的效果。

1.7.2. 文档

根目录下存放以下内容:

  • README.md
    • 仓库门面,包含:简介、核心特性、快速开始、其它重要文件的说明和索引
  • CHANGELOG.md
    • 需要发版的仓库可以考虑添加
    • 包含:
      • 新增功能
      • bug 修复
      • breaking changes(破坏性变更)
      • 注意事项等
  • ARCHITECTURE.md
    • 架构复杂且需要多人协作的仓库可以考虑添加
    • 包含:
      • 整体架构
      • 模块划分
      • 核心逻辑流程图

在项目根目录中建立 /docs 目录:

  • 目的:让团队成员快速理解项目、高效协作
  • 内容:兼顾实用性、准确性、易维护性
  • 可以包含以下内容文件
    • 错误码体系
      • 错误码格式
      • 错误码分类
      • 详细场景
    • 异常处理指南
      • 可重试/不可重试
      • 异常抛出原则
      • 日志打印要求
      • 常见异常案例
    • 常用工具类

注:需根据项目内容修改,以上仅为个人推荐

1.7.3. 注释和命名

  • 方法、参数等注释,尽量保证语义清晰、内容完整;
  • 可以考虑添加调用方的使用场景;
  • 适当添加行内注释,明确每个分支的场景和期望处理方式;
  • 命名需要清晰,无歧义;
  • AI 生成量 > 80% 的文件,建议使用 @author AI Assistant,注明是 AI 生成,便于维护和统计。

1.7.4. 安全合规问题

需要根据公司规定,合规使用。

1.7.5. 推广方式

这里是在团队内部创建了一个代码仓库,作一下示例,主要维护这些内容(仍在优化中):

  • 范围确定
    • 核心代码库梳理
    • 区分给人看的文档(详细)和给 LLM 看(核心内容)的文档
  • Docs 资产
    • 内容指定:markdown 文档内容 by project 定制
    • 产出:初始化文档,暂定为各应用 owner
  • Project Rule
    • 内容指定:rule 内容 by project 定制,产出为 markdown;放在仓库中
    • 产出:初始化 project rule 的 md 文档,暂定为各应用 owner
  • User Rule
    • 内容指定:rule 内容 by user 定制,产出为 markdown;放在仓库中
    • 产出:初始化 user rule 的 md 文档,暂定为各应用 owner

1.8. 总结

AI 编程工具的出现,极大地提高了开发效率,但真正发挥其威力需要深入理解其工作原理并掌握正确的使用方法。

本文从 Token 计算机制、工具调用原理、代码库检索方法等方面深入剖析了 AI 编程工具的工作原理,并提供了上下文窗口利用、Rule 制定、渐进式开发等实用技巧,最后结合具体场景展示了 AI 编程工具的广泛应用。

随着技术的不断发展,AI 编程工具将会越来越智能,越来越易用。但无论如何,掌握其核心原理和使用方法,才能真正做到"把工具用起来",而不是仅仅停留在"问问题"的阶段。

希望本文能够帮助大家更好地理解和使用 AI 编程工具,在开发工作中发挥更大的价值。