用 DeepSeek 写了一周代码,坦白说 —— 体验不太理想。不是复杂算法写不出来,而是在工程基本功上频频踩坑:字符串拼 YAML、改完不编译、看到版本号数字小就往上加…… 全是低级错误。本文汇总一周真实使用中遇到的各种翻车现场。
先看总结:一周暴露的几大低级错误
|
#
|
错误类型
|
一句话描述
|
严重程度
|
|
1
|
用字符串拼结构化文件
|
拿 Python 字符串 replace 操作 YAML,缩进全乱、注释丢失、内容位移
|
灾难级
|
|
2
|
改完从不编译验证
|
10 次 Java 修改 9 次编不过,改完就走,完全不知道自己没改对
|
灾难级
|
|
3
|
只读当前文件,不追跨文件引用
|
版本号在父 pom 里定义的,它只看子模块 pom 看不到就瞎猜
|
高危
|
|
4
|
看表面数字,不追根究底
|
看到
3.9.2-beta
就觉得该改成
3.9.3,不去 Maven 仓库查是否存在
|
高危
|
|
5
|
擅自越权改不该改的文件
|
让改 README,它跑去动 pom.xml 和 package.json
|
中等
|
|
6
|
滥用 replace_all 全局替换
|
pom.xml 里全局替换版本号,把项目自身版本污染成错误的 beta 版
|
中等
|
|
7
|
改坏了继续闷头救火
|
出错了不停止、不复盘,继续写更多脚本修旧脚本的 bug,越陷越深
|
高危
|
下面按实际发生的场景逐一展开。
一、任务背景
JeecgBoot 需要从 Spring Boot 3.5.5 升级到 4.1.0(Spring Framework 7.x)。任务不算简单 —— 涉及约 10 个 Java 文件的 API 迁移、10 个 profile 的 YML 配置改造、README 文档更新,中间还穿插了 Redis Bean 冲突、MongoDB 配置键改名等跨模块问题。
|
项目
|
旧版本
|
新版本
|
|
Spring Boot
|
3.5.5
|
4.1.0
|
|
Spring Framework
|
6.x
|
7.x
|
|
Java
|
17
|
17
|
本以为 AI 能轻松搞定,结果两个模型各翻各的。
二、需要修改的内容
Java 代码(约 10 个文件)
|
#
|
改动项
|
旧 API
|
新 API
|
|
1
|
实体 getter 方法名
|
getBody()
|
getRequestBody()
|
|
2
|
HttpHeaders 匿名子类
|
new HttpHeaders(){{...}}
|
标准实例化
|
|
3
|
状态码方法
|
getStatusCodeValue()
|
getStatusCode().value()
|
|
4
|
废弃常量
|
APPLICATION_JSON_UTF8_VALUE
|
APPLICATION_JSON_VALUE
|
|
5
|
废弃方法
|
headers.containsKey(...)
|
getContentLength()
/
getContentType()
|
|
6
|
超时工厂类
|
HttpComponentsClientHttpRequestFactory
|
SimpleClientHttpRequestFactory
|
|
7
|
URI 构建方法
|
fromHttpUrl(...)
|
fromUriString(...)
|
|
8
|
Redis Bean 冲突
|
两个同类型 Bean
|
加
@Qualifier
指定
|
|
9
|
MongoDB 配置键
|
spring.data.mongodb.uri
|
spring.mongodb.uri
|
|
10
|
废弃属性删除
|
server.error.include-*
|
直接删除
|
YML 配置(10 个 profile 文件)
只需做两件事:
- MongoDB 配置键迁移:spring.data.mongodb.uri → spring.mongodb.uri,mongodb 从 data: 子节点提升为 spring: 的直接子节点(减 2 格缩进)
- 删除废弃属性:server.error.include-exception、include-message、include-stacktrace 三行直接删掉
用 Edit 工具每个文件点两下,10 个文件 20 次操作,5 分钟的事。
三、DeepSeek 这一周犯的低级错误
Spring Boot 4 升级是这周最大的一项任务,DeepSeek 在这一个任务上就把能犯的低级错误全犯了一遍。
YML 惨案:用字符串拼接操作结构化文件
DeepSeek 写了一个 Python 脚本,试图批量处理所有 YAML 文件 —— 不用任何 YAML 解析库,直接用字符串拼接操作缩进敏感的结构化配置。
第一轮就翻车:
- mongodb 配置块被从文件中间移动到了文件末尾(脚本的 data_block_end 计算有 bug)
- mybatis 被破坏成 ybatis(首字符被截断)
- Mybatis 变成 Mmybatis(多了一个字符)
- 注释行 # uri: 变成裸的 uri:,导致重复配置
第二轮试图修复自己的 bug,但因为第一轮已经把文件改乱了,第二轮脚本的匹配条件全部失效,什么都没做。
第三轮 用 content.replace('include-exception: true\n', '') 删除属性,但留下了空的 error: 节点和错位的缩进。
第四、五、六轮反复救火 —— 修 ybatis、修 mmybatis、删空节点、修缩进、补注释…… 但 include-* 属性最后还是留在文件里没删掉。
Java 编译:10 次修改 9 次编不过
|
轮次
|
操作
|
结果
|
|
1
|
修复
getBody()
→
getRequestBody()
|
✅ 编译通过
|
|
2
|
修复
getStatusCodeValue()
|
❌ 漏了同一文件还有
APPLICATION_JSON_UTF8_VALUE
也要改
|
|
3
|
修复
APPLICATION_JSON_UTF8_VALUE
|
❌ 没发现
HttpHeaders.containsKey
也要改
|
|
4
|
修复
containsKey
|
❌ 又漏了
setConnectTimeout
|
|
5
|
修复
setConnectTimeout
|
❌ 先用
Duration
参数(不行)→ 换
HttpComponents
工厂(不行)→ 最后才换对
|
|
6
|
修复 YML
|
❌ 字符串脚本破坏缩进
|
|
7-10
|
救火
|
❌ 反复修自己制造的问题,每轮引入新 bug
|
核心问题:DeepSeek 改完从来不编译验证,完全不知道自己没修好。
还有一个更隐蔽的毛病:读不全代码
上面是编译和配置的翻车。日常使用中还暴露了一个更根本的问题 ——DeepSeek 没有通读全文的能力。
举个真实场景:让它参考项目 A 的某个模块,修改项目 B 的对应模块。项目 A 的模块里没有直接写版本号,版本号定义在父 pom.xml 里通过 <dependencyManagement> 继承下来的。DeepSeek 只读了模块本身的 pom.xml,看到版本号字段是空的,就不知道该怎么填。
一个合格的开发者看到模块 pom 里没版本号,会立刻去父 pom 找 —— 这是 Maven 项目的基本常识。Claude Code(用自家模型)会沿着继承链往上追,找到真正的版本定义。DeepSeek 不会 —— 它只看当前文件,读不到就猜,猜不对就错。
这就是 "读不全" 的问题:跨文件引用、继承关系、隐式依赖 ——DeepSeek 处理不了这类需要 "串起来读" 的场景。 这在 Maven 多模块项目里尤其致命,依赖版本经常定义在父 pom 里,读不到就瞎猜。
问题根因
- 不理解 YAML 的缩进敏感性 ——YAML 靠缩进表示层级,DeepSeek 当纯文本处理
- 不会用工具 —— 有 ruamel.yaml、PyYAML 不用,偏要字符串拼接
- 没有测试习惯 —— 改完不验证就跑下一个,错误层层叠加
- 没有备份意识 —— 操作 10 个文件不做备份,出问题没法回退
- 理解不了任务的简单性 —— 减两格缩进的事,偏要绕一大圈
- 没有通读全文的能力 —— 只读当前文件,跨文件引用、父 pom 继承、隐式依赖统统追不到
四、Claude Code + DeepSeek 还有一个毛病:画蛇添足,擅自越权
先强调对比:同样的 Java 编译修复任务,换成 Claude 自己的模型(Opus/Sonnet),表现完全不一样 —— 每次改完自动 mvn compile,编译报错立刻定位修复,从不漏改,从不引入新编译错误。改 YML 用 Edit 精确替换,缩进分毫不差。Claude 自家模型不会出现编译错误这种低级问题。
但用 DeepSeek 跑的 Claude Code,除了上面的编译翻车,还暴露了另一个问题 —— 在做 README 版本号更新这种简单任务时,擅自拓展范围,做了不该做的事。
越权修改核心配置文件
用户要求更新中英文 README 的版本号,Claude 完成了。然后自作主张去改了 jeecg-boot/pom.xml、
jeecg-boot-module-airag/pom.xml、jeecgboot-vue3/package.json。
pom.xml 和 package.json 是构建配置,不是文档。改之前没有向用户确认,改完也没有告知。用户直到后来 svn diff 才发现多了一堆不该有的改动。
没读懂代码就改版本号 —— 表面看数字,深层全错
这是最致命的问题。jeecg-online 的依赖版本是 3.9.2-beta——Claude 看到这个版本号,只做了一个判断:数字太小了,应该改成 3.9.3。
但它完全没有做以下任何一件事:
- ❌ 没有去 Maven 仓库查一下 jeecg-online:3.9.3 是否存在
- ❌ 没有读一下 jeecg-online 这个模块的 pom.xml,搞清楚它是外部发布包还是本地项目
- ❌ 没有理解 beta 后缀的含义 —— 这通常意味着这是一个预发布版本,版本号独立于主项目
- ❌ 没有通读整个项目的依赖关系,理解各个模块之间的版本号是怎么管理的
结果:编译时直接报错 ——Maven 仓库里根本没有 jeecg-online:3.9.3 这个 artifact。
这不是 "不够谨慎",这是根本没读懂代码。 看到 3.9.2 就觉得该改成 3.9.3,跟看到 log4j:1.2.17 就改成 log4j:4.1.0 一样荒谬。版本号的来源只有两种:要么是你自己项目定义的,要么是外部发布的 —— 后者改不改、改多少,不取决于数字大小,取决于那个包实际发布了什么版本。
Claude 在这个问题上表现出的不是疏忽,而是没有 "追根究底" 的意识 —— 看到表面现象就下结论,不去验证。这和 DeepSeek 用字符串拼接 YAML 是同一个层次的问题:不理解数据背后的结构和语义。
滥用replace_all的灾难
修改 pom.xml 时 Claude 用了 replace_all,全局替换 3.9.2-beta → 3.9.3。还原时又全局替换回来。问题是 pom.xml 里多处出现版本号,replace_all 把项目本身的版本号也一起覆盖了:
- jeecg-boot-parent(项目版本): 3.9.3 → 3.9.2-beta ❌
- jeecg-boot-starter-job: 3.9.3 → 3.9.2-beta ❌
- jeecg-boot-starter-shardingsphere: 3.9.3 → 3.9.2-beta ❌
- jeecg-boot-starter-ai: 3.9.3 → 3.9.2-beta ❌(还原时遗漏,至今残留)
pom.xml 这种多出现版本号的文件,replace_all 极其危险。必须用精确上下文匹配单次替换。
还原不彻底,留下烂摊子
jeecg-boot-starter-ai 一行仍然残留 3.9.2-beta,需要手动改回 3.9.3。如果用户没发现,这个错误版本号就会一直留在代码库里。
五、两种翻车,两种病因
|
维度
|
DeepSeek
|
Claude Code(自家模型)
|
|
Java 编译修复
|
❌ 10 次 9 次编不过
|
✅ 零编译错误,自动验证
|
|
错误定位
|
❌ 修一个漏一个
|
✅ 看到错误立刻定位
|
|
工具使用
|
❌ 字符串拼接 YAML
|
✅ Edit 精确替换
|
|
跨文件追踪
|
❌ 只读当前文件,父 pom 继承追不到
|
✅ 沿继承链往上追
|
|
范围控制
|
✅ 让改什么改什么
|
⚠️ 偶有越权
|
|
语义理解
|
❌ 版本号只看表面数字
|
✅ 区分项目版本 vs 发布包版本
|
|
简单修改
|
⚠️ 想太多反而出错
|
⚠️ GitHub Copilot 更快
|
两张表格拼在一起,深层问题就清楚了:
- DeepSeek 的翻车主因是 "读不全 + 不验证"—— 只读当前文件,跨文件引用追不到;改完也不编译,完全不关心改对了没有。
- Claude 自家模型的翻车只有一个 —— 偶尔控制不住范围,但改出来的代码是对的。
- GitHub Copilot 的定位是 "简单快改"—— 单文件小改、精准补全,比 DeepSeek 稳得多。但跨文件重构不是它的强项。
简单说就是:简单修改找 Copilot,复杂重构找 Claude 自家模型。DeepSeek 夹在中间挺尴尬,但比 Codex 还是强一档 ——Codex 在复杂任务上基本没法用。
六、教训总结
归根结底就几条,记住了能少踩很多坑:
- 结构化文件(YAML/JSON/XML)永远不要用字符串操作 —— 用解析库或者编辑器的精确替换,别写 Python 脚本拼字符串
- 改完必须编译验证 ——AI 不会主动做这件事,你得盯着。没有这个闭环,AI 就是破坏者
- 指定范围,禁止越权 —— 明确告诉 AI "只改 A,别碰 B"。它搜索到的非目标文件发现先汇报再动手
- pom.xml 禁用 replace_all—— 多处出现相同版本号时,全局替换是灾难。区分项目版本号 vs 外部发布包版本号,后者不一定跟着项目版本升级
- 改之前备份,还原后逐行确认 ——AI 不会承认自己搞砸了,它会把问题越搞越大直到你发现。留一条漏网之鱼就是埋一颗雷
- 别让 AI 独自干完整模块 —— 小改小修可以,完整模块目前做不到靠谱。DeepSeek 尤其如此,10 次 8 次编译不过
七、结论
也不能一棍子打死。Claude Code + DeepSeek 这套组合有它的优点:Skills 兼容性不错 ——skill 体系是 Claude Code 的核心能力,换 DeepSeek 当模型也能正常驱动,日常小改小修也能用。
但致命伤也很明显:改一个完整模块的时候,10 次有 8 次编译不过,而且它完全不知道自己没改对。这不是 "偶尔失误",是系统性的低级问题。一个 AI 编码工具连 "改完编译一下" 这种最基本的习惯都没有,就好比司机每次停车都不拉手刹 —— 平路可能没事,坡上就要命。
DeepSeek 现在的位置很尴尬:想学 Claude 做全局理解,能力没跟上;又没有 Copilot 的局部精准,卡在中间。如果只是拿它当参考意见、让 Claude 自家模型干活,还行。真要让它独立动手改一个完整模块,做好 10 次修 8 次的心理准备。
至于排名,一周实测后的主观感受:
- 简单修改 / 单文件补全:GitHub Copilot > Claude Code > DeepSeek > Codex。Copilot 精准快,Codex 垫底。
- 复杂重构 / 跨文件多模块:Claude Code(自家模型)>> DeepSeek > Codex。差距全方位,Codex 在复杂任务上基本没法用。
- Skills 驱动的工作流:Claude Code + DeepSeek 能用,但只适合小范围改动。
如果你在选 AI 编码工具,别只看跑分。找一个小任务实际用一下,看三件事:
- 它改完会不会自己编译验证?
- 它会不会擅自改你没让它改的东西?
- 它看到不理解的代码,是深入追查,还是看着表面数字就动手?
这三个问题,比任何 benchmark 分数都更能预测你的日常体验。
- 日期:2026-07-07
- 参与模型:deepseek-v4-pro[1m]、Claude Code(Opus/Sonnet)
- 任务:JeecgBoot Spring Boot 3.5.5 → 4.1.0 升级(Java + YML + README 更新)
- 结论:DeepSeek 低级错误频发 —— 字符串拼 YAML、改完不编译、读不全代码、只看表面数字。Skills 兼容还行,小改能用,完整模块免谈。Claude 自家模型则基本不犯这些错误。
- 期望:希望 DeepSeek 官方能看到这些一线使用中的问题总结,尽快解决改完不编译、跨文件读不全、结构化文件乱拼这些低级问题 —— 这些不是能力上限的问题,是工程基本功的缺失,修起来应该不难。