
手头刚把 office2pdf 这个项目的 CLAUDE.md 规则文件整理完正好趁着热乎劲儿把整个思路沉淀下来。office2pdf 这名字很直白就是把 Office 文档Word、Excel、PPT批量转成 PDF 的转换服务而 CLAUDE.md 是给 AI 编程助手读的项目规则文件。这俩放在一起本质上就是一件事怎么把能跑的代码变成别人或者 AI也能安全维护的工程。我在维护这个项目的大半年里踩了不少坑从 LibreOffice 无头模式的字体设置到并发转换时内存爆炸再到后来引入 CLAUDE.md 后 AI 生成的代码风格终于稳定统一每一步都有值得记录的细节。这篇文章既是项目复盘也是写给两类人看的一类是想自己搭 Office 转 PDF 服务的开发者另一类是正在纠结到底要不要给项目写 CLAUDE.md、写了又该怎么写的团队。两部分内容我会穿插着讲因为对我来说它们其实是同一件事——把隐性规则显性化。1. office2pdf 到底在解决什么问题1.1 一个看似简单却处处是坑的需求Office 转 PDF听起来不就是另存为一下吗但在服务端做这件事复杂度完全不在转换本身而在稳定性、保真度和资源管理上。我接到这个需求时业务方的原话是帮我把销售团队每周交上来的提案、报价单、行业报告统一转成 PDF方便归档和发给客户。当时我心想这不简单给服务器装个 LibreOffice写个脚本循环调用不就完了。结果真正做起来才发现文档里用到的字体服务器上没有转换后中文全变成方块一个 200 页带复杂样式的 PPT转出来排版全乱转换进程偶发崩溃任务队列里的文件卡死多个转换任务同时跑服务器内存直接被打爆所以 office2pdf 项目从来不是一个转换脚本而是一个健壮的文件处理服务。它涉及文件上传、格式检测、任务排队、并发控制、转换执行、文件清理、错误重试、结果回调等多个环节。你在设计架构时至少要把它当成一个会吞掉各种奇怪输入的消息处理系统来对待而不是一个简单的工具函数。1.2 典型应用场景盘点我梳理了一下实际使用中最高频的几个场景基本可以覆盖大多数团队对 office2pdf 的需求在线预览浏览器不能直接渲染 docx / pptx统一转成 PDF 后通过pdf.js或浏览器内置 View 预览省去为每种 Office 格式单独做解析器的成本文档归档合同、方案、报告等需要长期保存PDF 的版式固定性远强于 Office 格式转完后可以作为唯一可信版本邮件附件处理把多份 Office 文档合并转成一个 PDF 再作为附件发送客户不需要安装 Office 也能查看内容安全管控转为 PDF 后可以做水印、加密、权限控制防止原始文档被随意编辑你会发现这些场景有一个共同点使用者并不关心 Office 源文件的编辑能力只关心最终看到的内容是否完整、准确、美观。这就是 PDF 作为内容交换格式的价值——它在几乎所有设备上的渲染结果都是一致的。1.3 项目范围的边界划分在写 CLAUDE.md 之前我做的第一件事是明确项目的边界。这不是文档形式主义而是为了后续所有开发决策有一个判断基准。我给 office2pdf 划定的边界是核心能力接收 Office 文件输出 PDF 文件输入范围.doc、.docx、.xls、.xlsx、.ppt、.pptx输出要求尽可能与 Office 中的排版一致字体嵌入页面尺寸正确非目标不做文档内容解析、不做 OCR、不做 PDF 编辑、不做格式间的任意转换这个边界很重要。因为在后续开发中会不断有人提能不能顺便把 PDF 转回 Word或者能不能顺便提取一下文档里的文字做全文搜索。有了明确的边界你就可以礼貌地拒绝或者把它们拆成独立项目而不是让一个转换服务变得越来越臃肿。2. CLAUDE.mdAI 时代的项目规则文件2.1 它是给谁看的CLAUDE.md 这个名字来自 Anthropic 的 Claude Code——一个能在终端里运行的 AI 编程助手。它的工作方式是读你项目里的文件、理解代码结构、帮你实现功能。但 AI 再聪明它对你的项目是陌生的不知道你习惯怎么组织代码、测试要跑什么命令、目录结构有什么约定。CLAUDE.md 就是你写给 AI 看的项目操作手册。说白了这和我们团队之前写新人入职文档是一个思路。新人第一天来不可能自己把代码库全读完才动手你需要给他一份快速上手指南构建命令是什么、代码风格如何、哪个目录放什么、踩过哪些坑要注意。CLAUDE.md 就是给 AI 新人的那份入职文档只不过它的读者是 Claude、Cursor、Copilot 这类编程助手。2.2 为什么一个转换小服务也需要项目规则你可能觉得office2pdf 这种项目总共没几个文件AI 看一眼就懂了写 CLAUDE.md 是不是小题大做我一开始也是这么想的直到我让 AI 帮我加一个队列深度上限配置它自作主张把整个系统从同步处理改成了异步架构——虽然功能没错但风格和现有代码完全不一致测试也全没跑过。那一刻我明白了AI 最缺的不是能力而是约束。一个没有规则文件的项目AI 每次生成代码都是一次自由发挥代码风格飘忽不定实现路径五花八门。而 CLAUDE.md 就是给这套自由发挥戴上枷锁让它在你划定的轨道上干活。具体到 office2pdf 这种工程项目CLAUDE.md 至少要解决这几个问题告诉 AI不要重新发明轮子转换引擎已经选定不要引入新的依赖告诉 AI构建和测试的命令格式让它改完代码后自己验证告诉 AI异常处理的约定比如转换失败时是重试还是直接丢弃告诉 AI代码风格的偏好对齐项目里已有的写法2.3 CLAUDE.md 与 AGENTS.md 的关系这里多说一句目前市面上有几种类似的约定文件AGENTS.md 是比较通用的一种Claude Code 认 CLAUDE.mdCursor 认.cursor/rulesGitHub Copilot 认.github/copilot-instructions.md。如果你在维护一个开源项目又希望不同 AI 工具都能读我的建议是以 CLAUDE.md 为主里面加上一句本文件同时适用于所有 AI 编程助手请遵循其中的规则然后通过软链接或复制生成一份 AGENTS.md。我在 office2pdf 里就是这么做的虽然没有硬性证据 AI 一定都读但至少把姿态摆出来了。3. 一份合格 CLAUDE.md 的骨架与编写要点3.1 先看一个精简的目录模板我给 office2pdf 写的 CLAUDE.md 大概有 120 行不算长但每一行都有信息量。它的结构大致是这样的# office2pdf 项目规则 ## 项目概述 两句话说明项目做什么、技术栈、核心约束 ## 常用命令 - 安装依赖: pip install -r requirements.txt - 运行服务: python app.py - 运行测试: pytest tests/ -q - 格式化: black src/ - 类型检查: mypy src/ ## 目录结构 说明 src / tests / data / output 各自放什么 ## 技术约束 - 转换引擎固定使用 LibreOffice headless 模式 - 禁止直接调用 Office COMWindows 依赖 - 文件处理必须走统一的转换队列 - 临时文件必须在使用后清理 ## 代码风格 - 类型标注必须完整 - 错误处理使用自定义异常体系 - 日志使用 logging 模块禁止 print ## 测试要求 - 新增转换格式必须补集成测试 - 测试夹具放在 tests/fixtures/ - 禁止把大文件10MB放入测试夹具 ## 常见坑 - 字体缺失导致中文乱码 - 高并发下 soffice 进程内存泄漏 - 文件路径包含空格和中文3.2 每个段落要回答什么问题写 CLAUDE.md 时我有一个原则每一段都要回答 AI 读了之后会问的一个具体问题。项目概述回答的是我是谁、我在哪、做什么——AI 需要先对项目建立整体认知才能避免做出方向性错误。常用命令回答的是我怎么验证代码是对的——AI 改完代码如果不知道跑什么测试它就不会主动验证。技术约束回答的是我能用什么、不能用什么——这是最容易让 AI 跑偏的部分它可能会因为觉得 LibreOffice 不好用而擅自换成别的方案。代码风格回答的是我写出来的代码应该长什么样——让 AI 生成的代码和已有的代码混在一起时不突兀。常见坑回答的是这个项目哪里容易翻车——这些都是你实际踩过的坑AI 看不到这些历史教训但它读了文档就能提前避开。3.3 编写中容易犯的三种错误第一写得像读书笔记而不是执行手册。有人会把 CLAUDE.md 写成本项目是一个基于 Flask 的文档转换服务支持多种格式……这种废话。规则文件里的每句话都应该能约束 AI 的某个具体行为而不是描述性的信息。第二规则太多太琐碎。如果 CLAUDE.md 几千行AI 的上下文窗口有限真正关键的规则反而可能被遗漏。我的经验是控制在 150~200 行为宜只写那些不遵守就会出问题的规则。第三只写规则不写原因。同样一条禁止使用 print 调试如果你加一句项目日志统一走 logging方便采集到 ELKAI 遵守的意愿和准确度都会明显提升。规则原因是黄金组合。4. office2pdf 核心实现转换方案选型与对比4.1 四大路线的优劣分析如果要自建 office2pdf转换引擎的选择是第一个要做的决定。我调研了四类路线简单说说它们的取舍。LibreOffice headless 模式我最终选用的方案通过soffice --headless --convert-to pdf命令行完成转换支持几乎所有 Office 格式免费开源跨平台。缺点是每次启动 soffice 进程有冷启动开销需要常驻服务模式来优化复杂文档的排版保真度与 Office 原生有差距。Apache POI Apache PDFBox纯 Java 生态不需要安装任何 office 软件POI 负责解析 Office 文件结构PDFBox 负责生成 PDF。但这个路线的工程量非常大需要自己处理段落、表格、图片、样式等等维护成本极高一般只适合对特定格式做深度定制的场景。Aspose / Spire 等商业库转换保真度最好API 设计也友好但需要购买授权商用成本不低。如果你的业务对排版还原度有硬性要求且预算充足这个路线最省心。调用 Office 的 COM 自动化Windows 上保真度最高因为就是 Office 自己导出的 PDF。但强依赖 Windows 环境服务端不能部署在 Linux 上而且稳定性差Office 弹个更新对话框就能让转换挂掉。我推荐你做一个简单的决策矩阵把成本、平台兼容性、保真度、维护复杂度四个维度列出来按项目实际需求打分。对大多数服务端场景来说LibreOffice 是性价比最高的选择这也是我最终选它的原因。4.2 LibreOffice 常驻服务的必要性和配置一开始我用的是每次转换都调用一次 soffice的方式简单是简单但性能很差。一个 10MB 的 PPT 转 PDF光启动 soffice 就要 5 秒加上转换时间总共要 15 秒左右。后来我改成了常驻监听模式启动一个soffice --headless --acceptsocket,hostlocalhost,port2002;urp;进程然后用 UNO API 通过 socket 连接它做转换冷启动时间直接降为 0。但也有代价常驻进程如果被某些文档搞崩溃了所有后续请求都会失败。所以我在代码里加了一个 watchdog定期发一个健康检查随便转一个内置小文档如果超时或报错就直接 kill 掉重启。这个逻辑一定要有否则线上会出莫名其妙所有转换都失败的诡异事故。配置方面有几个参数值得注意soffice --headless --convert-to pdf --outdir /tmp/output input.docx如果遇到字体问题需要修改 LibreOffice 的字体配置或安装系统字体如果并发量上来了可以考虑用--env:UserInstallationfile:///tmp/lo_profile隔离用户配置目录避免多实例冲突。这两个细节我在后面的排查部分细说。4.3 服务层架构把转换包成可扩展的流程单纯的转换引擎只解决了文件从 A 变 B一个可运营的转换服务还得包一层。我的架构分四层接口层HTTP API接收上传文件和参数返回任务 ID队列层内存队列 多消费者线程或者 Celery / RabbitMQ控制并发度执行层调用转换引擎处理生命周期存储层输入文件的临时存储、输出 PDF 的持久化存储代码上用 Python FastAPI 的话核心执行流程大概是这样的app.post(/convert) async def convert(file: UploadFile, output_format: str pdf): task_id str(uuid.uuid4()) input_path save_to_temp(file) queue.put((task_id, input_path)) return {task_id: task_id, status: queued} def worker(): while True: task_id, input_path queue.get() try: output_path converter.convert_to_pdf(input_path) notify_callback(task_id, output_path) except ConversionError as e: record_failure(task_id, str(e)) finally: cleanup_temp_files(input_path, output_path)这里注意几个设计任务 ID 是幂等的关键回调通知用异步方式避免阻塞临时文件必须在 finally 里清理。我第一次上线时忘了清理临时文件结果 /tmp 被撑爆整个服务挂了教训很深刻。5. 实操构建一个带队列与重试的转换服务5.1 FastAPI 脚手架与目录规划如果从零开始搭我建议项目结构直接规划成下面这样后面扩展不会痛苦office2pdf/ ├── app/ │ ├── main.py # FastAPI 入口 │ ├── config.py # 全局配置并发数、超时、存储路径 │ ├── converter/ │ │ ├── base.py # 转换器抽象接口 │ │ ├── libreoffice.py # LibreOffice 实现 │ │ └── registry.py # 格式路由docx-pdf, xlsx-pdf... │ ├── queue/ │ │ ├── manager.py # 队列管理 │ │ └── worker.py # 消费线程 │ ├── models/ │ │ └── task.py # 任务状态模型 │ └── storage/ │ ├── temp.py # 临时文件管理 │ └── output.py # 输出文件管理 ├── tests/ │ ├── fixtures/ # 测试用文档 │ ├── test_api.py │ └── test_converter.py ├── CLAUDE.md ├── requirements.txt └── README.md目录规划至少要满足两个目的第一业务代码之间解耦队列、转换、存储各自独立替换任何一个实现都不影响其他第二边界清晰AI 拿到这份 CLAUDE.md 后能快速定位我要改的是哪个模块不会在错误的位置用力。5.2 队列设计并发数、重试与超时队列是整个服务的核心这块设计不好其他部分再稳都没用。我用的是一套简化版设计但思路可以复用到任何任务队列系统上。并发控制LibreOffice 常驻进程是单例的多个转换同时打进去会排队甚至报错。我用一个信号量threading.Semaphore(4)控制同时进行的转换任务数。这个 4 是压测出来的4 个并发时 CPU 和内存都还在合理范围吞吐量也最大。并发数不是越大越好要根据服务器配置和文档大小实测。重试策略转换失败不一定是永久错误比如网络抖动导致临时文件没下载完或者 soffice 进程刚好在 restart。我的重试逻辑是前两次间隔 2 秒、5 秒第三次失败就直接标记失败放进死信队列。超过重试次数的任务不能无限堆积死信队列可以留着人工排查。超时控制一个 200MB 的诡异文档可能转换 10 分钟不结束必须设置超时。LibreOffice 命令行模式可以用--convert-to pdf --outdir /tmp/out input.docx sleep 60; kill %1这种粗糙方式更优雅的是用subprocess.run(..., timeout120)给进程加外部超时。超时后把进程和它的子进程全部杀掉否则僵尸进程会占着资源不放。5.3 环境兼容性Windows、Linux、Docker我强烈建议直接用 Docker 打包因为 LibreOffice 的依赖链太复杂了不同系统上安装方式和版本差异很大。我踩过一个坑本地 Ubuntu 20.04 上装好的 LibreOffice 转换正常一到 CentOS 7 的服务器上就缺各种系统库而且字体渲染效果也不一样。Dockerfile 里核心的是这几步FROM python:3.11-slim RUN apt-get update \ apt-get install -y --no-install-recommends libreoffice-core \ libreoffice-writer libreoffice-calc libreoffice-impress \ fonts-noto-cjk fonts-noto-color-emoji \ rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app/ /app/ WORKDIR /app CMD [python, main.py]注意fonts-noto-cjk这个包没有它中文社区文档转换出来就是满屏方块。具体的字体问题我在下一节展开。5.4 接口设计细节接口层有几个容易被忽略但实际很重要的细节文件大小限制必须设置上传文件大小上限我用的是 50MB。没有限制的接口会被恶意或误操作的大文件拖垮。格式白名单接收文件时只允许扩展名在.doc, .docx, .xls, .xlsx, .ppt, .pptx列表里的文件其他一律拒绝。不然有人传个.exe进来你的转换器会尝试用 LibreOffice 打开它轻则报错重则被利用。异步化转换是耗时操作接口不能同步等待结果。我采用提交任务 - 返回 task_id - 客户端轮询或接收回调的模型。回调 URL 由客户端上传时指定任务完成后服务端主动 POST 通知避免客户端频繁轮询浪费资源。class ConvertRequest(BaseModel): callback_url: str | None None priority: str normal # high / normal / low class ConvertResponse(BaseModel): task_id: str status: str5.5 别忘了写测试CLAUDE.md 里强调测试要求不是空话因为这类项目的回归风险非常高。一次 LibreOffice 升级可能导致所有旧文档的转换效果变化测试就是你的安全网。我的测试分三层单元测试队列逻辑、文件路径处理、超时判断等不涉及真实转换的纯逻辑集成测试真实调用转换引擎用一个小型 docx 转 PDF 验证流程跑通快照对比每次变更后固定转换一组标准文档对比 PDF 页数和关键文本是否一致用pypdf提取文本做断言最后这层做个简单的页面数断言就够了assert page_count expected_pages。太精细的像素级比对维护成本太高做成可选的人工巡检更现实。6. 常见问题排查与避坑实录6.1 中文乱码与字体缺失这是 office2pdf 项目里遇到最多的一个问题说白了就是转换环境没有目标字体。你 Windows 上做的文档用的微软雅黑服务器 Linux 上没有LibreOffice 只能找一个替代字体替代效果通常很糟糕。排查思路分三步先确认服务器上装了哪些字体fc-list | grep -i yahei\|noto\|simsun确认 Office 文档里用的字体名用unzip -p document.docx word/fontTable.xml查看在服务器上安装对应字体路径一般是/usr/share/fonts/装完执行fc-cache -f刷新经验之谈直接装上 fonts-noto-cjk 只能解决一部分问题。如果业务方大量使用特定字体比如方正小标宋、微软雅黑、宋体你需要手动把字体文件拷到服务器并注册。我在 Dockerfile 里加了一步COPY fonts/ /usr/share/fonts/custom/ RUN fc-cache -f6.2 格式错位转出来和 Word 里不一样这种问题的根因通常是字体的度量metrics不同导致字体换行位置变化段落排版跟着偏移。严格来说这很难 100% 解决但要尽量靠近。我的做法有几个优先使用 LibreOffice 7.x 以上版本低版本的渲染引擎弱不少转换时指定--infilterMicrosoft Word 2007-2019 XML (.docx)让 LibreOffice 用正确的解析过滤器对于 PPT可以在调用时加上--convert-to pdf:impress_pdf_Export指定导出配置如果客户反馈某份文档转完和源文件差距很大先确认是不是字体问题再确认是不是 LibreOffice 本身对某些复杂样式支持不佳。遇到这种极端情况我的方案是单独微调该文档而不是改全局配置。6.3 高并发下的内存与稳定性LibreOffice 常驻模式虽然解决了冷启动问题但内存管理并不完美。我压测时发现连续转换几十个大文件后soffice 进程的 RSS 内存肉眼可见地涨不及时处理就会崩。对策有三板斧定期重启每晚低峰期自动重启一次 soffice 进程把内存打回初始状态内存上限监控用psutil监控 soffice 的 RSS超过阈值比如 1.5GB就主动重启失败自动恢复如果某个文档导致 soffice 进程崩溃必须能自动拉起新进程并重新排队任务代码上我在 worker 里包了一层def safe_convert(task): for attempt in range(3): try: return self.converter.convert_to_pdf(task) except ConverterCrashError: self.converter.restart() continue raise ConversionError(soffice crashed 3 times)6.4 文件路径、权限与清理很多转换失败不是转换器的问题是文件系统的问题。我整理过一份清单路径含空格LibreOffice 命令行传参时路径必须用引号包裹否则会被解析成多个参数路径含中文确保环境变量LANG或LC_ALL为 UTF-8否则文件路径里的中文可能乱码导致找不到文件临时目录权限运行服务的用户对/tmp和输出目录要有写入权限用 Docker 时尤其注意挂载卷权限文件清理不清理临时文件是最大的隐患建议用tempfile.NamedTemporaryFile(deleteFalse)创建然后在finally里删除再加一个定期任务扫掉超过 24 小时的残留文件7. CLAUDE.md 中的项目规则如何真正落地7.1 一个反例没有规则文件时的 AI 代码说回 CLAUDE.md。为了让你直观感受规则文件的价值我拿真实发生过的一次对话举例。当时我没有写规则让 Claude 给 office2pdf加一个转换超时时间配置项。它给我的方案是# AI 生成的自由发挥版本 def convert_with_timeout(file, timeout120): # 先用 pdf2image 把文档渲染成图片不等等 # 我应该用 subprocess 调 soffice但需要处理更多 edge case # 要不我可以先检查文件类型 import mimetypes ...这个回答在功能方向上是对的但暴露了很多问题它引入了一个项目里从未用过的库mimetypes没有遵循已有的异常处理模式也没有跑测试就交差了。原因很简单——它不知道项目的规则只能按它训练数据里的普遍常识来写。7.2 有了规则文件之后的效果写上 CLAUDE.md 之后同样的需求变成这样它先读取 CLAUDE.md 里的技术约束转换引擎固定是 LibreOffice、自动日志、类型标注、跑测试然后给出的实现就靠谱得多——在我已有的config.py里加字段复用既有的converter抽象报错抛我自定义的ConfigError最后还会主动说我跑一下pytest tests/ -q验证。当然AI 也不是读了规则就完美但规则文件把错误的发生率从很高降到了偶发这个差距已经足以影响你是否敢让 AI 参与项目维护了。我的判断标准是如果 AI 按规则做即使有错错误类型是可预期的、可 review 的如果不按规则做那几乎是不可预期的。7.3 规则的按需更新把踩坑沉淀回文档CLAUDE.md 不是一次性写完就完事的。我每踩一个新的坑只要这个坑对后续开发有约束价值就会补进常见坑一节。比如有一次我发现并发数从 4 调到 8 之后soffice 反而更容易崩溃而且整体吞吐量没提升于是在 CLAUDE.md 里写了一条硬性规则并发转换数不得超过 4具体压测数据见 docs/concurrency-test.md。这种坑 - 规则 - 文档的闭环让 CLAUDE.md 成为项目中的活文档。它记录的每一行都不是拍脑袋想出来的而是真实发生过、需要被约束的。这也是我推荐每个项目都写 CLAUDE.md 的核心原因——它强制你把项目的隐性经验变成显性规则这对人、对 AI 都有价值。7.4 结合具体场景CLAUDE.md 里还有哪些值得补充的内容除了前面提到的 6 个核心段落我在实际使用中还加了几个补充块供你参考安全约定部分明确转换过程中不执行文档内嵌宏不解析文档里的外部链接避免引入安全风险。生产环境说明部分写清楚生产环境是 Docker 部署、监听端口、日志位置AI 做运维类改动时不会瞎改。CI/CD 流程部分告诉 AI 提交前跑pre-commit格式和 Lint 不过不能提交这样 AI 生成的代码一开始就能过 CI。我还加了一段业务语义约定比如任务状态流转只能是 queued - processing - done/failed防止 AI 随意扩展状态枚举导致回调逻辑混乱。这类约束对小项目可能多余但对要长期演进的项目越早写越省心。8. 一些小习惯让项目规则文件持续保鲜最后分享几个我实际操作中养成的习惯不一定适合所有团队但效果确实不错。第一给 CLAUDE.md 写个变更日志。每次增删规则都记录一行日期变更原因这样你回看的时候能清楚地知道为什么有这条规则。三个月后你看到禁用并发数 4这条如果没有变更日志可能已经想不起当初压测的结论了。第二把反向约束也写进去。所谓反向约束就是明确告诉 AI这个项目不适合做什么。我在 office2pdf 里写了一条本服务不负责转换 Excel 中的图片提取不建议在此项目内实现该功能请推荐到独立 OCR 服务。AI 有时会过度发挥反向约束能有效拦住它。第三定期审视规则是否过时。我每个季度会过一遍 CLAUDE.md删除已经不成立的规则更新技术选型决策。比如最初我写了禁止使用任何新依赖但后来为了性能优化引入了psutil就需要同步更新这条规则。规则文件和代码一样不维护就会腐烂。我记得有一次团队新增了一个同事专门负责 office2pdf他上手第一天看完代码后问我这个项目怎么这么多规矩。我让他先按规矩跑一遍测试他跑完回来跟我说了句这些规矩保住了我一下午的头发。这个反馈比任何开发方法论都让我欣慰。如果你也在维护类似的文档转换项目或者正打算把 CLAUDE.md 引入团队工作流我的建议是从小做起先写下构建命令、测试命令、三条最重要的技术约束然后让 AI 在项目里改一个小功能试试。你会直观感受到当 AI 不再靠猜来干活时它才真正变成一个靠谱的同事。