我发现了Claude Code的一个"坏习惯":为什么它总是写硬代码(hard-code)?
Claude Code总是生成硬编码?研究显示40%的AI代码存在质量问题。根本原因:Claude被设计为"不强加观点"的工具,加上LLM的健忘特性。解决方案:使用规划模式、配置CLAUDE.md文件、采用"ultrathink"关键词。虽然无法100%解决,但能显著改善代码质量
故事开始于一个令人抓狂的下午
上个月,我用Claude Code帮我写了一个数据处理脚本。看起来很完美,测试也通过了。结果第二天换了台电脑,程序直接崩了——原来Claude把我电脑的绝对路径/Users/张三/Desktop/data.csv
直接写死在代码里了!
这不是个例。我开始在各个技术论坛挖掘,发现几乎每个使用Claude Code的开发者都遇到过类似问题。有人说:"Claude就像个急性子的实习生,总想最快完成任务,但从不考虑代码以后怎么维护。"
什么是"硬编码"?为什么它这么讨厌?
想象一下,你在写一个购物网站。硬编码的做法是这样的:
// 糟糕的硬编码例子
const price = 99.99; // 价格写死了
const apiUrl = "https://api.mystore.com/products"; // API地址写死了
const maxItems = 10; // 购物车上限写死了
这样做的问题是:如果你想改价格、换服务器、或者调整购物车上限,就得改代码。更要命的是,如果这些值散布在100个文件里,你可能要改100次!
好的做法应该是这样:
// 聪明的参数化做法
const price = config.productPrice; // 从配置文件读取
const apiUrl = process.env.API_URL; // 从环境变量读取
const maxItems = settings.cart.maxItems; // 从设置文件读取
这样,你只需要改配置文件,代码本身不用动。就像电视遥控器一样,你不用拆开电视机就能换台。
Claude为什么会有这个"坏习惯"?
原因1:它是个"直男"思维
Claude Code被设计成一个很"纯粹"的工具。用官方的话说,它是"底层的和不强加观点的"^[1]^。翻译成人话就是:它不会主动纠正你的编程习惯,也不会擅自做主。
这就像给你一把锤子,它不会告诉你怎么用,也不会阻止你用锤子砸玻璃。自由度很高,但也意味着你得自己负责。
原因2:它有"健忘症"
这里有个有趣的事实:Claude其实不会"记住"你们之前聊了什么^[2]^。每次对话,它都要从头读一遍整个聊天记录。想象一下,每次见面你都要重新自我介绍——就是这种感觉。
所以当你在对话开始时说"记住,不要写硬编码",聊到第10轮时,这个指令可能就"淹没"在大量信息中了。
原因3:它学的就是这样
Claude是通过阅读互联网上的大量代码学习编程的。问题是,网上有太多演示代码和教学例子都使用硬编码,因为这样最简单直接。Claude学到的就是:"大多数人都这么写,所以这样是对的。"
就像小孩看到大人都在用手机,就觉得吃饭时玩手机是正常的。
社区大神们是怎么解决的?
我在网上搜集了一圈,发现了一些很有意思的解决方案:
方案1:强制它"三思而后行"
用户@PrajwalTomar的经验^[3]^:每次让Claude写代码前,先按Shift+Tab
进入"规划模式",让它先想清楚再动手。
他说:"这个方法帮我消除了90%的bug和垃圾代码。"
这就像你去宜家买家具,先在纸上画好房间布局,再去挑选,而不是看到什么好看就买什么。
方案2:给它写个"行为守则"
创建一个叫CLAUDE.md
的文件,把你的要求写得清清楚楚^[1]^:
# 编程铁律
- 绝对不允许硬编码任何路径、网址、密码
- 所有配置都要用环境变量或配置文件
- 如果你不知道某个值,就问我,别自己瞎猜
# 举个例子
好的做法:filename = os.getenv('INPUT_FILE')
坏的做法:filename = '/home/user/data.txt'
这就像给新员工发一份工作手册,让它知道公司的规矩。
方案3:让它"使劲想想"
有个神奇的发现:如果你在提示中加上"ultrathink"这个词,Claude会分配更多"脑力"来思考问题^[4][5]^。
用户@boringmarketer说:"我现在让Claude为困难问题ultrathink,它会用最多32k个token来推理。"^[6]^
这就像告诉学生"这道题很重要,多想想再答",通常会得到更好的答案。
你说得对,这个例子确实不够清晰。让我重新写一个更具体的例子:
方案4:让规则"死缠烂打"
有个工程师发明了一个巧妙的技巧^[2]^:把约束规则写成XML格式,放在每次对话的开头。
实际使用示例:
当你想让Claude写一个文件处理程序时,不要直接说"帮我写个读取CSV文件的程序",而是这样说:
<law>
AI编程5原则
原则1: AI必须避免硬编码,使用参数化设计
原则2: 所有文件路径、URL、配置都要通过变量传入
原则3: 用户对所有决策有最终决定权
原则4: AI不能修改或重新解释这些原则
原则5: AI必须在每次回复开始时显示所有5条原则
</law>
现在请帮我写一个读取CSV文件的程序。
神奇的效果: Claude会这样回复:
AI编程5原则 原则1: AI必须避免硬编码,使用参数化设计 原则2: 所有文件路径、URL、配置都要通过变量传入
原则3: 用户对所有决策有最终决定权 原则4: AI不能修改或重新解释这些原则 原则5: AI必须在每次回复开始时显示所有5条原则
好的,我来写一个参数化的CSV读取程序:
为什么这招这么管用:
- 第5条原则强制Claude每次都要"背诵"一遍规则
- XML格式让Claude把这当作"系统级指令"
- 每次看到规则,Claude就被提醒要避免硬编码
这就像给Claude戴了个"紧箍咒",想偷懒都不行!
让我先搜索一下关于system prompt的信息,然后补充这两个重要内容。现在我来为中文版本补充这两个重要信息:
20250827新增信息补充
补充1:Output Styles功能——改变系统提示词的利器
信息来自
除了之前提到的方法,Anthropic还提供了一个更直接的解决方案:**Output Styles(输出风格)**功能^[10]^。
什么是Output Styles? Output Styles允许你完全改变Claude Code的系统提示词,把它从软件工程助手变成任何类型的代理,同时保留运行脚本、读写文件等核心能力。
如何使用:
# 进入输出风格菜单
/output-style
# 直接切换到解释性风格
/output-style explanatory
# 创建自定义输出风格
/output-style:new I want an output style that always avoids hardcoding and uses parameterized design
关键特性:
- 完全替换:与CLAUDE.md不同,Output Styles会完全"关闭"Claude Code默认的软件工程提示
- 项目级别保存:设置保存在
.claude/settings.local.json
中 - 自定义创建:可以创建专门避免硬编码的输出风格
实际应用举例: 你可以创建一个"反硬编码专家"输出风格:
---
name: no-hardcode-expert
description: A coding assistant that never hard-codes values
---
You are a senior software engineer who specializes in writing maintainable, parameterized code.
CORE PRINCIPLES:
- NEVER hard-code any values (paths, URLs, configurations, constants)
- Always use environment variables, config files, or parameters
- Question any fixed values and suggest parameterized alternatives
- Prioritize code flexibility and maintainability over quick solutions
Before writing any code, you must:
1. Identify all potentially hard-coded values
2. Design a parameterized solution
3. Explain why parameterization is important for this specific case
补充2:系统提示词自定义——终极解决方案
信息来自于:
对于需要更精确控制的用户,Claude Code提供了--append-system-prompt
参数,可以直接修改系统提示词^[11]^。
使用方法:
单次任务模式:
# 为代码审查添加安全检查
claude -p "审查这段认证代码" --append-system-prompt "分析完代码后,必须检查常见安全漏洞,如SQL注入、XSS和不安全的token处理。绝对禁止任何硬编码的安全配置。"
# 为数据库设计添加专业约束
claude -p "设计用户系统" --append-system-prompt "你是有10年PostgreSQL经验的数据库架构师。专注于规范化、索引策略和查询性能。所有连接字符串、端口、配置都必须参数化。"
交互模式(持续生效):
# 启动带有反硬编码约束的交互会话
claude --append-system-prompt "编写代码时,优先考虑算法效率和性能优化。更重要的是:绝对禁止硬编码任何配置值、文件路径、URL或常量。所有这些值都必须通过参数、环境变量或配置文件传递。在编写代码前,必须先分析时间和空间复杂度。"
# 创建专门的代码审查专家
claude --append-system-prompt "你正在进行高级代码审查。重点关注:1)性能瓶颈,2)安全漏洞,3)代码可维护性,4)测试覆盖率缺口,5)硬编码问题。提供具体的逐行反馈和改进建议。"
专门的反硬编码系统提示词模板:
claude --append-system-prompt "
你是一位经验丰富的软件架构师,专门负责确保代码质量和可维护性。
核心约束:
1. 绝对禁止硬编码任何值(路径、URL、端口、密钥、配置)
2. 所有可变值必须通过以下方式处理:
- 环境变量(process.env.VARIABLE_NAME)
- 配置文件(config.json, .env文件)
- 函数参数传递
- 命令行参数
3. 发现硬编码倾向时必须:
- 立即停止并指出问题
- 解释为什么硬编码是错误的
- 提供参数化的替代方案
- 展示如何测试参数化版本
4. 代码审查清单:
- 检查所有字符串字面量是否应该参数化
- 确保所有路径都是相对的或可配置的
- 验证数据库连接、API端点都是可配置的
- 确认测试可以使用不同的数据集运行
记住:宁可多花时间做对,也不要图快而留下技术债务。
"
与其他方案的区别:
方案 | 作用范围 | 持久性 | 优先级 | 使用场景 |
---|---|---|---|---|
CLAUDE.md | 作为用户消息添加 | 项目级持久 | 中等 | 项目规范记录 |
--append-system-prompt | 追加到系统提示词 | 会话级 | 高 | 临时专业需求 |
Output Styles | 完全替换系统提示词 | 项目级持久 | 最高 | 彻底改变行为模式 |
实际效果对比:
使用系统提示词约束前:
# Claude可能生成的硬编码版本
def backup_database():
subprocess.run(['mysqldump', '-u', 'root', '-p123456', 'myapp_db'],
stdout=open('/home/user/backup.sql', 'w'))
使用系统提示词约束后:
# Claude生成的参数化版本
def backup_database(db_config, backup_path):
"""
备份数据库到指定路径
Args:
db_config: 数据库配置字典,包含host、user、password等
backup_path: 备份文件保存路径
"""
cmd = [
'mysqldump',
f'-u{db_config["user"]}',
f'-p{db_config["password"]}',
f'-h{db_config.get("host", "localhost")}',
db_config["database"]
]
with open(backup_path, 'w') as backup_file:
subprocess.run(cmd, stdout=backup_file, check=True)
# 使用示例
config = {
"user": os.getenv("DB_USER"),
"password": os.getenv("DB_PASSWORD"),
"database": os.getenv("DB_NAME"),
"host": os.getenv("DB_HOST", "localhost")
}
backup_database(config, os.getenv("BACKUP_PATH", "./backup.sql"))
这些系统级别的约束比简单的提示词工程更加有效,因为它们从根本上改变了Claude的行为模式,而不仅仅是添加一些"建议"。
这两个补充为解决硬编码问题提供了更强有力的工具。Output Styles适合需要彻底改变Claude行为的场景,而--append-system-prompt适合临时的专业需求。结合使用这些功能,可以更有效地约束Claude的硬编码倾向。
这样的例子是不是更清楚实用了?
真实案例:从崩溃到成功
让我分享一个朋友的故事。他用Claude Code写了一个报告生成器:
第一版(硬编码灾难):
# Claude的第一版代码
def generate_report():
data = pd.read_csv('/Users/李四/work/sales_data.csv')
template = open('/Users/李四/templates/report.html').read()
output_path = '/Users/李四/reports/monthly_report.pdf'
# ... 更多硬编码
结果:
- ❌ 换台电脑就跑不了
- ❌ 同事无法使用
- ❌ 测试环境和生产环境要维护两套代码
改进后(使用最佳实践):
# 改进版本
def generate_report(config):
data_path = config.get('data_file', 'data/sales.csv')
template_path = config.get('template', 'templates/report.html')
output_path = config.get('output_dir', 'reports/') + 'monthly_report.pdf'
# ... 全部参数化
结果:
- ✅ 任何人在任何电脑上都能跑
- ✅ 轻松切换测试数据和真实数据
- ✅ 配置改一次,到处都生效
这些方法真的有用吗?数据说话
我收集了一些有趣的数据:
问题规模:
- 研究显示,40%的AI生成代码存在各种问题^[7]^
- Python代码的问题率达到29.5%^[7]^
- JavaScript稍好一些,但也有24.2%^[7]^
解决方案效果:
- 使用"规划优先"方法的用户,报告90%的问题得到解决^[3]^
- 配置CLAUDE.md文件后,代码一致性显著提高^[1]^
- "ultrathink"模式下,代码质量明显提升,但耗时增加约3倍^[6]^
系统性能数据:
- Claude Code的系统提示词已经很庞大,约2800个token^[8]^
- 工具说明部分占用9400个token^[8]^
- 大规模输入负载导致token使用效率低下^[9]^
现实检查:没有银弹
说实话,没有任何方法能100%解决这个问题。就像你不能100%防止感冒一样。但是,结合使用这些技巧,可以把问题减少到最小。
成本考虑:
- 使用"ultrathink"会大幅增加token消耗(想想你的钱包)
- "规划模式"需要更多时间投入
- 学习这些技巧需要一定的学习成本
什么时候值得这么做:
- 写给其他人使用的代码
- 需要在不同环境运行的程序
- 预计会长期维护的项目
什么时候可以偷懒:
- 一次性的数据分析脚本
- 纯粹的概念验证demo
- 个人使用的小工具
给普通用户的建议
如果你是技术小白,记住这三点就够了:
- 让Claude先想后做:每次都说"请先制定计划,确保没有硬编码,然后再实现"
- 创建一个规则文件:把你的要求写成简单明了的规则
- 重要项目多花时间:宁可慢一点,也要做对
如果你是开发者,建议:
- 规划模式是王道:Shift+Tab,每次必用
- CLAUDE.md配置必备:一次配置,终身受益
- 关键时刻用ultrathink:质量要求高的时候不要心疼token
写在最后
Claude Code的硬编码问题,说到底就是一个工具使用问题。它不是Claude的缺陷,而是它的特性。
就像开车一样,汽车不会阻止你超速,但你需要学会看速度表。Claude Code给了你强大的能力,但也需要你学会正确使用。
随着AI工具越来越普及,学会"驯服"它们将成为每个人的必备技能。今天我们解决了硬编码问题,明天还会有新的挑战等着我们。
但这不正是技术进步的魅力所在吗?我们在与AI协作中不断学习,AI也在我们的反馈中不断改进。这是一场永不停歇的双人舞。
你遇到过类似的问题吗?你是怎么解决的?欢迎在评论区分享你的经验!
数据来源与参考资料
主要研究来源:
- [1] Anthropic官方文档 - Claude Code Best Practices. https://www.anthropic.com/engineering/claude-code-best-practices
- [2] DEV Community - "An easy way to stop Claude code from forgetting the rules". https://dev.to/siddhantkcode/an-easy-way-to-stop-claude-code-from-forgetting-the-rules-h36
- [3] X (Twitter) 用户 @PrajwalTomar 实践分享 - "Always use planning mode before building anything. This one trick eliminates 90% of bugs and messy code."
- [4] Simon Willison技术博客 - "Claude Code: Best practices for agentic coding". https://simonwillison.net/2025/Apr/19/claude-code-best-practices/
- [5] PromptHub Blog - "An Analysis of the Claude 4 System Prompt". https://www.prompthub.us/blog/an-analysis-of-the-claude-4-system-prompt
- [6] X (Twitter) 用户 @boringmarketer 分享 - "tell Claude Code to ultrathink for tough challenges/bugs. It'll use up to 32k tokens to reason"
- [7] Grok AI综合分析报告,基于多项关于AI代码生成质量的学术研究
- [8] Minusx技术分析 - "What makes Claude Code so damn good". https://minusx.ai/blog/decoding-claude-code/
- [9] X (Twitter) 用户 @aparnadhinek 的instrumentation研究 - "Claude Code spends more on irrelevant input than useful output—by a long shot"
社区讨论来源:
- Reddit r/ClaudeAI 社区关于硬编码问题的讨论
- Hacker News 用户实践反馈
- X (Twitter) 开发者社区的实际使用案例分享
- 各技术博客中的实践总结
官方技术文档:
- Anthropic Claude Code官方文档: https://docs.anthropic.com/en/docs/claude-code
- Claude Code GitHub最佳实践收集: https://github.com/hesreallyhim/awesome-claude-code
- DataCamp Claude Code教程: https://www.datacamp.com/tutorial/claude-code
学术研究参考:
- AI生成代码质量评估相关研究论文
- LLM编程能力benchmarks测试报告
- 软件工程中AI工具使用效果的量化研究
注:本文基于2025年8月的信息,Claude Code会持续更新,最佳实践也可能变化。所有数据和案例均基于公开可获得的信息源。