news 2026/10/3 7:08:35

为什么你的 Claude 正在把代码写成“屎山”?——用 CLAUDE.md 给 AI 编程补上架构地图

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么你的 Claude 正在把代码写成“屎山”?——用 CLAUDE.md 给 AI 编程补上架构地图

1. 为什么 Claude 会把代码写成“屎山”:AI 编程的“近视眼”缺陷

Claude 在大型代码库中写代码,本质上是一个“高度近视眼”在干活。它能把你当前打开的那个文件、那段函数写得漂漂亮亮,但它看不到整个项目的架构地图。你让它加一个键盘快捷键,它不会先去翻hooks/useButtonAction.ts里有没有现成的处理逻辑,而是直接在事件监听器里把按钮的handleClick逻辑复制一份。几周后产品改需求,你改了一处,另一处还是旧逻辑,Bug 就这么来的。

这不是 Claude 变笨了,而是它的工作模式决定的。当你通过工具让它读取文件时,它并不是像人类资深工程师那样先在脑子里建一张“Controller -> Service -> Repository”的立体图。它高度依赖关键词搜索——grep 到几个看起来相关的片段,认知闭环就完成了。社区里有个很准的观察:模型被训练成“找到即停止”的行为模式,它不会主动想“这个逻辑是不是已经在 utils 里封装过了”,它只看到眼前这几行,就地解决。结果就是局部最优、全局崩坏。

我试过在一个 3 万行的 React 项目里让 Claude 加一个“导出 CSV”的功能。它写得很快,代码也能跑。但后来我发现,项目里其实已经有一个exportToCSV的通用函数,在utils/export.ts里躺了半年。Claude 没找到它,因为它的搜索关键词是“download csv”,而那个函数叫exportToCSV。于是它重新写了一个,用了不同的分隔符处理逻辑,还引入了一个新的依赖。这就是典型的“隐形重复”——代码库像癌细胞扩散一样变胖,每个轮子都长得差不多但又不完全一样。

问题的根源在于:Claude 没有你的项目架构记忆。每次对话对它来说都是“第一次来这个代码库”。你可能会说,那我把它需要的文件都贴给它不就行了?但大型项目动辄几百个文件,上下文窗口再大也装不下。而且就算装得下,它也不会主动去建立文件之间的依赖关系图。它只会线性地读,然后在你指哪打哪。

所以破局的关键不是换一个更强的模型,而是给这个“近视眼”配一副眼镜,再给它一张导航图。这副眼镜就是CLAUDE.md,这张导航图就是架构地图。CLAUDE.md放在项目根目录,Claude 在每次任务开始前会优先读取它。你可以在里面写清楚:项目结构树、关键设计模式、必须遵守的编码规范、以及最重要的——“哪些东西绝对不能重复实现”。这相当于给 AI 设定了元指令,让它在生成代码时时刻受到约束。

接下来的章节,我会带你从零开始写一份可复制的CLAUDE.md模板,梳理代码库结构的具体步骤,以及如何用 TaoToken 统一通道接入 Claude 后验证输出是否贴合项目架构。你不需要是架构师,只要跟着做,就能让 Claude 从“近视眼”变成“带着地图干活”。

2. TaoToken 前置准备:统一通道接入 Claude 与 API Key 获取

在开始写CLAUDE.md之前,你需要先确保 Claude 能稳定地读到你的项目文件。很多开发者卡在这一步:要么是本地代理配置失败,要么是 API Key 权限不对,导致 Claude 根本没法通过工具读取代码库。这一章我用 TaoToken 作为统一接入通道,把 Base URL、API Key、Model ID 三件套配好,后面所有验证步骤都基于这个通道。

TaoToken 是一个面向开发者的模型接入平台,它把 Claude、GPT 等模型的 API 统一成一套兼容 OpenAI 格式的接口。你不需要分别去申请不同厂商的 Key,也不用担心某个通道突然不通。对于 AI 编程场景来说,它的价值在于:你可以在CLAUDE.md里写死模型调用规范,而 TaoToken 保证这个调用始终走同一个入口,不会因为底层通道切换导致行为不一致。

首先打开 TaoToken 官网https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,注册后进入控制台。在控制台左侧找到“API Keys”菜单,点击“创建新 Key”。建议给 Key 起一个能区分用途的名字,比如claude-code-arch,这样后面如果多个项目共用,你能快速定位是哪个 Key 在消耗额度。创建完成后,Key 只会显示一次,立刻复制保存到本地密码管理器或.env文件里。注意不要直接提交到 Git 仓库,后面我会在CLAUDE.md里写清楚如何通过环境变量引用。

接下来确认 Base URL。TaoToken 的 API 端点是https://taotoken.net/api,注意这个地址不带 UTM 参数,是纯 API 调用地址。如果你用的是 Claude Code 这类 CLI 工具,它通常要求你配置ANTHROPIC_BASE_URL或OPENAI_BASE_URL。以 Claude Code 为例,你需要在终端里设置:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的TaoTokenKey"

如果你用的是 Cline、Continue 这类 VS Code 插件,配置方式类似,在插件的设置里找到“Custom API Endpoint”或“Base URL”,填入https://taotoken.net/api,然后在 API Key 字段填入刚才创建的 Key。Model ID 根据你实际使用的模型填写,比如claude-sonnet-4-20250514或claude-opus-4-20250514。这里有个细节:不同工具对 Model ID 的格式要求不一样,有的要求带anthropic/前缀,有的直接写模型名。如果你不确定,可以先在 TaoToken 的“模型对话”页面测试一下,确认模型能正常返回再填到工具里。

配置完成后,不要急着写CLAUDE.md。先做一个最小验证:在终端里用 curl 发一个请求,确认通道是通的。

curl -X POST "https://taotoken.net/api/v1/messages" \ -H "Content-Type: application/json" \ -H "x-api-key: sk-你的TaoTokenKey" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 100, "messages": [{"role": "user", "content": "回复 OK"}] }'

如果返回的 JSON 里有content字段且内容包含“OK”,说明通道正常。如果返回 401,检查 Key 是否复制完整、是否有多余空格。如果返回local proxy failed,说明你的工具还在走本地代理,需要把代理配置关掉,直接指向 TaoToken 的 Base URL。这一步很重要,因为后面 Claude 读取CLAUDE.md和项目文件都依赖这个通道,通道不稳,架构地图再详细也没用。

最后,把 Key 和 Base URL 写进项目的.env.local文件(记得加入.gitignore),然后在CLAUDE.md里引用环境变量名而不是硬编码 Key。这样既安全,又方便团队其他成员用自己的 Key 接入。下一章我会给出完整的CLAUDE.md模板,包括项目结构树、共享服务清单、禁区列表,以及如何让 Claude 在每次任务前先读这张地图。

3. 可复制配置:CLAUDE.md 模板与架构地图梳理步骤

这一章是核心。我会给你一份可以直接复制到项目根目录的CLAUDE.md模板,然后带你一步步把代码库的结构梳理清楚,填进模板里。不要跳过梳理步骤直接抄模板,因为每个项目的架构不一样,模板只是骨架,填进去的内容才是让 Claude 不写“屎山”的关键。

先看模板。在项目根目录创建CLAUDE.md,内容如下:

# 项目架构地图与 AI 编码规范 ## 项目结构树 src/ ├── components/ # 纯 UI 组件,不含业务逻辑 ├── hooks/ # 通用 Hook,必须优先复用 ├── services/ # 业务逻辑层,所有 API 调用必须走这里 ├── utils/ # 工具函数,禁止在组件内重复实现 ├── pages/ # 页面级组件,只做组合和路由 └── types/ # 全局类型定义 ## 共享服务清单(禁止重复实现) - `utils/export.ts` 中的 `exportToCSV`:所有 CSV 导出必须调用此函数 - `hooks/useButtonAction.ts` 中的 `useButtonAction`:按钮点击逻辑统一走此 Hook - `services/auth.ts` 中的 `AuthService`:所有鉴权相关逻辑必须通过此类 - `components/Button.tsx`:所有按钮必须使用此组件,禁止原生 button ## 编码规范 - 禁止在组件内直接写 fetch/axios,必须通过 services 层 - 禁止复制粘贴已有逻辑,先搜索 hooks/utils/services - 新增依赖前必须检查 package.json 是否已有类似库 - 所有键盘快捷键必须复用对应的点击处理函数 ## 禁区 - 不要重新实现 exportToCSV - 不要绕过 AuthService 直接操作 token - 不要在 pages 层写业务逻辑

这份模板的关键在于“共享服务清单”和“禁区”两部分。Claude 在生成代码前会读这个文件,当它想写一个导出功能时,会看到“所有 CSV 导出必须调用 exportToCSV”,于是它就会去搜索这个函数而不是重新写一个。这就像给近视眼配了一副眼镜,让它能看到项目里已经有什么。

现在带你梳理自己的代码库。第一步,生成项目结构树。在终端里运行:

find src -type d -maxdepth 3 | sort

把输出整理成树形结构,填进CLAUDE.md的“项目结构树”部分。注意只列到第三层,太深了 Claude 也记不住。第二步,找出所有共享服务。用 grep 搜索export function和export const,重点看utils/、hooks/、services/三个目录:

grep -r "export function\|export const" src/utils src/hooks src/services --include="*.ts" --include="*.tsx" -l

把每个文件里的导出函数名和用途简要写进“共享服务清单”。比如utils/export.ts里有exportToCSV,就写“所有 CSV 导出必须调用此函数”。第三步,列出禁区。回顾一下过去三个月里 Claude 或你自己重复实现过哪些逻辑,把那些“本应该复用却重新写”的功能列进“禁区”。比如“不要重新实现日期格式化,用utils/date.ts里的formatDate”。

填完模板后,还需要在 Claude Code 或 Cline 的配置里确保它会读取CLAUDE.md。以 Claude Code 为例,它默认会读取项目根目录的CLAUDE.md,但你需要确认配置里没有禁用。如果你用的是 Cline,在插件的“Custom Instructions”里加上一句:“每次任务开始前,先读取项目根目录的 CLAUDE.md 并遵守其中的架构约束。”这样双保险。

另外,如果你用 Codex 或类似工具,它可能要求auth.json里配置 Base URL 和 Key。确保auth.json里的baseURL指向https://taotoken.net/api,apiKey引用环境变量。Model ID 填你实际用的 Claude 模型。这三件套(Base URL + Key + Model ID)在任何工具里都必须一致,否则 Claude 可能读不到CLAUDE.md就开始了,那架构地图就白写了。

配置完成后,不要急着让 Claude 写新功能。先做一个测试:让它“在pages/ProfilePage.tsx里添加一个导出用户列表的按钮”。观察它的行为。如果它先搜索exportToCSV并调用,说明CLAUDE.md生效了。如果它直接写了一个新的 CSV 拼接逻辑,说明它没读到或没遵守,你需要检查文件路径和工具配置。下一章我会给出具体的验证请求和成功结果对照。

4. 验证请求与成功结果:检查 Claude 输出是否贴合架构

配置写好了,但你怎么知道 Claude 真的在读CLAUDE.md并遵守架构约束?这一章我给你一套可执行的验证动作,包括具体的请求语句、预期输出、以及如何判断它是在“按地图走”还是在“重新发明轮子”。

先做一个基础验证。在 Claude Code 或 Cline 里输入:

请阅读项目根目录的 CLAUDE.md,然后告诉我:项目里 CSV 导出应该调用哪个函数?按钮点击逻辑应该走哪个 Hook?

如果 Claude 正确回答“CSV 导出调用utils/export.ts里的exportToCSV,按钮点击走hooks/useButtonAction.ts里的useButtonAction”,说明它已经读到了架构地图。如果它回答“我不确定”或给出错误答案,检查CLAUDE.md是否在根目录、文件名大小写是否正确、工具是否配置了读取该文件。

接下来做行为验证。输入一个真实任务:

在 pages/ProfilePage.tsx 里添加一个“导出用户列表”按钮,点击后下载 CSV。

观察 Claude 的思考过程和代码输出。成功的标志有三个:第一,它先搜索了exportToCSV或utils/export,而不是直接写Blob和URL.createObjectURL;第二,它调用了useButtonAction或至少复用了现有的按钮组件;第三,它没有在ProfilePage.tsx里直接写fetch或axios,而是通过services层获取数据。如果这三点都满足,说明架构地图生效了。

如果 Claude 还是写了重复逻辑,比如自己拼了一个 CSV 字符串,你需要检查两个地方。第一,CLAUDE.md里的“共享服务清单”是否写得太模糊。不要写“有导出功能”,要写“所有 CSV 导出必须调用utils/export.ts中的exportToCSV,该函数接受data: Record<string, any>[]和filename: string两个参数”。第二,工具是否真的把CLAUDE.md放进了上下文。有些工具需要你在对话开头手动@CLAUDE.md或运行/read CLAUDE.md。确认一下你的工具文档。

还有一个进阶验证:让 Claude 修改一个已有功能,看它会不会破坏架构。比如:

修改 useButtonAction,让它在点击时先上报埋点,再执行原逻辑。

成功的输出应该是:Claude 只修改hooks/useButtonAction.ts,不会去改每个调用它的组件。如果它跑到ProfilePage.tsx里加埋点代码,说明它没有理解“按钮逻辑统一走 Hook”这个约束。这时候你需要在CLAUDE.md的“编码规范”里加一条:“修改按钮行为时,只允许修改useButtonAction,禁止在调用方添加重复逻辑。”

验证通过后,你还可以用 TaoToken 的“模型对话”页面做交叉检查。把 Claude 生成的代码片段贴进去,问它:“这段代码是否符合 CLAUDE.md 中的架构约束?有没有重复实现已有服务?”TaoToken 的模型对话页面支持直接调用 Claude,你可以把它当成一个架构审查助手。如果它指出“这里应该调用 exportToCSV 而不是自己拼 CSV”,说明你的CLAUDE.md写得足够清晰,连另一个模型实例都能理解。

最后,把验证动作固化成流程。每次 Claude 完成一个任务后,你花 30 秒检查三件事:有没有新增重复函数、有没有绕过 services 层、有没有在错误的地方写业务逻辑。如果发现问题,立刻更新CLAUDE.md的“禁区”部分,把这次踩的坑写进去。这样架构地图会越来越准,Claude 的“近视眼”也会被矫正得越来越好。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

配置CLAUDE.md和 TaoToken 通道的过程中,你大概率会遇到几个报错。这一章我把最常见的四个错误和排查步骤列出来,每个都给出具体的终端输出和解决方法。你遇到问题时可以直接对照。

第一个错误:401 Unauthorized。完整报错通常是:

{"error":{"type":"authentication_error","message":"invalid x-api-key"}}

原因有三个:Key 复制不完整、Key 前后有空格、或者你用的 Header 名称不对。TaoToken 兼容 Anthropic 格式时用x-api-key,兼容 OpenAI 格式时用Authorization: Bearer。如果你在 Claude Code 里配置的是ANTHROPIC_API_KEY,但工具实际发的是 OpenAI 格式请求,就会 401。解决方法是检查工具的 API 格式设置。在 TaoToken 控制台的“API Keys”页面重新复制一次 Key,粘贴到终端里用echo $ANTHROPIC_API_KEY确认没有换行和空格。如果还是 401,换一个 Key 试试,排除 Key 本身被禁用的情况。

第二个错误:local proxy failed或connect ECONNREFUSED 127.0.0.1:7890。完整报错:

Error: connect ECONNREFUSED 127.0.0.1:7890 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1595:16)

这说明你的工具还在走本地代理端口。很多开发者之前配置过本地代理,环境变量里残留了HTTP_PROXY或HTTPS_PROXY。解决方法是清除这些变量:

unset HTTP_PROXY unset HTTPS_PROXY unset ALL_PROXY

然后在工具配置里确认 Base URL 直接指向https://taotoken.net/api,没有经过任何本地转发。如果你用的是 VS Code 插件,检查插件的“Proxy”设置是否为空。清除后重启终端和编辑器,再次请求。

第三个错误:reading choices或Cannot read properties of undefined (reading 'choices')。完整报错:

TypeError: Cannot read properties of undefined (reading 'choices') at parseResponse (openai-adapter.js:42:18)

这个错误通常出现在你用 OpenAI 格式的客户端去请求 Anthropic 格式的端点,或者反过来。TaoToken 的/api/v1/messages是 Anthropic 格式,返回结构是content数组;/api/v1/chat/completions是 OpenAI 格式,返回结构是choices数组。如果你在 Cline 里选了“OpenAI Compatible”但填了/api/v1/messages,解析时就会找不到choices。解决方法是确认端点路径和客户端格式匹配。Claude Code 用/api/v1/messages,Cline 的 OpenAI Compatible 模式用/api/v1/chat/completions。改对路径后错误消失。

第四个错误:OAuth相关报错,比如OAuth token expired或invalid_grant。完整报错:

Error: invalid_grant: Token has been expired or revoked.

如果你用的是 Claude Code 的 OAuth 登录模式,它默认会走 Anthropic 官方鉴权,而不是你的 TaoToken Key。你需要在 Claude Code 的设置里切换到 API Key 模式,或者设置环境变量ANTHROPIC_API_KEY并确保它优先于 OAuth。具体操作:运行claude config set --global apiKey sk-你的TaoTokenKey,然后重启 Claude Code。如果还是报 OAuth 错误,检查~/.claude/config.json里是否有残留的oauthToken字段,删掉它,只保留apiKey和baseURL。

排查完这些错误后,建议你做一个“最小可复现”测试:在一个空目录里只放一个CLAUDE.md和一个test.ts,用最简单的请求验证通道和文件读取都正常。确认无误后再回到大型项目里。这样能把配置问题和架构问题分开,避免在复杂环境里浪费时间。

6. 用 TaoToken 统一通道持续提升 Claude 代码质量

配置好CLAUDE.md和 TaoToken 通道后,你还需要一套持续维护的机制,否则架构地图会过期,Claude 又会慢慢退回“近视眼”状态。这一章我给你三个可落地的习惯,以及如何用 TaoToken 的不同入口分别处理排障、验证和长期编码任务。

第一个习惯:每次 Claude 完成一个功能后,花 2 分钟更新CLAUDE.md。如果它这次重复实现了某个逻辑,把那个逻辑写进“禁区”。如果它发现了一个你之前没列出的共享服务,把它补进“共享服务清单”。比如你发现utils/date.ts里的formatDate被 Claude 忽略了,就在清单里加一行:“所有日期格式化必须调用utils/date.ts中的formatDate,禁止使用new Date().toLocaleDateString()。”这样下次它就会先搜索这个函数。更新完CLAUDE.md后,不需要重启工具,Claude 在下一次任务开始时会重新读取。

第二个习惯:每周做一次“架构大扫除”。用 grep 找出最近一周新增的重复代码:

grep -r "function.*export\|const.*export" src --include="*.ts" --include="*.tsx" -n | sort

对比CLAUDE.md里的共享服务清单,看有没有功能相似但名字不同的函数。如果有,合并它们,然后更新清单。这个过程不需要 Claude 参与,你自己做更快。做完后把清理结果写进CLAUDE.md的“变更日志”部分(可以在文件末尾加一个## 变更日志),记录“2025-06-01 合并了三个重复的 CSV 导出函数,统一为 exportToCSV”。这样 Claude 下次读到时会知道这个函数是经过整理的,更倾向于复用它。

第三个习惯:用 TaoToken 的不同入口分流任务。排障和接入问题,比如 401、local proxy failed,直接去 TaoToken 的“API Keys”页面检查 Key 状态,或者看“接入文档”里的配置示例。验证模型输出是否贴合架构,用“模型对话”页面,把 Claude 生成的代码贴进去问它是否符合CLAUDE.md约束。长期编码和 Agent 任务,比如让 Claude 自动重构一个模块,用“Coding Plan”入口,它更适合多轮对话和长上下文任务。这三个入口的地址分别是:API Keys 在控制台左侧菜单,接入文档在官网导航栏,模型对话和 Coding Plan 在控制台首页。你不需要记具体 URL,登录 TaoToken 后都能找到。

最后,记住一个原则:CLAUDE.md是活文档,不是一次性配置。代码库在变,架构在演进,Claude 的行为也在更新。你每更新一次CLAUDE.md,就相当于给这副“眼镜”换了一次更准的镜片。坚持一个月,你会发现 Claude 生成的代码开始主动调用已有服务,而不是重新发明轮子。那时候你就不再是“搬砖工”,而是真正驾驭 AI 的架构师。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 7:07:41

OpenClaw技术架构与智能体:从网关到统一API的TaoToken接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 7:06:38

STM32F217ZG+DRV8818PWPR步进电机控制方案与工程实践

STM32F217ZG 配 DRV8818PWPR 这套组合&#xff0c;是我在定位平台和机器人项目里用得比较多的一套步进电机控制方案。一个负责出脑子&#xff0c;一个负责出大力&#xff1a;STM32F217ZG 作为主控生成 STEP/DIR 脉冲并跑加减速逻辑&#xff0c;DRV8818PWPR 作为专用步进驱动芯片…

作者头像 李华
网站建设 2026/10/3 7:06:08

基于DRV8818与MKV46的双极步进电机驱动控制方案详解

1. 项目背景与核心方案拆解1.1 双极步进电机在工业与机器人场景中到底难在哪双极步进电机和单极电机最大的区别在于绕组结构&#xff1a;双极电机每组绕组只有两根线&#xff0c;驱动时必须由H桥电路换向&#xff0c;让电流可以正反两个方向流过绕组。这意味着驱动器至少要两个…

作者头像 李华