01 学习交流群
知识库之外,我们还建了「主流 Agent 入门交流群」。
进群和大家一起交流主流 Agent 的使用方法、适用场景和入门实践,分享不同工具的上手经验、工作流与真实案例,也会同步专题最新更新和实战资料。
扫码加入,一起找到适合自己的 Agent,真正用起来。

02 学前须知
先解决一个误会
你在网上搜"CodeBuddy",会看到三种完全不同的东西:一个装进 VS Code 的插件、一个独立的开发软件、一个在终端里敲命令的工具。
它们都叫 CodeBuddy,都是腾讯出的,但确实是三个不同的产品。
这不是营销上的混乱,是有意的设计——三种形态覆盖三种人。但如果你在不知道这件事的情况下开始用,很容易出现"我装了半天,怎么跟教程里长得不一样"这种问题。
所以这一章先把这件事讲清楚。
三种形态,一句话一个
| 形态 | 它是什么 | 长什么样 |
|---|---|---|
| CodeBuddy 插件 | 装进你现有编辑器的插件 | VS Code、JetBrains 系列里多一个侧边栏 |
| CodeBuddy IDE | 一个独立的桌面开发环境 | 单独安装的软件,打开就是它的界面 |
| CodeBuddy Code | 终端里的命令行工具 | 在终端敲 codebuddy,进入一个对话界面 |
再往下说一层,它们的定位差别很大:
插件版——你还是你,编辑器还是那个编辑器,它只是在旁边帮你补全代码、回答问题、改个 bug。传统模式下"人主导、AI 打辅助"。适合本来就天天写代码的开发者。
IDE 版——主打"对话即编程"。你不写代码,你描述需求,它从需求规划、设计、写代码一直做到部署。官方定位是"产品—设计—研发—部署"一体化,还带可视化调试和设计稿转代码。完全不懂编程的人也能从这里入门。
CLI 版(CodeBuddy Code)——本教程的主角。它在你的终端里运行,能读文件、跑命令、操作 Git、访问网络,还能接进自动化流水线。适合习惯命令行的人、需要批量处理的人、要把它塞进 CI/CD 的人。
为什么这套教程选 CLI
三个理由。
第一,它是能力最完整的一个。 插件只能在编辑器里活动;CLI 能碰的东西是系统级的——你的文件、你的命令、你的 Git 仓库、你的网络。批量处理两百个文件、给整个项目做重构、写个脚本让它自己定时跑,这些只有 CLI 顺手。
第二,它最容易被低估。 很多人装了插件就以为"AI 编程就那样",没意识到终端里还有一个能真正替你干活的东西。
第三,它逼着你养成好习惯。 CLI 会真的执行命令、真的改文件,你不得不学会"先要方案""看完 diff 再收工""先提交再动手"。这些习惯换成任何工具都受用。
至于 IDE 版和插件版,第 12 章会讲,到时候你会发现它们和 CLI 共享同一套记忆和规则文件——学完 CLI 再去用它们,几乎没有额外成本。
**本套教程配套代码:**https://gitee.com/geektime-geekbang_admin/ai-tutorial-material/tree/master/codebuddy-materials
它到底能干什么
说几个具体的,你感受一下:
用说话的方式完成开发任务。 "给我这个项目加上单元测试"、"把这个函数的性能问题找出来"、"把 util 目录下的代码风格统一一下"。它自己去读代码、改代码、跑命令、跑测试。
它是 Unix 工具链的一员。 这一点很多人不知道。它支持管道:
cat error.log | codebuddy -p "分析这些报错,找出根因"
git log --oneline -20 | codebuddy -p "看看这些提交里有没有可疑的"
就像 grep、awk 一样,可以塞进你的脚本里。
它能批量干活。 一个目录下三百个文件要重命名、老项目里所有 class 组件要改函数组件、几十个文件要加统一的错误处理——这类活它最擅长,也是手工做最痛苦的部分。
它能自动化。 因为它是命令行程序,所以可以被 cron 调用、被 CI 流水线调用、被你自己的脚本调用。第 9 章就干这个。
它能扩展。 MCP 可以接外部工具,子代理可以让不同的"专家"分工干活,规则文件可以让它记住你项目的规矩。
说清楚它不干什么
它不会替你做判断。 该不该这么重构、这个方案的风险在哪、这个数据能不能信——这些是你的活。它给的是选项和依据。
它会真的执行命令。 这是 CLI 和对话框最大的区别,也是最大的风险。它会跑 rm、会改文件、会提交 Git。所以"先让它给方案"不是一个建议,是必须。
它不是一次就对的。 第一版不满意是常态。正确做法是接着说哪里不对,而不是推倒重来——它记得前面所有的上下文。
它读到的信息要你把关。 联网查到的东西、对陌生代码的推测,都可能不准。教程里会反复提醒你验一遍。
你需要什么样的基础
这套教程的门槛不高,但你得满足这几条:
- 会在终端里敲命令,知道
cd、ls是干什么的 - 有自己的电脑,并且愿意在上面装东西
- 知道 Git 是什么(不熟没关系,教程会带着用)
- 能看懂简单的代码。案例用的是 Python,但你不需要会写——看懂大概意思就行
如果你完全没碰过终端,我建议你先花半小时熟悉一下基本命令再回来,不然每个命令都要现查,会很累。
如果你已经是熟练开发者,这套教程对你最有价值的应该是第 4 章(接手陌生仓库)、第 9 章(Git hook 与 CI)、第 10 章(规则与子代理)、**第 11 章(Plan 模式 / 子代理 / Skills / Hooks)**那几章——那些是真正能把日常流程重做一遍的地方。
这门课怎么学
七个案例,就是开发者日常会遇到的七件事:
- 接手陌生仓库:从 clone 到跑起来
- 给没测试的项目补上测试
- 从报错到修复:完整走一次 debug
- 重构那个没人敢动的臃肿模块
- 从零做一个小服务并部署上线
- 把重复活自动化:脚本、hook、CI
- 让它守规矩:规则、子代理、MCP
不是玩具需求,也不是假想的大企业系统——规模都在个人项目、开源贡献、小团队日常这个量级,你在工作里大概率遇到过。
每个案例你都会带走一个真的能跑的东西。贯穿全程的有三条规矩:动手前先让它给方案、改完先看 diff、每一步都有 Git 兜底。
关于命令的写法
这是本教程的一个规矩,先说明白:
凡是涉及命令的地方,我都会把三个环境分开写——macOS / Linux、Windows PowerShell、WSL2。因为它们的路径写法、环境变量配置方式、定时任务机制都不一样,混着写一定会出问题。
格式长这样:
macOS / Linux
mkdir -p ~/playground && cd ~/playground
Windows PowerShell
New-Item -ItemType Directory -Path "$HOME\playground" -Force
Set-Location "$HOME\playground"
WSL2
# 命令和 Linux 一样,但项目要放在 WSL 自己的文件系统里
mkdir -p ~/playground && cd ~/playground
你只需要看自己那一行。
另外提醒一句:WSL2 是 Windows 里跑 Linux,它的行为跟"Windows PowerShell 原生"是两回事。 如果你分不清自己在哪个环境里,先敲一行 uname -a(macOS/Linux/WSL2 会有输出,PowerShell 里会报错),确认一下再继续。
开始吧
下一章,把它装好。
四个平台我都写了,包括最麻烦的 WSL2。照着敲,中间别跳步——尤其是配置 PATH 那一段,那是新手卡住最多的地方。
03 装好它-四种环境
这一章的目标只有一个:不管你用什么机器,走完这一章,codebuddy 这条命令能用。
先说清楚一件事:这一章看起来长,是因为我把 macOS、Linux、Windows PowerShell、WSL2 四种环境分开写了。你只需要看你那一段,别的一眼扫过就行。
先确认你在哪个环境
如果你分不清自己属于哪一类,先做这个判断:
macOS / Linux(bash、zsh)
uname -a
有输出(一串系统信息)→ 你在这两类里。再敲 sw_vers 有输出就是 macOS,没有就是 Linux。
Windows PowerShell
$PSVersionTable.PSVersion
能显示版本号 → 你在 PowerShell 里。
WSL2
在 Windows 上打开 Ubuntu(或你装的发行版)终端,敲:
uname -a
输出里带 microsoft 或 WSL 字样 → 你在 WSL2 里。
关键区别:WSL2 是 Windows 里跑的 Linux,它按 Linux 的方式装、按 Linux 的方式用。它和"Windows PowerShell 原生"是两套环境,可以各装一份,互不干扰,但坑不一样——后面单独讲。
三条安装路线,选一条
CodeBuddy Code 有三种装法,挑一种就行:
| 路线 | 命令 | 前提 | 适合谁 |
|---|---|---|---|
| npm 系 | npm install -g @tencent-ai/codebuddy-code |
Node.js ≥ 18.20 | 机器上本来就有 Node 的开发者 |
| Homebrew | brew install Tencent-CodeBuddy/tap/codebuddy-code |
无(不用 Node) | macOS / Linux 用户,最省事 |
| 原生安装器(Beta) | 一行脚本 | 无(不用 Node) | 想要单文件、启动快、自动更新稳的人 |
我的建议:macOS 和 Linux 用 Homebrew,Windows 用原生安装器脚本。都不想折腾就直接用原生安装器,三种系统都能跑。
三条路最后得到的命令都是 codebuddy,功能没有区别。
macOS
第一步:装命令行工具(首次需要)
打开"终端"(Terminal),敲:
xcode-select --install
弹窗点"安装",等它跑完。这一步是为了拿到 git 和基础编译工具,后面会用到。
第二步:选一条安装路线
路线 A:Homebrew(推荐)
没有 Homebrew 先装它:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
装完按提示把 brew 加进 PATH。注意 Apple 芯片(M1/M2/M3/M4)的 brew 在 /opt/homebrew,Intel 在 /usr/local,装完终端会告诉你该加哪一行。
然后装 CodeBuddy:
brew install Tencent-CodeBuddy/tap/codebuddy-code
路线 B:原生安装器(不用装 Node)
curl -fsSL https://www.codebuddy.cn/cli/install.sh | bash
路线 C:npm(需要 Node ≥ 18.20)
npm install -g @tencent-ai/codebuddy-code
没有 Node 的话:brew install node。
第三步:如果命令找不到
原生安装器会把可执行文件放在 ~/.local/bin。如果敲 codebuddy 提示 command not found,手动加 PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
macOS 从 Catalina 开始默认 shell 是 zsh,配置文件是
~/.zshrc。如果你改过默认 shell 用 bash,那就是~/.bash_profile。不确定?敲echo $SHELL,显示/bin/zsh就用.zshrc,/bin/bash就用.bash_profile。
Linux
第一步:装依赖
Ubuntu / Debian
sudo apt update
sudo apt install -y curl git
CentOS / RHEL / Fedora
sudo dnf install -y curl git
(老版本 CentOS 用 yum 代替 dnf。)
第二步:选一条安装路线
路线 A:Homebrew(如果已装 brew)
brew install Tencent-CodeBuddy/tap/codebuddy-code
路线 B:原生安装器(推荐,不用 Node)
curl -fsSL https://www.codebuddy.cn/cli/install.sh | bash
路线 C:npm
npm install -g @tencent-ai/codebuddy-code
注意:apt 源里的 Node 版本经常很旧(可能低于 18.20)。要用 npm 路线,建议先装 nvm 或按 NodeSource 的指引装 LTS 版本,别直接
apt install nodejs。
第三步:PATH
命令找不到就加:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
用 zsh 的话把 .bashrc 换成 .zshrc。
没有 sudo 权限怎么办
用原生安装器时它会装到你的家目录,不需要 sudo。如果还是报权限错误,可以先指定一个自己的安装目录(具体参数以官方安装脚本提示为准),或者直接用 npm 路线配 nvm(nvm 装在 ~/.nvm,也不需 sudo)。
Windows PowerShell(原生)
第一步:确认执行策略
PowerShell 默认可能禁止运行远程脚本。先看一下当前策略:
Get-ExecutionPolicy
如果显示 Restricted,改成允许本地用户运行签名脚本:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
提示确认时输入 Y 回车。这一条只改当前用户,不影响系统其他账户。
第二步:安装
路线 A:原生安装器(推荐)
irm https://www.codebuddy.cn/cli/install.ps1 | iex
(irm 是 Invoke-RestMethod 的简写,iex 是 Invoke-Expression 的简写,作用类似于 bash 里的 curl | bash。)
路线 B:npm
没有 Node 先装:
winget install OpenJS.NodeJS.LTS
装完关掉终端重开一次(让 PATH 生效),再:
npm install -g @tencent-ai/codebuddy-code
第三步:PATH
原生安装器装在 %USERPROFILE%\AppData\Local\codebuddy\bin。命令找不到就手动加进用户 PATH:
[Environment]::SetEnvironmentVariable(
"Path",
[Environment]::GetEnvironmentVariable("Path", "User") + ";$env:USERPROFILE\AppData\Local\codebuddy\bin",
"User"
)
改完必须重开终端,新开的窗口才会生效。
建议:换个好点的终端
系统自带的 PowerShell 窗口体验一般,推荐装 Windows Terminal(微软商店里搜就有),它可以同时开 PowerShell、WSL、cmd 的标签页。
WSL2
WSL2 是在 Windows 里跑一个真正的 Linux。它按 Linux 的方式装 CodeBuddy,但有四个坑必须提前知道。
第一步:装 WSL2(如果还没装)
在 PowerShell(管理员身份)里敲:
wsl --install
它会自动装默认的 Ubuntu。想指定版本:
wsl --list --online
wsl --install -d Ubuntu-24.04
装完重启,开始菜单里会出现 Ubuntu,打开后设置用户名密码。
确认一下版本是 2:
wsl -l -v
VERSION 那一列应该是 2。如果是 1,执行 wsl --set-version Ubuntu-24.04 2。
第二步:在 WSL 里装 CodeBuddy
打开 Ubuntu 终端,按 Linux 的方式装:
sudo apt update && sudo apt install -y curl git
curl -fsSL https://www.codebuddy.cn/cli/install.sh | bash
装完如果需要:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
坑一:项目必须放在 WSL 的文件系统里
这是 WSL 性能问题里最大的一个。
# 对的:放在 WSL 自己的家目录
cd ~/projects/my-app
# 错的:放在 Windows 盘符映射过来的目录,会慢到怀疑人生
cd /mnt/c/Users/xxx/projects/my-app
/mnt/c/ 是跨文件系统的访问,读写速度差一个量级,尤其跑 npm install、git 操作的时候。代码放 WSL 里,需要用 Windows 工具编辑时再映射过去。
坑二:换行符
Windows 用 CRLF,Linux 用 LF。你在 WSL 里写代码、Windows 侧用编辑器打开,很容易搞出满屏 diff。
在 WSL 里设一次:
git config --global core.autocrlf input
含义是:提交时统一转成 LF,检出时不转换。这样仓库里永远是干净的 LF。
坑三:cron 不会自动启动
WSL 里 cron 服务默认不随系统启动。要用定时任务时:
sudo service cron start
想每次开机自动起,可以把这行加进 ~/.bashrc(或者配置 WSL 的 /etc/wsl.conf 开启 systemd)。
坑四:和 Windows 侧各装一套
你可以在 PowerShell 里装一份、在 WSL 里再装一份,两者独立,配置目录也不共享(Windows 是 %USERPROFILE%\.codebuddy,WSL 是 ~/.codebuddy)。
建议只在你主要干活的那一侧装,避免自己搞混"我刚才在哪边跑的"。
验证:确认装好了
不管哪个平台,都敲这一条:
codebuddy --version
显示版本号就是装好了。再进一次会话,敲 /doctor 让它自己体检一遍环境。
顺便认识一下它的短命令:
cbc --version
cbc 是 codebuddy 的简写,后面教程里两个都会出现,你习惯哪个用哪个。
登录
第一次启动:
codebuddy
会让你选登录方式:
Select login method:
› Log in via Chinese Site
Log in via International Site
Log in via Enterprise Domain
Log in via iOA (Tencent only)
用 ↑↓ 选择,Enter 确认,然后浏览器会自动打开让你完成认证。
四个选项的区别:
- Chinese Site(国内站):国内用户选这个,走腾讯云国内站
- International Site(国际站):海外用户
- Enterprise Domain(企业域名):公司自建或专享版,需要填企业给的服务地址
- iOA:腾讯内部员工专用
选错了没关系,随时可以 /logout 再 /login 换。
更新与卸载
更新
codebuddy update
它会自动检测你的安装方式并执行对应更新。默认也会自动更新,想关掉:
export DISABLE_AUTOUPDATER=1
从 npm 版迁移到原生版
codebuddy install
卸载
用哪条路装的就用哪条卸:brew uninstall codebuddy-code / npm uninstall -g @tencent-ai/codebuddy-code。原生安装器的话,删掉 ~/.local/bin/codebuddy(Windows 是 %USERPROFILE%\AppData\Local\codebuddy)即可。
四个平台的常见坑
| 症状 | 可能原因 | 怎么解决 |
|---|---|---|
command not found / 不是内部或外部命令 |
PATH 没配对 | 按上面各平台的 PATH 步骤加,且重开终端 |
| 装了一半卡住 | 网络问题 | 换网络,或改用国内镜像地址 https://copilot.tencent.com/cli/install.sh(PowerShell 是 install.ps1) |
| Node 版本报错 | Node 低于 18.20 | 换 Homebrew 或原生安装器路线,绕开 Node |
| PowerShell 报"禁止运行脚本" | 执行策略限制 | Set-ExecutionPolicy -Scope CurrentUser RemoteSigned |
| WSL 里跑得极慢 | 项目放在 /mnt/c/ |
把代码挪到 WSL 家目录 |
| git diff 全是改动其实没改 | 换行符不一致 | WSL/Linux/macOS 设 core.autocrlf input |
| 装完命令能跑但登录不了 | 网络或代理 | 检查代理环境变量,或换一种登录方式 |
小结
现在你手上有了一条能用的 codebuddy 命令。
下一章我们真的用它干活:建一个练习目录、跑第一次对话、把项目记忆建起来。那之后你才会发现,装好只是最简单的一步。
04 第一次对话-跑通一个小任务
装好了,先别急着拿它干正事。
这一章的目的很朴素:在一个随便怎么搞都不心疼的目录里,把它启动起来、跟它说上话、看它干成一件事。走完这一章,你对它的脾气就有手感了。
先弄一个 playground
我们需要一块沙地。它等会儿会真的在里面创建文件、跑命令,所以这块地必须是无所谓的——别直接在你的项目根目录或者桌面练手。
macOS / Linux
mkdir -p ~/playground/cbc-demo && cd ~/playground/cbc-demo
git init
Windows PowerShell
New-Item -ItemType Directory -Path "$HOME\playground\cbc-demo" -Force
Set-Location "$HOME\playground\cbc-demo"
git init
WSL2
# 注意:目录要建在 WSL 自己的文件系统里,别放 /mnt/c/
mkdir -p ~/playground/cbc-demo && cd ~/playground/cbc-demo
git init
git init 这一步不是走形式。往后每一章我都会强调同一件事:让它动手之前,先让 Git 能兜底。 现在这个仓库是空的,但等会儿它建的文件、改的内容,你随时能 git status 看到、随时能回退。这一条习惯,比学会任何一个命令都值钱。
顺便确认一下 git 认识你是谁(没设过的话提交会失败):
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
启动
在那个目录里敲:
codebuddy
(短命令 cbc 一样用。)
你会进入一个对话界面:底部是一个输入框,上面是它的输出区。第一次进去它可能提示你选登录方式(第 1 章讲过),登录完就能用了。
界面上会显示当前目录、当前权限模式这类信息。先别管,往下走。
第一件事:建项目记忆
进会话之后,第一个要敲的不是你的需求,是这条命令:
/init
它会扫描当前目录,然后生成一个 CODEBUDDY.md 文件。这就是这个项目的记忆文件——项目是干什么的、目录怎么组织的、用什么技术栈、有什么规矩,都记在这里。
以后每次在这个目录启动 CodeBuddy,它都会自动读这个文件。也就是说,你不用每次都重复介绍"这是个 Python 项目、用 pytest 跑测试、提交信息要用英文"。
为什么这件事要第一个做?
因为不建记忆的后果,是它会反复扫同一批文件、反复问你同样的问题、反复踩同样的坑。一个项目建一次记忆,后面几十次对话都省事。
现在目录是空的,它生成的 CODEBUDDY.md 会很简陋。没关系,等会儿目录里有东西了,我们再让它重写一次。
你可以看一眼它写了什么:
macOS / Linux / WSL2
cat CODEBUDDY.md
Windows PowerShell
Get-Content CODEBUDDY.md
第一个任务
好,跟它说第一句话。复制这段进去:
帮我写一个 Python 脚本 wordcount.py,读当前目录下任意一个或多个文本文件,
统计每个词出现的次数,按频次从高到低输出前 20 个,并打印总词数。
要求:
1. 用 argparse 做命令行参数,支持传多个文件路径
2. 忽略大小写,忽略标点符号
3. 包含 if __name__ == "__main__": 入口
4. 不要引入第三方依赖,只用标准库
写完直接运行一次,自己造两个测试用的文本文件验证结果对不对。
说完回车。然后你会看到它开始工作——它会说打算做什么、创建文件、可能问你"是否允许执行 python wordcount.py"。
注意那个询问。 这就是 CLI 和聊天框最大的区别:它要真的执行命令,所以默认每条有副作用的命令都会问你一次。你可以选 Yes,也可以选"Yes, and don't ask again for this command"。
如果你不想一条条确认,可以按 Shift+Tab 切换权限模式(后面细讲)。
跑完之后,看结果:
macOS / Linux / WSL2
git status
Windows PowerShell
git status
你会看到它新建了 wordcount.py 和两个测试文本文件。git status 这条命令,往后每次它干完活你都要敲一遍——看它到底动了哪些文件,别只听它说"我改好了"。
四个权限模式,你得知道自己在哪个
CLI 有四种权限模式,决定了"它能不能不问我直接干"。
| 模式 | 行为 | 什么时候用 |
|---|---|---|
default |
读文件自动放行,改文件/跑命令要问你 | 默认。陌生项目、第一次操作、心里没底的时候 |
acceptEdits |
改文件不问了,跑命令还是问 | 你已经信任它,且改动都在版本控制里 |
plan |
只给方案,一个字都不动 | 想先看它打算怎么干,或者涉及危险操作 |
bypassPermissions |
全部放行 | 只在容器、CI 这类隔离环境里用。日常开发慎用 |
切换方式是按 Shift+Tab(部分 Windows 终端上是 Alt+M),按一次切一个,界面上有提示。
我的建议:日常保持 default,涉及重构和删除先切 plan。 那几次"点一下 Yes"的成本,远低于它一次改错带给你的麻烦。
几个必须记住的键
不用背,用两次就熟了:
| 键 | 作用 |
|---|---|
Esc |
中断它正在做的事。它跑偏了、开始胡说八道了,按这个 |
Ctrl+C |
退出当前任务/退出程序 |
Ctrl+O |
展开看它的思考过程(默认折叠)。想知道它"为什么这么做"时用 |
Shift+Enter |
输入框里换行(直接回车是发送)。写多行提示词必备 |
↑ |
调出上一条输入 |
Tab |
输入 @ 之后按 Tab 补全文件名 |
Esc 那个键特别值得记住。它开始跑一个莫名其妙的命令时,别等它跑完,直接打断。
结束与恢复
一次对话干完一件事,想换话题,敲:
/clear
它会清空上下文重新开始。这一条比你想象的重要——上下文里堆着上一件事的细节,会污染下一件事的判断。一件事一个会话,是最省 token 也最不容易出错的做法。
想找回上一次的会话:
/resume
会列出最近的会话让你挑。或者启动时指定:
codebuddy --resume
顺手做一次完整闭环
趁热打铁,把这套动作做一遍,往后每个案例都这么走:
# 1. 看它改了什么
git status
# 2. 看具体改了哪些行
git diff
# 3. 没问题就提交
git add -A
git commit -m "feat: add wordcount script with argparse and tests"
git diff 那一步别省。它的"改好了"和你的"改好了"可能不是一个意思——尤其当它自作主张删了点什么的时候,只有 diff 会告诉你。
本章你多了什么
- 一个
~/playground/cbc-demo目录,里面有一个能跑的wordcount.py - 一份
CODEBUDDY.md项目记忆(现在还很简单) - 一条肌肉记忆:动手前 git 兜底,干完看 status 和 diff
- 四个权限模式的概念和
Shift+Tab切换 Esc打断、/clear换话题、/resume找回
常见坑
它一直在问"是否允许",烦。 两种解法:一是按 Shift+Tab 切到 acceptEdits;二是针对某条命令选"不再询问"。但涉及 rm、git push、--force 这类,我建议你永远手动确认。
它改出来的脚本跑不起来。 把报错整段复制给它,说"这段报错,修一下"。不用自己分析,它会读得比你还仔细。这是 CLI 最省事的地方之一。
它跑了很久没动静。 可能是在扫描大量文件或者在等网络。按 Ctrl+O 看它在想什么。真的卡住了就 Esc。
换了个目录启动,它就不认识项目了。 记忆文件是按目录走的。换了目录要么重新 /init,要么用 @CODEBUDDY.md 把它引进来(第 3 章讲)。
下一章讲心法——喂什么样的上下文、三种用法怎么选、会话怎么管。这些内容不刺激,但决定了后面七个案例你做得顺不顺。
05 核心心法-上下文、模式、会话
这一章没有实战案例,但它是整本书的分水岭。
用同一个工具,有人觉得"也就那样",有人觉得离不开,差别几乎全在这一章:你给它的上下文够不够、你会不会分阶段喂、你知不知道什么时候该开新会话。
3.1 上下文决定质量
先记住一句话:它不知道的事情,它一定会猜。而猜的部分,就是错误的部分。
你给的上下文越具体,它猜的空间越小,输出越可用。这件事听起来理所当然,但绝大多数"AI 不好用"的抱怨,根源都是上下文没给够。
CodeBuddy 的上下文是分层的,一共五层,从全局到局部:
| 层级 | 位置 | 作用 | 要不要提交进 Git |
|---|---|---|---|
| 用户记忆 | ~/.codebuddy/CODEBUDDY.md |
你个人的通用偏好,所有项目都生效 | 不(在你家目录里) |
| 用户规则 | ~/.codebuddy/rules/ |
你个人的通用规则 | 不 |
| 项目记忆 | ./CODEBUDDY.md 或 ./.codebuddy/CODEBUDDY.md |
这个项目的背景、结构、约定 | 要,团队共享 |
| 项目规则 | ./.codebuddy/rules/ |
这个项目的具体规矩 | 要 |
| 本地记忆 | CODEBUDDY.local.md |
个人在这个项目里的临时偏好 | 不(自动进 gitignore) |
这个分层设计的用意很清楚:能共享的共享(项目级,提交进仓库),不能共享的留本地(用户级和 local,自动忽略)。
你不需要现在就记住这张表。先知道两件事:
CODEBUDDY.md是项目记忆,/init生成的就是它,可以手动改,改完它立刻按新内容执行- 有些私人的东西(比如"我的测试数据库连接变量名(不填写密码或密钥)是 xxx")绝对不要写进项目记忆,写进
CODEBUDDY.local.md
想看看当前的记忆状态,会话里敲:
/memory
它会列出加载了哪些记忆文件。觉得它忘了什么事,多半是那一层没写。
一份好的项目记忆长什么样
不是"这是一个 Python 项目"这种废话,是这些信息:
# 项目:订单服务
## 是什么
内部订单处理服务,给 App 和小程序提供订单接口。
## 技术栈
- Python 3.11 + FastAPI
- PostgreSQL 14,SQLAlchemy 2.0(不用 1.x 写法)
- pytest + pytest-cov,覆盖率门槛 80%
## 怎么跑
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload # http://localhost:8000/docs
## 目录约定
app/api/ 接口层,只做参数校验和转发
app/service/ 业务逻辑,不允许直接写 SQL
app/model/ 数据模型
tests/ 测试,目录结构与 app/ 对应
## 规矩
- 所有接口必须有对应的单元测试
- 数据库操作一律走 service 层,禁止在 api 层直接查库
- 提交信息用 Conventional Commits 格式
- 不要修改 migrations/ 下已提交的迁移文件
注意最后那块"规矩"。你写的每条规矩,它都会当作约束遵守。 这是让 AI 稳定输出的最有效手段——比你在提示词里重复一百遍都管用。
3.2 怎么把材料喂给它
四种方式,按场景选。
一、@ 引用文件。 输入 @ 会弹出文件列表,或者直接打字:
@src/order/service.py 这个函数为什么在并发下会算错金额?
支持一次引用多个,也支持引用整个目录(@src/order/)。引用会触发 Tab 补全。
二、@import 语法。 在 CODEBUDDY.md 里用 @import 可以把别的文件引进来:
@import ./docs/api-convention.md
@import ./docs/db-schema.md
适合记忆文件太长、想拆开维护的情况。
三、直接粘贴。 报错日志、配置片段、一小段代码,直接粘进输入框最省事。长日志建议先存成文件再引用,免得刷屏。
四、管道。 这一条最容易被忽略,也最能体现 CLI 的优势:
# 把日志灌进去分析
cat error.log | codebuddy -p "找出根因,给出最可能的三个原因"
# 分析最近 20 个提交
git log --oneline -20 | codebuddy -p "哪些提交有风险,为什么"
# 分析依赖情况
pip list --format=freeze | codebuddy -p "哪些包版本过旧,哪些有已知漏洞"
选 @ 还是管道? 规则很简单:内容在文件里就用 @(它还能顺带看文件的上下文),内容是命令的输出就用管道。
3.3 三种用法
交互式
codebuddy
进入对话,适合探索性的活——"这个项目怎么回事"、"帮我设计个方案"。大部分开发任务用这个。
单次执行(-p)
codebuddy -p "把这个目录下所有 .py 文件的 docstring 统一成 Google 风格"
跑完就退出,不进对话。适合塞进脚本和 CI。
需要它自己干活不想被权限拦住时,加 -y:
codebuddy -p "给 utils.py 补上单元测试" -y
-y 是跳过确认的意思,请谨慎。 我的习惯是:在容器里、CI 里、或者改动全在 Git 版本控制下的裸仓库里才敢加 -y。日常开发目录里不要加。
管道
上一节说过了。管道本质是把 -p 和 stdin 结合起来,适合一次性分析。
怎么选? 需要来回讨论 → 交互式;确定性的批处理任务 → -p;分析命令输出 → 管道。
3.4 会话管理
几个命令,用熟了效率差很多:
| 命令 | 作用 | 什么时候用 |
|---|---|---|
/clear |
清空上下文重新开始 | 换了一件事 |
/resume |
找回之前的会话 | 昨天的活接着干 |
/compact |
压缩历史对话,保留要点 | 上下文快满了、它开始"失忆" |
/context |
看当前占用了多少上下文 | 感觉它变笨了 |
/cost |
花了多少 | 心里有数 |
/branch |
从当前位置开一个分支会话 | 想试两条路,不想互相污染 |
/compact 值得单独说。 当一轮对话聊了几十轮,上下文会接近上限,它开始忘记前面说过的话。这时候 /compact 会把历史压缩成一份摘要,质量不会明显下降,但空间腾出来了。
判断标准:敲 /context 看占用比例,超过七成就该 /compact 或者 /clear 了。
3.5 让它先想清楚
这一条我单独拿出来讲,因为它是区分新手和熟手的分水岭。
新手拿到任务是直接说"帮我重构这个文件"。熟手会先说:
先不要改任何代码。读一遍 src/order/service.py,
告诉我:它现在有哪几个职责、哪几块耦合最严重、
你会怎么拆、每一步的风险是什么。给我一个三到五步的方案。
拿到方案,你看一眼,觉得对,再说"按第一步来"。
为什么要多这一步? 三个理由:
- 方案错了,改起来零成本;代码错了,改起来很贵。 它改完三百行你才发现方向不对,比看三行方案累一百倍。
- 你能借机发现它理解错了。 比如它以为那个字段是必填的,其实可以为空。在方案阶段说清楚,比在代码阶段返工强。
- 方案给你验收的依据。 后面每一步你都有东西可以对照。
配合 plan 模式用效果更好:按 Shift+Tab 切到 plan 模式,它在里面只能出方案不能动手,物理上杜绝了"说着说着就改了"。
"先给方案"这句话怎么写? 记住这个句式:
先不要改代码。先做A,然后给我B。
A = 读什么、分析什么;B = 输出什么格式的方案。越具体越好,比如"给我三到五步的方案,每步标注改动的文件和验证方式"。
3.6 验收三步
它说"完成了",只是开始。每次都要走这三步:
第一步:看它动了什么。
git status
git diff
重点看有没有动到你不让它动的文件。它会顺手"优化"一些你没要求的东西,这是常见行为。
第二步:跑一遍。
# 按项目自己的方式
pytest
# 或 npm test / make test / go test ./...
测试过了再看下一步。项目没测试?那正好是下一章的事。
第三步:自己读关键改动。
不是逐行 review,而是看这几处:
- 它加了什么依赖?(
package.json/requirements.txt有没有多出没必要的包) - 它删了什么?(有没有顺手删掉你不让删的)
- 边界处理对不对?(空值、异常、并发)
- 有没有硬编码的东西混进来(路径、密钥、端口号)
这三步加起来两三分钟。跳过它,出问题的概率会高很多。
3.7 好习惯清单
后面七个案例反复会用到这几条,先列在这里:
- 动手前先有 Git 快照。 新项目
git init,老项目确认工作区干净,改大东西先开分支。 - 先要方案,再要代码。 尤其是重构、删除、批量操作。
- 一件事一个会话。 换事就
/clear。 - 干完必看
git status和git diff。 - 报错整段复制给它,不要自己转述。
- 不满意就接着说哪里不对,不要重开——它记得上下文,重开等于丢掉所有背景。
- 危险操作(
rm、--force、git push、改数据库)永远手动确认。 - 把重复的规矩写进
CODEBUDDY.md,不要每次在提示词里重说。 - 它联网查到的东西,自己验一遍。 版本号、API 签名、配置项,它都有可能记错。
- 上下文超过七成就
/compact。
常见坑
它总是忘了我说过的话。 两可能:一是上下文满了(/compact),二是你把它写在了对话里而不是 CODEBUDDY.md。对话里的规矩会随着 /clear 消失,写进记忆文件的不会。
它改了一堆我没让它改的文件。 提示词里明确加一句"只改 X,其他文件一个都不要动"。并且事后一定要 git status 检查。
同一个任务每次结果都不一样。 说明你的提示词约束不够。把输出格式、边界条件、不允许的做法都写死,它才会稳定。
它说"已完成"但我跑不起来。 把报错粘给它。90% 的情况它缺的是运行环境信息——Python 版本、依赖版本、当前工作目录。在 CODEBUDDY.md 里写清楚这些,这类问题会少一大半。
从下一章开始,全是实战。第一个案例就是最常遇到的:接手一个陌生仓库。
个人记忆也会进入模型上下文。凭据用环境变量或密钥管理器提供,不写进记忆、提示词或日志。
06 案例1-接手陌生仓库
4.1 准备一个独立副本
安装 Python 3.10+ 和 Git,确认 python --version(macOS/Linux 可用 python3)和 git --version。把 materials-cbc/01-legacy-repo 复制到新的 playground/legacy-repo,后面的命令在该副本根目录执行。目录已有文件时另取名字,不覆盖。git init -b main 后先检查 git status,再 git add main.py 并提交初始快照;Git 要求身份时先配置自己的 user.name 和 user.email。
这份素材只有 main.py,使用 Python 标准库,没有 Flask,也不需要 pip install。它故意把端口保存成字符串。
4.2 先复现,再交给助手
运行 python main.py,应在绑定端口时出现类型错误。保留完整错误、Python 版本和运行目录。让 CodeBuddy 先读取源码,说明启动入口、HTTP 路由和错误触发位置,暂不修改。检查它是否指向 HTTPServer 的端口类型,而不是建议安装无关依赖。
4.3 一次只修启动问题
创建 docs/onboarding 分支,请它只修端口类型并补 README:启动命令、默认端口、健康检查、停止方式。退出 Plan 模式后才执行。不要同时重构路由或升级依赖。
启动修复后的服务,另开终端执行:
python -c "import urllib.request; r=urllib.request.urlopen('http://127.0.0.1:5000/health',timeout=5); print(r.status,r.read().decode())"
应为 HTTP 200,JSON 中 status 为 ok。服务终端 Ctrl+C 停止;5000 被占用时先识别占用进程,或明确同时修改启动端口和检查地址。
4.4 验收并交接
运行 git status --short --untracked-files=all 和 git diff,确认仅有端口修复与 README;复核 README 命令可以从新终端运行,再提交。记录:原错误、根因、改动、验证输出。不能仅凭助手说“启动成功”验收。
下一章使用另一个独立项目 02-billkit,不在本目录继续加账单逻辑。
07 案例2-给没测试的项目补上测试
5.1 准备与基线
把 materials-cbc/02-billkit 复制到新目录 playground/billkit,进入副本。Python 3.10+;创建虚拟环境并激活(Windows 为 .venv\Scripts\Activate.ps1,POSIX 为 source .venv/bin/activate),执行 python -m pip install pytest==8.4.2 pytest-cov。git init -b main,检查忽略规则后提交初始快照。
python -m billkit.cli --input data/usage-2024-03.csv --month 2024-03
python -m pytest --cov=billkit --cov-report=term-missing
第一条应输出 14 张账单。初始目录没有 tests,第二条应提示没有收集到测试,退出码为 5;这是基线,不是测试通过。覆盖率可能没有数据,不伪造一张 0% 报表。
5.2 先确定测试契约
让助手先读取 README 和源码,按价格、折扣、输入校验、账单合计、CLI 排序测试风险。人工核算 basic 的 12000 用量:10000×0.02+2000×0.015=230;70000 用量小计 1000。折扣合同是“达到即享”,包括 basic 的 1000/3000 和 pro 的 2000/5000 四个边界。
只添加 tests/test_pricing.py,不修改 billkit/ 实现。
用 Decimal 字符串构造金额和期望值;分别测阶梯内、跨档、零、负数、未知套餐。
四个折扣门槛按达到即享断言。运行后区分测试自身错误和实现违反合同。
实现的边界缺陷保留到第 6 章,不为跑绿改低期望或修产品代码。
先运行测试,再 git diff -- billkit,后者应为空。四个门槛应失败;其他规则应通过。需要校对时,参考 materials-cbc/verification/test_pricing.py,不直接拿实现结果当期望。
5.3 检查断言与补齐输入测试
非空、类型断言不能替代金额断言。对照至少一个手算样例。parser.read_usage 遇到坏行抛 ValueError,不是跳过坏行;测试缺列、空客户、非法/负 units。当前输入月份采用 YYYY-MM,不能凭空要求多种日期格式兼容。
给 Invoice.finalize 的税前、6% 税率和两位小数取整补用例。给 processor.process(path, month) 传 tmp_path 下的小 CSV,断言返回账单列表的客户、数量及金额;它没有 run() 或输出文件参数。CLI 测试另用 subprocess 检查退出码和实际文本。
5.4 对比练习放在独立 worktree
先提交本章测试(提交信息写明四个已知边界失败),确认工作区干净,再 git worktree add ../billkit-naive -b experiment/naive HEAD。在该副本试“帮我写测试”,对比它是否漏掉边界。未提交文件不会因切分支消失,因此不要在主目录切来切去模拟隔离。
结束时先检查副本的 git status;需要留存就提交,确认无未保存内容后 git worktree remove ../billkit-naive。不要用强制删除掩盖实验产物。
5.5 本章验收与下一章
统一入口为 python -m pytest -v,跨平台都可用,不要求系统自带 make。需要覆盖率时加 --cov=billkit。保留失败日志和四个边界断言,提交测试,不修实现。第 6 章将在同一 billkit 副本修复这些边界;完成后才能进入第 7 章重构。
08 案例3-从报错到修复
场景
线上收到工单:有客户说账单金额跟合同对不上。日志里有零星几条 WARNING,但你本地跑一遍,结果看着挺正常。
偶发 bug 是最难搞的一类——复现不了就没法验证修没修好,改完还得担心是不是把别的弄坏了。
这一章我们完整走一遍:从日志定位 → 构造最小复现 → 先写失败测试 → 改代码 → 回归验证 → 评估影响范围。
现场
在 billkit 项目里(上一章做完的那个),素材包给了两份现场材料:
logs/app.log 220 行,里面有 WARNING 和 ERROR
data/usage-2024-03.csv 3 月的用量数据
先自己看一眼日志,心里有个底:
macOS / Linux / WSL2
grep -E "WARNING|ERROR" logs/app.log | head -20
Windows PowerShell
Select-String -Path logs\app.log -Pattern "WARNING|ERROR" | Select-Object -First 20
你会看到类似:
2024-04-01 02:15:00,123 WARNING billkit 客户 C1016 账单金额高于预期,用量档位疑似未生效
2024-04-01 03:21:00,456 ERROR billkit 收到工单:账单金额与合同不符,请核查阶梯计价
注意那个词:"疑似未生效"。前人的猜测未必对——待会儿你会看到真正的根因不是档位问题。这很常见:日志里的判断经常是错的,别照着日志的结论去修。
第一步:先让它读现场,但别让它改
读一下 logs/app.log 和 billkit/pricing.py、billkit/processor.py。
工单说有客户账单金额跟合同对不上。请你:
1. 从日志里找出被点名的客户 ID
2. 列出你对根因的三个假设,按可能性排序,每个假设说明依据
3. 对每个假设,给出一个能证伪它的具体命令或代码
先不要改任何代码。
"给出能证伪它的具体方法"这句是关键。它会逼自己把假设变成可验证的东西,而不是停留在"可能是档位没生效"。
第二步:用真实数据复现
它多半会建议跑一遍真实数据,把可疑客户挑出来。我们就这么干:
在项目根目录写 find_anomaly.py(使本地 billkit 包可导入),
对 data/usage-2024-03.csv 跑一遍完整流程,对每个客户输出:
客户号、套餐、用量、小计、折扣率、折扣额、税额、应付。
然后对照 pricing.py 里文档字符串写的折扣规则("达到"门槛即享),
找出实际折扣与规则不符的客户。把结果做成表格打印出来。
这个脚本是临时排查用的,写完告诉我,我会决定要不要删。
跑:
python find_anomaly.py
你会得到这样的输出(数字以实际为准):
客户 套餐 用量 小计 折扣率 折扣额 应付
C1016 basic 70000 1000.00 0.00 0.00 1060.00 ← 规则说满1000应减3%
C1017 pro 200000 2000.00 0.05 100.00 2014.00 ← 规则说满2000应减10%
找到了。只有这两个客户有问题,其他 12 个都正常——这就是"偶发"的真相:不是随机出现,是只有金额恰好等于门槛时才出现。
这类 bug 靠"多跑几次碰运气"是永远复现不出来的。正确做法是找出触发条件的边界,而不是靠运气。
第三步:把根因挖出来
现在让它定位代码:
复现了:C1016(basic,小计恰好 1000.00)应该享受 3% 折扣但实际是 0;
C1017(pro,小计恰好 2000.00)应该是 10% 但实际是 5%。
其他客户都对。
看 pricing.py 的 volume_discount,告诉我:
1. 根因是哪一行
2. 为什么只有"恰好等于"时才触发
3. 这个写法在别的地方有没有同样的隐患(比如 tiered_price 里)
4. 改动会影响哪些调用方
它会指出:volume_discount 里用的是 subtotal > 1000 和 subtotal > 2000,而合同写的是"达到即享",应该是 >=。恰好等于时不满足 >,所以跳到了下一档。
顺手让它查了第 3 点——同一类错误往往不止一处。这比只修眼前这一个值钱得多。
第四步:先写失败测试,再改代码
上一章我们已经提交过一组失败的边界测试了(具体名称以你的 tests/test_pricing.py 为准)。如果你跳过了上一章,现在补一个:
给 pricing.py 的折扣门槛写一个 pytest 用例,放在 tests/test_pricing.py:
- basic 套餐,subtotal 恰好 1000.00,期望折扣率 0.03
- basic 套餐,subtotal 恰好 3000.00,期望折扣率 0.08
- pro 套餐,subtotal 恰好 2000.00,期望折扣率 0.10
- pro 套餐,subtotal 恰好 5000.00,期望折扣率 0.15
先跑一遍确认它是红的,把失败输出给我看。别改实现代码。
pytest tests/test_pricing.py -k discount -v
看到红色。FAILED ... assert 0.0 == 0.03。
为什么坚持"先写失败测试"? 三个理由:
- 它证明你真的复现了。 测试红 = bug 在,测试绿 = bug 没了。这是唯一可靠的判据。
- 它防止 bug 复发。 三个月后有人手滑把
>=改回>,这条测试会立刻报警。 - 它是最清晰的 bug 报告。 比截图和文字描述都精确。
第五步:改
现在才轮到改代码:
现在改。要求:
1. 把 volume_discount 里的门槛判断改成"达到即享"语义(>=)
2. 顺手检查 tiered_price 里有没有同类的边界问题,有就一起修,没有就明确告诉我没有
3. 不要改函数签名,不要改调用方
4. 改完把 tests/test_pricing.py 跑绿,再把全套测试跑一遍
5. 告诉我改了哪几行
它改完之后,先看 diff 再看测试:
git diff
确认改动只有那几行比较运算符,没有顺手"优化"别的东西。确认完再跑:
pytest -v
全绿。再验一次真实数据:
python -m billkit.cli --input data/usage-2024-03.csv --month 2024-03
现在 C1016 应该是 ¥1028.20(1000 - 30 折扣 = 970,加 6% 税 = 1028.20),C1017 是 ¥1908.00(2000 - 200 = 1800,加税 1908.00)。
算一遍这个数。 让 AI 改代码的风险不在于它改错,而在于它改对了但你不知道它对不对。手算一遍是最后一道防线。
第六步:评估影响范围
修完就完了吗?没有。这是个已经跑了几个月的计费 bug,得知道历史上影响了谁。
这个 bug 从 volume_discount 写出来的那天就存在了。帮我评估影响范围:
1. 查 git log,找出这个函数是何时引入的、之后改过几次
2. 写一个脚本,扫描 out/ 和 data/ 下所有历史账单数据,
找出"小计恰好等于折扣门槛值"的记录,列出客户和月份
3. 估算这些客户被多收的总金额
4. 给我一份需要补差价的客户清单,格式是 CSV
脚本只读取、不修改任何现有文件。
第 4 点那句"脚本只读取、不修改"很重要。排查脚本一旦会写文件,风险就上了一个量级。
有了这份清单,你才敢去跟业务方说"影响 N 个客户、合计 M 元,需要补差价"。没有这个数,你只能说"好像有点问题"——那是完全不同的两回事。
Git:fix 分支的两步提交
git checkout -b fix/discount-boundary
# 第一步:提交失败测试(如果你上一章没提交过)
git add tests/
git commit -m "test: 折扣门槛按「达到即享」语义补充边界用例
合同规定月度金额达到门槛即享折扣,实现用了 > 而非 >=,
导致小计恰好等于门槛的客户不打折。当前用例失败,用于固化缺陷。"
# 第二步:提交修复
git add billkit/pricing.py
git commit -m "fix: 折扣门槛改为达到即享,修正边界客户不打折的问题
volume_discount 判断门槛时用了严格大于,小计恰好等于
1000/3000/2000/5000 的客户无法享受对应折扣。改为 >=。
影响范围:2024-03 账单中 C1016、C1017 两个客户,
分别多收 31.80 元和 106.00 元,需补差价。"
分两次提交的价值:将来看这段历史的人,能清楚看到"先有测试证明 bug 存在,再有修复"。顺序反了(先改再补测试),说服力就弱了——别人会怀疑测试是照着新代码写的。
提交信息让它生成:
用 Conventional Commits 格式给这次修复写提交信息。
标题不超过 50 字,正文说明:根因是什么、改了什么、
影响范围和金额、如何验证。
合并
git checkout main
git merge --no-ff fix/discount-boundary -m "Merge fix/discount-boundary
修复折扣门槛边界问题,影响 2 个客户共 137.80 元。"
用 --no-ff 保留分支历史。以后回看时能一眼看出"这是一次完整的 bug 修复"。
平台差异:排查命令对照
| 干什么 | macOS / Linux | Windows PowerShell | WSL2 |
|---|---|---|---|
| 实时看日志 | tail -f app.log |
Get-Content app.log -Wait |
tail -f app.log |
| 过滤关键字 | grep ERROR app.log |
Select-String -Path app.log -Pattern ERROR |
同 Linux |
| 统计出现次数 | grep -c ERROR app.log |
(Select-String -Path app.log -Pattern ERROR).Count |
同 Linux |
| 看端口占用 | lsof -i :8000 |
Get-NetTCPConnection -LocalPort 8000 |
同 Linux |
| 看进程 | ps aux | grep python |
Get-Process python |
同 Linux |
| 环境变量 | export X=1 |
$env:X = "1" |
同 Linux |
追日志时的高效用法:让终端里的日志直接流给它分析。
tail -f logs/app.log | codebuddy -p "实时分析这些日志,出现 ERROR 或异常模式时总结出来"
本章你多了什么
- 一个修好的 bug,和一条防它复发的回归测试
- 一份影响范围清单(哪些客户、多少钱、哪些月份)
- 一次完整的 debug 流程经验:不是"看到报错→改代码",而是"定位→复现→固化→修复→评估"
本章新知识点
| 知识点 | 说明 |
|---|---|
| 要假设,也要证伪方法 | 逼它把猜测变成可验证的东西 |
| 找触发边界,不靠碰运气 | 偶发 bug 的真相通常是某个边界条件 |
| 先写失败测试 | 唯一可靠的"修好了"判据 |
| 排查脚本只读 | 定位阶段绝不让它写文件 |
| 评估影响范围 | 修完 bug 不等于事情结束 |
| 两步提交 | 测试一次、修复一次 |
延伸练习
- 让它把这次 debug 的全过程写成一份
docs/postmortem-2024-03-discount.md(事故复盘模板) - 让它在
tests/里加一个"合同一致性测试":把折扣规则写成数据驱动的用例表,改规则时只改表 - 让它给
processor.py加一个防御:账单金额与上月相比波动超过某个阈值时打 WARNING——让下一个 bug 早点被发现
常见坑
它一上来就改代码。 用 plan 模式(按 Shift+Tab 切到 plan),它在里面只能出方案。
它改的地方比你要求的多。 提示词里写"不要改函数签名,不要改调用方,改完告诉我改了哪几行"。事后一定 git diff。
它说修好了,但你不知道验证标准。 每次都要它给出"修复前后的具体数值对比"。修 bug 必须能看到数字变化。
日志里的结论是错的。 这次日志说"档位未生效",实际是折扣门槛判断问题。永远把日志当线索,不当结论。
偶发 bug 修完就没再管。 一定要跑影响范围评估——代码里的一个字符,对应的是真金白银。
下一章,我们对那个谁都不敢碰的胖子模块下手。
09 案例4-重构那个没人敢动的模块
7.1 接续条件
沿用第 6 章副本,先跑全套 pytest,并确认四个折扣边界已经通过。提交修复,工作区干净后创建 refactor/billing 分支。本素材刻意保持短小,processor.py 没有几百行,也没有 render_text、write_outputs 等函数;不要为演示拆分而凭空造出七层模块。
7.2 给外部行为留证据
processor.process(path, month) 接收 CSV 路径和月份,返回 Invoice 列表。先补一组特征测试:同月多客户、跨月、空输入、非法用量;断言客户、套餐、用量、小计、折扣和 finalize() 金额。用临时 CSV,不改配套原始数据。
记录 CLI 的 14 张账单输出,其中 C1016 为 1028.20,C1017 为 1908.00。特征测试记录现状,但发现现状违反合同仍需单独记录缺陷,不能因为快照通过就宣布正确。
7.3 只抽出一个有价值的边界
先让助手给方案,不写代码。可选的小步是抽出纯函数 build_invoice(row),保留 process(path, month) 的签名、筛选规则和输出顺序。确认后退出 Plan 模式,授权这一小步;拒绝新增不必要的配置框架。
改完跑单元及 CLI 测试,查看 git diff,确认没有改价格、折扣或舍入规则,再提交。若扩展出 CSV 导出,先增加对外契约和回归测试,作为功能开发另一次提交,不混进“行为不变”的重构。
7.4 失败实验与回退
需要比较“一口气重写”时,从干净提交创建独立 worktree;方法见第 5 章 5.4。主工作区保留通过测试的版本。改动未提交时先看 diff 并保存需要的内容,不能把切换分支当作清空改动。
7.5 验收
全部测试通过、CLI 两个关键金额不变、对外签名不变、每次提交只有一个意图。最终记录抽出的职责以及为何值得抽出;没有收益时保留原实现也是合理结论。
10 案例5-从零做一个小服务并部署上线
8.1 明确第一版契约
复制 materials-cbc/05-service-starter 到独立 shortlink 项目,阅读需求说明:GET /health 返回 {"status":"ok"};POST /api/shorten 接收 url,返回 code;GET /{code} 返回 302 与 Location;GET /api/stats/{code} 返回 clicks。非法 URL 返回 4xx,未知 code 返回 404。只接受 http/https,拒绝空值和 javascript: 等协议。
让助手先规划 FastAPI、SQLite 和测试入口,确认后才实施。锁定实际安装的依赖版本,生成 requirements.txt 或锁文件;不要假定未安装的测试客户端可用。DATABASE_PATH 是唯一数据库路径配置,默认本地 data/shortlink.db,容器用 /data/shortlink.db。
8.2 本地验收
启动命令、端口和环境变量写入 README;以下约定服务在 8000。把配套 smoke.py 复制到 scripts/,执行:
python scripts/smoke.py http://127.0.0.1:8000
脚本验证健康响应、创建、302 Location 和计数,不跟随外站跳转;任一失败必须非零退出。另写 pytest 覆盖非法 URL、未知 code、数据库临时目录隔离。把健康状态改错或跳转状态改成 200 时,smoke 必须失败;恢复后再继续。
8.3 容器持久卷
要求助手生成 Dockerfile:锁定依赖,使用非 root 用户,创建 /data 并将所有权交给该用户;服务监听 0.0.0.0:8000。构建前确认 Docker 可用。
docker build -t shortlink:lesson .
docker volume create shortlink-data
docker run -d --name shortlink-lesson -p 8000:8000 -e DATABASE_PATH=/data/shortlink.db -v shortlink-data:/data shortlink:lesson
python scripts/smoke.py http://127.0.0.1:8000
保存 smoke 输出的 code,再 docker stop shortlink-lesson、docker rm shortlink-lesson,以同一命令重建容器。访问旧 code 应仍然 302,stats 保留先前点击记录;只创建新 code 不能证明持久化。若 volume 权限错误,修正镜像目录权限,不能退回每次随机临时数据库。
8.4 云端部署
选用支持持久磁盘的平台,把同一个 DATABASE_PATH 指向实际挂载点,核对 HTTPS、端口映射和重启策略。存储和计费以平台当前文档为准,不承诺免费层具备持久卷。部署后重新执行 smoke 与旧 code 重启验证,再记录镜像版本、配置变量名和回滚方法。凭据不提交。
本地验证不能替代云端验证;没有云账号时做到容器实验并在 README 标注“云端未验证”,不要虚构已上线地址。
11 案例6-把重复活自动化
9.1 先有可重复的检查
沿用测试已通过的 billkit。统一 python -m pytest -v 为门禁,测试失败必须返回非零。AI 审查只提供建议;成功解释错误不代表测试通过。
9.2 暂存审查和分支审查是两个输入
提交前捕获 git diff --cached --binary,它包含本次暂存修改;PR 审查使用 git diff main...HEAD,它只比较已提交的分支差异。没有 main 时先确认实际基准,不盲目运行。把差异保存到项目外临时文件,再明确提供给 CodeBuddy;保留工具退出码和原始输出,输出“OK”不是验收协议。
普通 pytest 检查的是当前工作树。若有部分暂存修改,先整理提交范围或在临时 worktree 重建暂存快照后测试,不能宣称普通 pre-commit 自动验证了索引中的精确版本。
9.3 配置提交检查
使用 pre-commit 时先在虚拟环境安装工具,添加本地 hook:
repos:
- repo: local
hooks:
- id: tests
name: Python tests
entry: python -m pytest -v
language: system
pass_filenames: false
always_run: true
fail_fast: false
执行 pre-commit install,再 pre-commit run --all-files。fail_fast:false 只表示某项失败后继续运行其他 hook,失败仍会阻止提交。想要建议性质的 AI 审查,应在单独命令或 CI 报告步骤中执行,不靠这个选项忽略失败。
9.4 每周依赖检查
配套 weekly_dep_check.py 使用当前 Python 执行 pip list --outdated --format=json,失败非零,成功写入依赖报告。先手工运行并检查报告,再交给系统调度。不会自动安装升级。
POSIX cron 使用解释器与脚本的绝对路径;Windows 任务计划程序同样把虚拟环境 python.exe 填入“程序”,脚本绝对路径与报告路径作为参数,设置工作目录。不调用不存在的 .ps1,也不要求未安装的 pwsh。调度账号、网络和虚拟环境必须与手动验收一致。
9.5 验收自动化本身
临时制造一个测试失败,pre-commit 应拒绝提交;恢复后通过。只暂存一个文件,确认 cached diff 不含未暂存文件。模拟依赖命令失败,不应留下看似本次成功的新报告。记录三个结果后才启用定时任务。
12 案例7-让它守规矩
场景
前面六个案例,你每次都在提示词里重复同样的要求:
- "提交信息用 Conventional Commits"
- "改完跑测试"
- "不要改我没让你改的文件"
- "金额计算要有测试,边界要测"
说第三遍的时候你就该意识到:这些不该在提示词里说,应该写成规则让它自己记住。
这一章你会带走:一套提交进仓库的项目规范、一个自定义的审查子代理、一个接进来的外部工具。
先分清四样东西
很多人把它们搞混。一句话一个:
| 东西 | 是什么 | 什么时候加载 |
|---|---|---|
记忆(CODEBUDDY.md) |
项目背景知识 | 每次都加载 |
规则(.codebuddy/rules/*.md) |
具体的行为约束 | 按条件触发(或常驻) |
| 子代理 | 一个有独立上下文的专职角色 | 你点名或它自动派活时 |
| MCP | 外部工具/数据源的接入 | 需要时调用 |
记忆回答"这是什么",规则回答"该怎么做",子代理回答"谁来干",MCP 回答"能用什么工具"。
第一步:把规矩写成规则文件
先让它帮你整理:
回顾我们前面几章做过的所有要求和项目约定,
把它们整理成一组规则文件,放在 .codebuddy/rules/ 下。
要求:
1. 一个主题一个文件,不要塞进一个大文件
2. 每条规则必须是可检查的(能判断做没做到),
不能是"要写好代码"这种没法验证的话
3. 用 frontmatter 标注触发条件:
- 有些规则要一直生效(比如提交信息格式)
- 有些只在改特定文件时生效(比如改到 pricing.py 才提醒金额测试)
4. 每条规则给出正反例子
先列一份清单给我看,确认后你再写文件。
它整理的清单大概是这样:
| 文件 | 触发条件 | 内容 |
|---|---|---|
commit.md |
常驻 | 提交信息用 Conventional Commits,标题 ≤50 字 |
testing.md |
tests/**、**/*pricing* |
金额与边界必须有测试,禁止假断言 |
python-style.md |
**/*.py |
类型注解、禁止裸 except、路径用 pathlib |
git-workflow.md |
常驻 | 重构与修 bug 分分支;危险命令先确认 |
security.md |
常驻 | 禁止把密钥写进代码;禁止读 .env |
单个规则文件长这样(frontmatter 的字段名以你当前版本为准,不确定就在会话里问它一句):
---
description: 金额计算相关的改动必须有边界测试
paths: ["**/pricing*.py", "**/models.py", "**/invoice*.py"]
alwaysApply: false
---
# 金额计算改动规范
修改任何涉及金额计算的代码时,必须同时补测试。
## 必须覆盖
- 档位/门槛的边界值(恰好等于、刚好超过、刚好不足)
- 负数、零、空输入
- 浮点精度(断言用 `pytest.approx`,不要直接 `==`)
## 禁止
- `assert result is not None` 这类不验证数值的断言
- 只测正常流程不测异常
## 正例
assert tiered_price(10000, "basic") == pytest.approx(200.0)
## 反例
assert tiered_price(10000, "basic") is not None
注意"正反例子"这部分。 抽象的规则它容易理解偏,给个反例它就不会犯。这是写规则最有效的一招。
再看一个常驻规则的写法:
---
description: 提交信息格式
alwaysApply: true
---
# 提交信息规范
格式:`<type>(<scope>): <subject>`
type 只能是:feat / fix / refactor / test / docs / chore / perf / build
subject 用中文或英文都可以,但同一仓库要统一,不超过 50 字,结尾不加句号。
正文(可选)说明"为什么改",不是"改了什么"——改了什么看 diff 就知道。
## 反例
改了点东西
fix bug
Update files
第二步:写一个自定义审查子代理
规则是"它自己记住",子代理是"派一个专职的人去干"。
我们来写一个 code-reviewer:
帮我定义一个子代理 code-reviewer,放在 .codebuddy/agents/code-reviewer.md。
它的职责:改完代码之后做一次独立审查。
要求:
1. 只读,不允许修改任何文件(要在定义里写死它的工具权限)
2. 审查清单:
- 逻辑正确性(边界、异常、并发)
- 安全性(注入、越权、敏感信息)
- 是否符合 .codebuddy/rules/ 里的所有规则
- 是否有遗漏的测试
- 与项目既有约定的一致性
3. 输出格式:按 [阻塞] [建议] [可选] 三类,每条标注文件名和行号
4. 每条问题必须给出具体的修改建议,不能只说"这里有问题"
5. 如果没发现问题,就明确说"没发现问题",不要硬凑
定义文件大概是这样:
---
name: code-reviewer
description: 代码改动完成后做独立审查。改完代码、提交前、或需要第二意见时使用。
tools:
- Read
- Grep
- Glob
---
你是这个项目的代码审查者。你只做审查,不修改任何文件。
## 审查清单
1. 逻辑正确性:边界条件、异常处理、并发问题
2. 安全性:注入、越权、敏感信息是否可能被打印或提交
3. 规范符合度:逐条对照 .codebuddy/rules/ 下的规则
4. 测试覆盖:这次改动有没有对应的测试
5. 一致性:命名、错误处理风格是否和既有代码一致
## 输出格式
[阻塞] 文件路径:行号 —— 问题描述 —— 建议怎么改
[建议] ...
[可选] ...
没问题的分类写"无"。不要为了显得有输出而凑问题。
tools 那一栏是关键——只给它只读工具,它就没法改代码。这比在提示词里说"不要改"可靠得多。
用起来:
用 code-reviewer 审查一下我刚才的改动
或者让它自动跑:
以后每次我让你改完代码并且跑通测试之后,
自动用 code-reviewer 子代理再审查一遍,把结果给我。
用 /agents 可以查看和管理所有子代理。
子代理的真正价值是上下文隔离。 它去翻一百个文件找线索,翻完只把结论交给你——你的主上下文不会被那些搜索过程污染。审查、考古、调研这类"要翻很多东西但结论很短"的活,都该派子代理。
第三步:接一个外部工具(MCP)
MCP 是让 CodeBuddy 能调用外部服务的标准协议——数据库、Jira、内部 API、文档系统,都能接进来。
我想让你可以直接查我们项目的数据库(只读)。
帮我:
1. 说明 MCP 配置应该放在哪个文件、什么格式
2. 给出一个只读数据库 MCP server 的配置示例
3. 告诉我怎么验证它真的接上了
4. 提醒我这类配置里哪些东西绝对不能提交进仓库
会话里敲 /mcp 可以看到当前接入了哪些服务和它们的状态。
第 4 点那个提醒很重要:MCP 配置里通常是连接串、token、账号密码。这类东西要么放 settings.local.json(自动被忽略),要么用环境变量引用,绝对不要写进共享的 settings.json。
第四步:配置分层,哪些共享哪些不共享
.codebuddy/
├── settings.json 团队共享:权限规则、允许/禁止的工具 → 提交
├── settings.local.json 个人覆盖:我自己喜欢的输出风格、本地路径 → 不提交
├── rules/ 项目规则 → 提交
├── agents/ 自定义子代理 → 提交
└── CODEBUDDY.md 项目记忆 → 提交
~/.codebuddy/
├── CODEBUDDY.md 我的个人偏好(所有项目生效) → 不提交
└── rules/ 我的个人规则 → 不提交
判断标准就一条:这条规矩换个人来还成立吗? 成立就提交,不成立就放 local。
比如"提交信息用 Conventional Commits"是团队约定 → 提交;"我习惯让它回答简短一点"是个人偏好 → 放 local。
检查一下有没有漏网的:
检查 .gitignore 是否正确忽略了 .codebuddy/settings.local.json
和任何含密钥的文件。然后用 git status 确认一遍:
现在待提交的文件里有没有包含密钥、token、本机绝对路径?
踩一次坑:写一堆正确的废话
对比一下两种规则写法。
没用的写法:
---
description: 代码规范
alwaysApply: true
---
# 代码规范
- 要写好代码
- 注意代码质量
- 遵循最佳实践
- 保持代码整洁
这四条它都会"遵守"——因为它本来就觉得自己一直在遵守。这类规则等于没写,还白白占上下文。
有用的写法:
---
description: Python 代码规范
paths: ["**/*.py"]
---
1. 所有公开函数必须有类型注解和 docstring
2. 禁止裸 `except:` 和 `except Exception: pass`
3. 文件路径一律用 `pathlib.Path`,不要字符串拼接
4. 单个函数不超过 50 行,超了就拆
5. 金额计算必须用 Decimal 或明确说明为什么用 float
每条都能一眼判断做没做到。判断不了的规则,就是无效规则。
还有一条经验:规则不要一次写太多。写 30 条规则,它每条都打折扣;写 8 条精准的,它每条都执行到位。先写最痛的那几条,跑一段时间再补。
Git:共享配置提交,个人配置忽略
git add .codebuddy/settings.json .codebuddy/rules .codebuddy/agents CODEBUDDY.md
git commit -m "chore: 建立项目级 AI 协作规范
- rules/:提交信息、测试、Python 风格、安全、git 工作流五条规则
- agents/code-reviewer:只读审查子代理
- settings.json:禁止读取 .env 与执行破坏性命令
- 个人偏好放 settings.local.json,已加入 gitignore"
平台差异:配置目录在哪
| 环境 | 用户级配置目录 |
|---|---|
| macOS / Linux | ~/.codebuddy/ |
| Windows PowerShell | %USERPROFILE%\.codebuddy\(通常是 C:\Users\你\.codebuddy) |
| WSL2 | ~/.codebuddy/(WSL 内部,和 Windows 侧不共享) |
WSL 和 Windows 各有一份用户级配置,不互通。项目级配置(.codebuddy/)因为跟着仓库走,两边都能读到——所以团队共享的东西一定要放在项目级,别放用户级。
另外,Windows 上做软链(ln -s)和 Unix 行为不一样。想把个人规则软链到项目里的话,Windows 上要用 mklink 或者直接复制,别指望 ln -s 能正常工作。
本章你多了什么
.codebuddy/rules/下五条可检查的规则- 一个只读的
code-reviewer子代理 - 一份权限与工具配置,敏感文件已被挡住
- 一套"什么该共享、什么该本地"的判断标准
本章新知识点
| 知识点 | 说明 |
|---|---|
| 规则比提示词可靠 | 写一次,之后每次都生效 |
| 规则要可检查 | 判断不了的规则等于没写 |
| 正反例子 | 给反例它就不会犯 |
paths 条件触发 |
不是所有规则都要常驻,省上下文 |
子代理的 tools 限制 |
只给只读工具,没有授予写文件和 Bash 工具 |
| 上下文隔离 | 子代理翻文件的"过程"不占主上下文 |
| 配置分层 | 团队共享 vs 个人偏好 |
延伸练习
- 再加一个
test-writer子代理,专门负责按规则写测试,并且让它只能用Write写tests/下的文件 - 写一条规则:改动数据库 schema 时必须同时检查 migrations 目录,看看会发生什么
- 把第 9 章那个 PR 审查工作流改成调用
code-reviewer子代理,对比一下输出质量
常见坑
规则写了很多,但感觉没生效。 检查三件事:frontmatter 语法对不对、文件路径是不是 .codebuddy/rules/、触发条件是不是没匹配上。可以让它自己确认:"列出你当前加载的所有规则"。
规则之间互相冲突。 比如一条说"函数要短",另一条说"不要把逻辑拆太散"。规则多了容易打架,定期让它检查一遍:"读一遍所有规则,找出互相冲突或重复的地方"。
子代理还是改了代码。 检查它的 tools 列表里有没有 Write / Edit / Bash(不带限制的 Bash 等于什么都能干)。
密钥被提交上去了。 每次提交前跑一遍那句检查:"待提交的文件里有没有密钥?"发现已经提交了,立刻改密钥——git 历史里的密钥删不掉,只能作废。
到这里,你已经能让它按你的规矩干活了。但规矩之外还有一层:在它动手之前和之后各插一道卡子,以及把整套做事方法打包成可复用的能力——那是 Plan 模式、子代理、Skills 和 Hooks 的事。
下一章就把这四个讲透,每个都配能直接抄走的配置。
规则验收:分别打开匹配 paths 的 pricing.py 与不匹配的文本文件,检查规则加载情况。子代理只给 Read、Grep、Glob;需要 diff 时由外部先生成后提供。规则和提示词不是系统访问控制,最终仍检查实际工具授权与文件差异。
13 四个被低估的能力
11.1 Plan:确认后再实施
在 billkit 的干净副本进入 Plan,请助手分析新增 CSV 导出的接口、影响文件与测试,先不实施。确认方案后退出 Plan,明确只授权第一步。工具限制以当前权限配置为准,提示词“不要写”本身不是安全沙箱。验收是计划与实际 diff 一致,不能只看回答。
11.2 子代理:给审查者最小工具
把 materials-cbc/06-power-features/agents/code-reviewer.md 复制到 .codebuddy/agents/。模板仅允许 Read、Grep、Glob,不允许 Bash(git:*);git reset、restore、clean 都可改文件。父流程先生成 diff 供审查,子代理返回文件、位置、触发条件和证据。实际创建/调用入口以本机 /agents 帮助为准;未出现代理时先检查加载目录与 frontmatter。
11.3 Skill:保存重复验收步骤
把配套 skills/billkit-check 复制到 .codebuddy/skills/,检查 SKILL.md 的 description 与测试入口。请求一次账单合同审查,核对是否读取规则、运行实际测试并如实报告已知失败。Skill 是可复用任务说明,不会自动赋予缺失权限,也不能保证模型每次严格执行;外部测试才是完成证据。
11.4 Hook:先独立测脚本,再接入
把配套 hooks/guard_command.py 放到 .codebuddy/hooks/。它是保守教学示例:所有 Bash 调用都阻断,非 Bash 允许;非法 JSON 返回 2,不默认放行。不使用“包含 /tmp 就允许删除”或字符串黑名单模拟完整 shell 安全边界。
在 .codebuddy/settings.json 合并(不要覆盖已有设置):
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "python3 .codebuddy/hooks/guard_command.py", "timeout": 15}]
}]
}
}
命令在项目根目录验证。Windows 或 python3 不存在时,将 command 改为已验证的解释器路径,按实际 Hook shell 转义;先手动输入有效事件测试,再启动 CodeBuddy。该示例依据 CLI Hook 的退出码协议:0 继续,2 阻断并反馈 stderr。其他非零不应被当作同等安全阻断。
验收三项:Bash 事件返回 2;非 Bash 返回 0;坏 JSON 返回 2。接入后请求一条无害的 echo,确认确实被拦截;测试结束移除这一教学 Hook 才能继续需要 Bash 的练习。它没有限制其他工具、MCP、网络和系统权限,不把它宣传成完整沙箱。
参考:CodeBuddy Code 文档。若版本字段变化,先按同一版本文档调整并重做三项验收。
14 桌面版与插件版
前面十章都在终端里。这一章换个场景。
不是说 CLI 不够好——而是它并不总是最合适的工具。用对工具的前提是知道每个工具擅长什么。
什么时候该从 CLI 切到桌面版
| 你在干什么 | 该用哪个 | 为什么 |
|---|---|---|
| 批量改几十个文件 | CLI | 脚本化、可重放、能接 CI |
| 接进流水线 / 定时任务 | CLI | 只有命令行能被调用 |
| 在服务器或容器里干活 | CLI | 没有图形界面 |
| 想看着 diff 一点点改 | Desktop / 插件 | 可视化 diff 比终端里读 patch 舒服得多 |
| 断点调试、看变量 | Desktop / 插件 | CLI 里你只能靠 print 和日志 |
| 从零做一个带界面的东西 | Desktop | 有预览,能边看边调 |
| 边写边要补全 | 插件 | 补全必须在编辑器里 |
| 设计稿转代码 | Desktop | 需要上传设计稿和可视图 |
一句话的判断标准:要"看"和"点"的,用桌面版或插件;要"批量"和"自动"的,用 CLI。
装 Desktop
macOS
- 打开官网下载页,下载 macOS 版安装包(.dmg)
- 双击打开,把图标拖进 Applications
- 首次打开如果提示"来自身份不明的开发者",去「系统设置 → 隐私与安全性」里点"仍要打开"
- 启动后按提示登录(和 CLI 一样的几种登录方式)
Windows
- 下载 Windows 版安装程序(.exe)
- 双击运行,按向导下一步
- 如果 SmartScreen 弹窗,点"更多信息 → 仍要运行"
- 启动后登录
Apple 芯片的 Mac 和 Intel 的 Mac 安装包不一样,下载时注意选对。不确定自己是哪一种:左上角苹果图标 → 关于本机,看"芯片"那一行。
WSL2 用户:Desktop 是 Windows 程序,装在 Windows 侧。它可以直接打开 WSL 里的项目目录——启动后选择"打开文件夹"时,WSL 的项目路径在 \\wsl$\Ubuntu\home\你\... 下面(或者在 WSL 终端里敲 explorer.exe . 直接用 Windows 资源管理器打开当前目录,再拖进去)。
界面长什么样
第一次打开你会看到三块区域:
- 左侧:文件树 + 会话列表
- 中间:对话区(和 CLI 里一样,用自然语言说需求)
- 右侧/下方:结果区——代码 diff、文件列表、预览
和 CLI 最大的区别有两个:
一是 diff 是可视化的。 CLI 里你看到的是文本 patch,这里你能看到并排的旧/新代码,能一行一行地点"保留"或"撤销"。改错了一行,不用整个推翻。
二是能真的调试。 它有运行环境,能打断点、看变量、看调用栈。CLI 里遇到复杂逻辑问题,你只能加 print 再跑一遍;这里可以直接停在那儿看。
同一个案例在 Desktop 里做一遍
我们把第 4 章那个"接手陌生仓库"在 Desktop 里重做一次,你就能感受到差别了。
第一步:打开项目。 启动 Desktop,选择"打开文件夹",选 ~/playground/legacy-repo(或你自己的项目)。
第二步:建记忆。 在对话框里输入:
/init
和 CLI 里完全一样。CODEBUDDY.md 会生成在同一个位置——这是关键:三端共享同一份项目记忆。
第三步:让它考古。
读一遍这个项目,告诉我它干什么、怎么启动、有哪些隐患。
先不要改代码。
第四步:看 diff。 让它修 Flask 那个 before_first_request 的问题。改完之后,右侧结果区会显示改动的文件列表,点进去能看到并排 diff。你可以逐行决定要还是不要。
对比一下两种体验:
| CLI | Desktop | |
|---|---|---|
| 建记忆 | /init |
一样 |
| 看改动 | git diff(文本 patch) |
并排可视化 diff,可逐行取舍 |
| 确认命令 | 弹一个 Y/n | 有命令执行面板,能看到完整命令再决定 |
| 验证启动 | 自己在终端跑 | 可以直接点运行、看输出、打断点 |
| 检查改动范围 | git status |
结果区直接列出所有被改的文件 |
哪个更好? 取决于你在干什么。这个案例里 Desktop 更舒服——因为你主要是在"看"和"验证"。但如果你的任务是"把两百个文件的 class 组件改成函数组件",CLI 的脚本化和可重放就是决定性的优势。
三端怎么配合
共享的部分:
CODEBUDDY.md 三端都读
.codebuddy/rules/ 三端都读
.codebuddy/settings.json 三端都读
.codebuddy/agents/ 三端都读
所以你在 CLI 里建立的规矩,切到 Desktop 里照样生效——这就是第 10、11 章那套配置最值钱的地方,它不绑工具。
具体说:项目级的 CODEBUDDY.md、.codebuddy/rules/、.codebuddy/agents/、.codebuddy/skills/ 三端都读。唯一的例外是 CodeBuddy 自己的 Hooks(第 11.4 节)——那是 CLI 运行时的机制,Desktop 有自己的执行环境,hooks 不一定会被触发。如果你依赖某个 hook 做安全拦截,跨端时要重新验证一遍,别默认它在那边也生效。
不共享的部分:
~/.codebuddy/CODEBUDDY.md 用户级,跟着机器走,但三端在同一台机器上都读
会话历史 CLI 的 /resume 和 Desktop 的会话列表是两套
会话历史不互通,这是当前的现实——你不能在终端里接着桌面版的会话继续聊。
我的实际用法,供你参考:
- 日常写代码:插件(在编辑器里补全和问答最顺)
- 批量改动、接 CI、服务器上干活:CLI
- 接手陌生项目、做原型、需要调试或预览:Desktop
- 项目规矩:写在
.codebuddy/里,三端共享
不需要忠诚于某一个。需要什么拿什么。
生态能力简介
Desktop 版有些能力是 CLI 没有的,简单提一下,用不用看你:
- 设计稿转代码:上传 Figma/图片设计稿,生成前端代码
- 后端集成:接 CloudBase、Supabase 这类托管后端,做带数据存储的应用
- 一键部署:做完直接发布成可访问的链接
- 可视化调试:前面说过了
这些能力面向的是"从零做一个能用的应用"这个场景,和 CLI 面向的"在既有代码库上干活"是两条路。
选择建议
| 你是谁 | 建议 |
|---|---|
| 后端 / 全栈开发者,日常在既有仓库里改 | CLI 为主,插件做补全 |
| 前端开发者,经常做界面 | 插件为主,Desktop 做原型 |
| DevOps / SRE | CLI,几乎不用别的 |
| 产品 / 设计 / 编程初学者 | Desktop |
| 学生 / 自学编程 | Desktop 入门,熟练后转 CLI |
如果你不知道选哪个:先用 Desktop(门槛最低),等你需要"批量改文件"或者"接进自动化"的时候,自然就会用到 CLI。到时候回来翻第 2、3 章就行。
常见坑
Desktop 里改了代码,CLI 里看不到。 不存在这个问题——同一个文件系统,同一份 git 仓库。只是两边的会话历史不互通。
规则在 Desktop 里没生效。 确认规则文件在 .codebuddy/rules/(项目级)而不是只有用户级。项目级的三端都读。
WSL 里的项目打开很慢。 可能是因为路径经过了网络映射。把项目放在 WSL 自己的文件系统里,通过 \\wsl$\... 路径打开,不要放在 /mnt/c/。
插件版和 Desktop 版冲突。 不冲突,它们是独立的。但同一个项目里三个工具同时改文件容易打架——同一时间只用一个工具改代码。
最后一章,把常用的东西整理成速查表。
15 速查表-模板-下一步
13.1 从问题找到入口
| 问题 | 回到哪里 |
|---|---|
| 安装、登录、版本与环境 | 第 1 章;先保存 codebuddy --version 与 --help |
| 上下文与会话 | 第 3 章;凭据不写进记忆 |
| 运行不了项目 | 第 4 章:目录、解释器、完整报错、最小修复 |
| 测试写完却没抓住缺陷 | 第 5~6 章:合同、边界与先红后绿 |
| 重构后行为变化 | 第 7 章:小步提交与特征测试 |
| 容器重建丢数据 | 第 8 章:DATABASE_PATH 与持久卷 |
| 自动化误报成功 | 第 9 章:独立测试退出码与真实差异输入 |
| 条件规则不触发 | 第 10 章:paths、alwaysApply 和实际匹配验证 |
| 子代理、Skill、Hook | 第 11 章与配套 06-power-features |
13.2 只保留一份模板
规则模板以第 10 章为准,使用 paths,不再重复 globs 旧模板。子代理、Skill、Hook 的可复制文件统一在 materials-cbc/06-power-features;修改后同时更新说明与验收。不要把其他产品同名配置直接复制过来。
13.3 完成课程的证据
保存:第 4 章健康检查、账单修复前后边界测试、第 7 章行为对比、短链重启持久化结果、提交 Hook 的失败拦截结果。标注本机产品版本和操作系统;未登录或未部署的步骤明确留为待验证。
13.4 下一步
选一个自己的小项目复用“契约—最小实现—独立验收—提交”的流程。一次只增加一个能力;先证明它解决实际问题,再增加插件或子代理。
16 进阶学习
这套 CodeBuddy 教程,从第 0 章就先把产品形态说清楚,再选择 CLI 作为主线。随后处理 macOS、 Linux、Windows PowerShell 和 WSL2 四种环境,带着读者跑通第一次对话,建立项目记忆,认识权限模式、上下文和会话。
真正有价值的部分,是后面的七个案例。
接手陌生仓库时,先准备独立副本,先复现,再只修启动问题。给没有测试的项目补测试时,先确定测试契约,还用独立 Worktree 做对比练习。从报错到修复时,先读现场但不修改,用真实数据复现, 挖出根因,先写失败测试,再改代码。
到了重构,教程要求先给外部行为留证据,只抽取一个有价值的边界,失败就回退。做短链服务时, 又把第一版契约、本地验收、容器持久卷和云端部署串起来。自动化章节也没有把 AI 审查当万能答案,而是先建立可重复检查,再区分暂存审查与分支审查,最后连自动化本身也要验收。
第 10 和第 11 章继续把规则文件、子代理、MCP、Plan、Skill 和 Hook 接进来。
所以如果真的走完这 14 章,你学到的已经不只是 CodeBuddy 怎么用。
你学到的是一套小型但完整的 AI 编程纪律。
先复现,再修复。先写失败测试,再改代码。先让外部行为留下证据,再重构。共享配置提交,个人配置忽略。Hook 脚本先独立测试,再接入工作流。
刚好在对抗 AI 编程最常见的诱惑。
看见代码出来,就以为任务完成了。
教程本身已经把这个坑堵得很严。可到了团队和企业项目里,难度会继续上升。
陌生仓库不再是一个练习项目,而可能有几百个模块、多个服务和多年历史。测试契约不再只覆盖账单或短链,而要处理跨系统接口、权限、数据迁移和兼容性。一个子代理做审查也不够,调研、实现、测试、安全与性能可能需要并行推进,还要避免不同 Agent 互相覆盖修改。
这时,项目记忆需要升级成仓库级工程知识。
项目怎样启动,常用命令是什么,目录如何分工,架构边界在哪里,哪些操作必须人工确认,哪些结果能机器验收。这些都需要被持续维护,而不是在每次新会话里临时解释。
Plan 也要升级成规格。
教程里让 CodeBuddy 先想清楚再修改。复杂项目里,还要把业务目标、非目标、接口、约束、风险和验收标准整理成 spec,再拆成 plan 和 tasks。否则计划写得再漂亮,也可能是在错误需求上认真执
行。
Skill 和 Hook 也要升级成团队资产。
个人 Skill 解决自己重复做的验收,团队 Skill 则要可读、可测、可版本管理。Hook 不只执行一个本地脚本,还可能承担格式、测试、安全和提交门禁。它们一旦进入多人协作,稳定性与可维护性就变得重要。
所以在这里,我们想向你推荐一门课程,「企业级 AI 编程实战营」。它承接的正是这层放大后的问题。
课程用 SDD 把需求转成 spec、plan 和 tasks,用 Harness Engineering 把项目规则、权限、环境、测试和验收变成 Agent 可以遵守的工程护栏。Subagents、Worktrees、Skills、Slash Commands、 Permission 和 Hooks,会在真实复杂项目里组合使用。
三个项目也刚好对应 CodeBuddy 教程已经触碰过、但规模更大的场景。
从零构建 AI 智能体操作系统,练系统底座和 Agent Runtime。开发分布式延时投递服务,练复杂系统设计、高可用和增量演进。对 Dify 做企业级二次开发,练大型陌生代码库理解与最小侵入改造。最后进入 mq9 开源项目协作,接受维护者的真实 PR review,实际是否合并以 review 结果为准。
扫码添加学习顾问,领取完整大纲和试听资料
