我发现了Claude Code的一个"坏习惯":为什么它总是写硬代码(hard-code)?

Claude Code总是生成硬编码?研究显示40%的AI代码存在质量问题。根本原因:Claude被设计为"不强加观点"的工具,加上LLM的健忘特性。解决方案:使用规划模式、配置CLAUDE.md文件、采用"ultrathink"关键词。虽然无法100%解决,但能显著改善代码质量

我发现了Claude Code的一个"坏习惯":为什么它总是写硬代码(hard-code)?
Photo by Forlll De Rad / Unsplash

故事开始于一个令人抓狂的下午

上个月,我用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功能——改变系统提示词的利器

信息来自

https://x.com/wdonsong

除了之前提到的方法,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:系统提示词自定义——终极解决方案

信息来自于:

https://x.com/eviljer

对于需要更精确控制的用户,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
  • 个人使用的小工具

给普通用户的建议

如果你是技术小白,记住这三点就够了:

  1. 让Claude先想后做:每次都说"请先制定计划,确保没有硬编码,然后再实现"
  2. 创建一个规则文件:把你的要求写成简单明了的规则
  3. 重要项目多花时间:宁可慢一点,也要做对

如果你是开发者,建议:

  1. 规划模式是王道:Shift+Tab,每次必用
  2. CLAUDE.md配置必备:一次配置,终身受益
  3. 关键时刻用ultrathink:质量要求高的时候不要心疼token

写在最后

Claude Code的硬编码问题,说到底就是一个工具使用问题。它不是Claude的缺陷,而是它的特性

就像开车一样,汽车不会阻止你超速,但你需要学会看速度表。Claude Code给了你强大的能力,但也需要你学会正确使用。

随着AI工具越来越普及,学会"驯服"它们将成为每个人的必备技能。今天我们解决了硬编码问题,明天还会有新的挑战等着我们。

但这不正是技术进步的魅力所在吗?我们在与AI协作中不断学习,AI也在我们的反馈中不断改进。这是一场永不停歇的双人舞。

你遇到过类似的问题吗?你是怎么解决的?欢迎在评论区分享你的经验!


数据来源与参考资料

主要研究来源:

社区讨论来源:

  • Reddit r/ClaudeAI 社区关于硬编码问题的讨论
  • Hacker News 用户实践反馈
  • X (Twitter) 开发者社区的实际使用案例分享
  • 各技术博客中的实践总结

官方技术文档:

学术研究参考:

  • AI生成代码质量评估相关研究论文
  • LLM编程能力benchmarks测试报告
  • 软件工程中AI工具使用效果的量化研究

注:本文基于2025年8月的信息,Claude Code会持续更新,最佳实践也可能变化。所有数据和案例均基于公开可获得的信息源。