Stack Overflow调查显示84%开发者已用AI工具,但AI生成代码量远超人类理解速度,验证能力正成为开发者最值钱技能。文章引用数据论证这一趋势。
AI 现在已经能在你解释完需求之前就生成功能代码了。
你描述一个 API 端点,几秒钟后,你就拥有了 controller、service、数据库查询、校验逻辑、测试用例,甚至可能还有 Docker 配置。
所以代码是正确的……对吧?
而这可能正在软件工程领域发生最大的变化之一:
编写代码正在变得廉价。证明代码正确正在变得更有价值。
这其实不是什么新的工程原则。
专业软件团队在信任软件之前,一直以来都依赖审查、测试、安全分析、CI/CD 检查、监控以及其他形式的验证手段。
AI 改变的是,我们在人类完全理解代码之前能够生成的代码量。
这使得验证成为了开发者工作中更大的一部分。
开发者正在快速采用 AI。
2025 年 Stack Overflow 开发者调查显示,84% 的受访者正在使用或计划在开发中使用 AI 工具,51% 的专业开发者表示他们每天使用这些工具。
但与此同时,发生了一件有趣的事。
只有 33% 的人表示信任 AI 输出的准确性,而 46% 的人明确表示不信任。
最常见的挫折感并非:
"AI 不会写代码。"
恰恰相反。
66% 的人表示对"几乎正确但不完全对"的 AI 方案感到沮丧。另有 45% 表示调试 AI 生成的代码可能比手动编写更耗时。
这种"几乎正确"的情况是很危险的。
明显损坏的代码很容易处理。
几乎正确的代码则不同。
它看起来很专业。
它使用合理的变量名。
它遵循你的框架约定。
它甚至可能通过测试。
而在它内部的某个地方,存在一个并不成立的假设。

这里有一个重要的区分。
没有任何单一通用规则说:
"每个美国软件公司必须严格遵循以下七个步骤。"
初创公司、银行、国防承包商、SaaS 公司、医疗保健机构和小代理商的运作方式各不相同。
但成熟的工程组织往往围绕同一个理念趋同:
代码不会仅仅因为有人写了它就被信任。必须有证据支持它。
在美国,NIST 的安全软件开发框架描述了诸如审查或分析人类可读代码、以及测试可执行代码以识别漏洞并验证安全需求的实践。
NIST 特别讨论了以下技术:
记录发现的问题
CISA 的"安全设计"指南同样推荐同行评审、SAST、DAST、单元测试和集成测试等实践,作为互补技术而非将某一项检查视为足够。
这就是我们应该带到 AI 生成代码上的思维方式。
AI → 理解 → 验证 → 攻击 → 审查 → 观察 → 合并
假设你告诉一个 AI 智能体:
Create an endpoint for deleting a user's account.
DELETE /users/:id
这个实现可能在技术上是完美的。
但实际需求是什么?
用户应该永久消失吗?
记录应该被软删除吗?
发票必须保留用于财务审计吗?
共享工作区会怎样处理?
API 令牌会怎样?
用户应该收到一封邮件吗?
管理员可以恢复账户吗?
删除账户是否违反其他数据保留要求?
AI 可能为错误的规格说明生成完全有效的代码。
所以在审查实现细节之前,先问:
AI 做了哪些假设?
我经常发现这个问题比:
Is this code correct?
更有用。
List every important assumption you made while implementing this feature.
你可能会发现模型假设了:
这是你的第一层验证。
这就是 AI 编码对缺乏经验的开发者危险的地方。
一个智能体改了 17 个文件。
你看到的摘要:
✓ Added authentication
✓ Updated schema
✓ Added validation
✓ Added tests
✓ Fixed lint errors
摘要不等于实现。
如果你对这个拉取请求负责,你就应该理解重要的变更。
你不一定需要记住每行生成的代码。
但你应该能够解释:
如果你无法解释这些事情,你的信心来源就是 AI 的写作风格,而非工程证据。
先从便宜的检查开始。
对于 TypeScript 项目,可能意味着:
npm run typecheck
npm run lint
npm run build
对于另一种技术栈,可能包括:
dotnet build
cargo check
go vet ./...
python -m mypy .
AI 经常生成看起来语法合理但实际理解错误的代码:
编译不能证明正确性。
但无法编译的代码已经在一个非常便宜的证明上失败了。
async function transferMoney(
fromAccount: string,
toAccount: string,
amount: number
) {
await debit(fromAccount, amount);
await credit(toAccount, amount);
}
A → -$100
B → +$100
如果 credit() 失败了会怎样?
你的系统可能变成:
A → -$100
B → +$0
函数只成功了一半。
一半成功比完全失败更糟糕。
现在你在像验证者一样思考了。
await db.transaction(async (tx) => {
await debit(tx, fromAccount, amount);
await credit(tx, toAccount, amount);
});
这就是为什么经验丰富的开发者不断思考失败模式。
AI 喜欢 happy path。
生产环境喜欢其他一切。
对于每个重要函数,至少检查:
Normal input(正常输入)
Empty input(空输入)
Null / undefined
Minimum value(最小值)
Maximum value(最大值)
Incorrect type(错误类型)
Malformed input(格式错误的输入)
Duplicate operation(重复操作)
Unauthorized request(未授权请求)
Concurrent request(并发请求)
Network failure(网络故障)
Database failure(数据库故障)
Timeout(超时)
Retry(重试)
Partial failure(部分失败)
想象一个 AI 生成的注册表单。
john@example.com
JOHN@example.com
john+test@example.com
""
5000-character input(5000 字符输入)
Unicode
duplicate email(重复邮箱)
database timeout(数据库超时)
two simultaneous signups(两次同时注册)
正确性存在于边界处。
这是一个重要的工程习惯。
不要只测试:
10 + 20 = 30
而要测试那些应该始终保持为真的规则。
例如,在支付系统中:
资金不能凭空消失。
在库存系统中:
库存不能变成负数。
在授权系统中:
用户不能访问另一个组织的私有资源。
重试同一个 webhook 不能向客户收取两次费用。
这些就是不变量。
AI 生成的实现可以改变。
你的不变量不应该改变。
在审查 AI 生成的系统时,识别不变量可能比阅读数百行生成的代码更有价值。
这里有一个微妙的陷阱。
Implement this feature.
Write tests for it.
AI 在实现功能时做了假设 X。
现在它在基于……假设 X 编写测试。
wrong assumption → code(错误假设 → 代码)
same wrong assumption → test(同样错误假设 → 测试)
✅ 47 tests passed
但系统仍然可能是错的。
测试证明了实现满足测试。
它们不会自动证明测试代表了现实。
所以使用独立验证。
Implement this feature.
只给出需求和产生的 diff:
Act as a hostile reviewer.
Find incorrect assumptions, security vulnerabilities,
race conditions, missing edge cases and ways this
implementation could fail in production.
Do not try to defend the implementation.
现在 AI 被用作对手,而不仅仅是作者。
这要强大得多。
AI 生成的代码经常引入包。
npm install some-amazing-auth-helper
不要盲目运行它。
而且最重要的是:
我们真的需要另一个依赖吗?
依赖成为你软件供应链的一部分。
相应地对待它们。
这些不是同一回事。
你被允许这样做吗?
AI 处理身份验证经常正确,但遗漏了授权。
GET /projects/:projectId
if (!user) {
return 401;
}
if (project.organizationId !== user.organizationId) {
return 403;
}
没有它,每个通过身份验证的用户都可能通过更改 ID 来访问每个项目。
这不是假设性的"AI 安全"。
那是普通的应用安全。
这恰恰就是关键所在:
AI 生成的代码仍然需要通过普通的工程标准检验。
modify files
run terminal commands
execute migrations
call APIs
create infrastructure
delete resources
push code
deploy
这与自动补全的风险级别完全不同。
在允许危险操作之前,问自己:
Can it delete production data?
Can it modify production?
Can it rotate credentials?
Can it change infrastructure?
Can it force-push?
Can it publish packages?
一个有用的原则是:
如果一个智能体只需要修改源文件,它可能不需要生产数据库凭证。
如果它只需要分析日志,它可能不需要写权限。
能力应该是挣来的,而不是想当然的。
测试执行已知场景。
静态分析在不运行应用程序的情况下查找可疑模式。
根据技术栈,这可能包括以下工具:
linting
SAST
dependency scanning
secret scanning
type checking
code quality
license checks
一个 CI 流水线在概念上可能长这样:
Pull Request
↓
Type Check
↓
Lint
↓
Unit Tests
↓
Integration Tests
↓
Security Scan
↓
Dependency Scan
↓
Human Review
↓
Merge
注意到什么重要的事了吗?
Was generated by AI? → skip everything
AI 代码应该和人类代码通过相同的关卡。
当作者不完全理解生成的实现时,可能需要更严格的关卡。
一个单元可能正确,但系统可能是错的。
你的支付服务正常工作。
你的数据库服务正常工作。
你的 webhook 处理器正常工作。
然后生产环境发生了这个:
Stripe webhook
↓
timeout
↓
Stripe retries
↓
your endpoint processes again
↓
duplicate transaction
单个函数都没问题。
是交互出了问题。
AI 智能体特别擅长生成局部合理的组件。
这使得集成测试变得极其重要。
NIST 当前的 DevSecOps 参考材料还描述了自动化测试套件,涵盖功能和非功能需求,包括单元测试、集成测试、回归测试、冒烟测试和验收测试,然后制品才会进一步进入交付流程。
假设你的 AI 基于以下内容生成代码:
POST /v1/payments
也许实际的提供商已经改了它。
也许响应字段是:
{
"payment_status": "paid"
}
而 AI 假设的是:
{
"status": "success"
}
这就是为什么文档很重要。
Stack Overflow 调查仍然显示技术文档是开发者最常用的学习资源。
对于外部集成,请根据以下内容验证:
真实的沙箱响应
"AI 听起来很自信。"
AI 生成的迁移:
ALTER TABLE users
DROP COLUMN legacy_id;
AI 检查过以下情况了吗:
another service still reads it?
analytics depends on it?
a rollback requires it?
millions of rows need migration?
the operation locks the table?
Schema 变更值得不同的谨慎级别。
对于危险迁移,考虑:
expand
migrate
verify
contract
change everything immediately
这里还有另一个重要区别。
在我们预测的场景中,它行为正确吗?
在我们没有预测到的场景中,发生了什么?
logs
metrics
traces
error reporting
alerts
audit events
想象一个 AI 功能通过了所有测试,但导致 API 延迟从:
180 ms
变成:
2.8 seconds
运营层面很糟糕。
正确性包括生产行为。
这可能是本文最有用的技术。
Build this feature.
Feature: Password Reset
Requirements:
[ ] Token expires after 15 minutes
[ ] Token can only be used once
[ ] Existing sessions can be revoked
[ ] Email enumeration is prevented
[ ] Rate limiting exists
[ ] Password policy is enforced
[ ] Reset attempts are logged
[ ] Unit tests pass
[ ] Integration tests pass
[ ] Security scan passes
[ ] Another developer reviews the PR
现在对话变了。
不再问 AI:
"做密码重置。"
"生成一个满足这些可观察条件的实现。"
这更接近工程。
这是我越来越确信开发者应该学习的工作流:
┌───────────────┐
│ REQUIREMENT │
└───────┬───────┘
↓
┌───────────────┐
│ GENERATE │
└───────┬───────┘
↓
┌───────────────┐
│ UNDERSTAND │
└───────┬───────┘
↓
┌───────────────┐
│ TEST │
└───────┬───────┘
↓
┌───────────────┐
│ ATTACK │
└───────┬───────┘
↓
┌───────────────┐
│ REVIEW │
└───────┬───────┘
↓
┌───────────────┐
│ OBSERVE │
└───────┬───────┘
↓
┌───────────────┐
│ SHIP │
└───────────────┘
注意到打字代码的部分有多小了吗?
这可能就是软件工程的发展方向。
我有时看到这样的建议:
"AI 现在能写代码了,所以学基础知识不重要了。"
我认为恰恰相反。
如果 AI 给你这个:
const results = await Promise.all(
users.map(user => processUser(user))
);
你需要足够的工程知识来问:
如果有 20 万用户怎么办?
什么限制了并发?
我们会耗尽数据库连接吗?
操作是幂等的吗?
失败如何重试?
如果只完成了 40% 怎么办?
这应该是一个后台 job 吗?
AI 使语法变得不那么值钱。
它使判断力变得更加值钱。
databases
networking
HTTP
authentication
authorization
transactions
concurrency
caching
queues
distributed systems
testing
security
observability
system design
不是因为 AI 不能生成涉及这些的代码。
而是因为你需要这些概念来判断生成的代码是否有意义。
高级工程技能也可能改变。
高级开发者以前的杠杆部分来自:
"我能比初级开发者快得多地写出这个实现。"
现在 AI 可以快速生成两种实现。
高级开发者的优势变成:
"我知道哪个实现能在生产环境存活。"
架构后果
需求歧义
运营失败模式
当实现变得廉价时,这些技能变得更加重要。
在合并一个重要的 AI 生成 PR 之前,我想能够回答这些问题:
我知道这个功能确切地应该做什么吗?
我识别出 AI 的假设了吗?
验收标准定义了吗?
我理解重要的变更吗?
架构合适吗?
AI 引入了不必要的复杂性吗?
数据会损坏吗?
写操作在必要的地方是事务性的吗?
危险操作安全吗?
重试行为是幂等的吗?
认证正确吗?
授权正确吗?
依赖检查了吗?
注入风险考虑了吗?
边界情况测试了吗?
静态分析通过了吗?
安全检查通过了吗?
人工审查完成了吗?
如果我不能回答那张列表上的重要问题,我就还没准备好说:
"代码是正确的。"
这是我认为最重要的心态转变。
不要这样提示:
Build authentication.
Implement authentication.
Then provide:
1. assumptions you made
2. threat scenarios
3. tests covering happy and failure paths
4. authorization checks
5. dependency changes
6. migration implications
7. commands I can run to verify everything
8. unresolved risks
现在你不仅仅是在向 AI 要代码。
你是在请 AI 帮助产生证据。
而你独立验证那些证据。
AI 正在快速降低将想法转化为源代码所需的工作量。
但公司并不真正为工程师在 .ts、.py、.go、.rs 或 .java 文件中产生字符而付费。
他们为工程师让系统工作而付费。
并且在出问题时有责任人。
10,000 lines
生产环境不在乎。
Does it work?
Will it keep working?
Is it secure?
Can it fail safely?
Can we monitor it?
Can we recover?
Can another engineer maintain it?
Can you prove those things?
这就是软件工程。
自动化重复工作。
生成文档。
"AI 成功地生成了它"
你的完成定义。
把这个作为你的定义:
"我有足够的证据相信这可以在生产环境运行。"
因为当代码变得更容易生成时,有一种开发者技能变得更难自动化:
一个给每天与 AI 一起工作的开发者的问题:
如果 AI 生成了生产 pull request 的 80%,在你按下 Merge 之前,你需要个人理解多少那个实现?
A) 每一行重要的代码 B) 架构 + 关键路径 C) 我主要需要强测试和 CI 证据 D) 如果智能体能证明行为正确,我就合并 E) 我真的还不知道
我特别好奇这在不同类型的团队中有多大差异:初创公司、企业团队、独立开发者,以及受监管行业。
你的标准是什么?
如需进一步行动,你可以考虑屏蔽此人或举报滥用行为