DEV Community

GokuScraper悟空爬虫
GokuScraper悟空爬虫

Posted on

AI 写代码写得越溜,架构师就越值钱

AI 写代码写得越溜,架构师就越值钱

大家好,我是彪哥。

你有没有遇到让 claude 给你写个小脚本,对付几百条数据的时候跑得贼溜,但等数据量一上来,

同样的代码就开始各种摆烂:缺字段、格式错乱、死循环……你盯着满屏的红字报错,真的很想连电脑一起砸了。

对,这就是咱们常说的“屎山代码”。

后来我复盘了一下,发现这锅不全在 AI,更多是因为我自己图省事,把一大堆任务全塞进了一个 Prompt

上一个项目我就踩了一回坑,然后我换了个思路——用“流水线+一件事一个人干”的方式重写了一遍,结果就发生了天壤之别。

最初跑几千条能挂几十条,后来跑几万条几乎零失败。

今天我把这个翻车到重构的过程完整分享出来。


一、项目需求

当时手里攒了几万条游戏、影视类的 AI 提示词,数据长这样:

{
  "id": "xxx",
  "raw_p": "A cinematic shot of a futuristic city...",
  "i18n": {}
}
Enter fullscreen mode Exit fullscreen mode

需求不复杂:

1.把正文 raw_p 翻成中文和英文(有的原本是中文,有的是英文,还有少部分是日语);

2.翻完之后,分别从中英文里提取标题和几个标签;

3.再生成一个英文的 URL slug,还要分个类。

看着平平无奇对吧?我起初也这么觉得。


二、万能就是啥也不能

当时心态就是懒,心想大模型那么强,我一口气把要求全列出来,它肯定能给我咕嘟咕嘟吐出来一个完美 JSON。

我那个 Prompt 大概长这样:

你是专业的视频内容分析师,请一次性完成下面的事:

  • 判断语言;
  • 如果是英文就翻成中文,中文就翻成英文;
  • 给中文内容起个不超过 10 字的标题和 3 个标签;
  • 给英文内容起标题、标签、slug(限 6 个词),还要从 Commercial / Entertainment / Content Creation 里挑一个;
  • 全部严格按 JSON 格式返回……

瞅着是不是逻辑满满?真跑起来全是惊吓:

前几百条还行,到后面 AI 开始“忘事”,slug 直接没了;

有个条目给我分了个 Gaming,但这根本不在我给的三个选项里;

更离谱的是碰到日语来源的,它居然只给了英文翻译,中文那块直接编了一段上去;

中文标题偶尔直接照抄原文,压根没翻。

几千条跑下来,挂了有二三十条,字段丢失、分类乱飘各种bug都来了。

而且我的重试逻辑也很粗暴,挂掉就重复请求好几次,白白烧掉一大堆 token。时间也全搭进去了。

那会儿我才反应过来:不是我用的 AI 蠢,是我设计这套流程的时候本身就埋了个大坑。


三、问题在哪?

我们都知道一个道理:一个函数最好只干一件事

但在写 Prompt 的时候,我们经常反向操作——把识别、翻译、提取、格式化全搅在一锅里,指望模型一次完美出锅。

小规模、不太讲究的场景可能真能混过去,可一旦数据量上去,任何一点格式偏差都会被成倍放大:

模型注意力被分散,小字段容易丢;

多个约束之间暗暗冲突,输出就开始左右横跳;

碰到一些变态长文本或者离谱的文本,模型直接开始出现严重的幻觉;

你后面做的校验也兜不住所有异常。

最后只能不停地补 if 'slug' not in data 这种补丁,活生生把代码补成一座屎山。


四、推倒重来

想明白之后,我把整个流程拆成了四个独立步骤,每一步只让模型集中精力干一件事。

新的处理流变成这个样子:

第一步:只判断语言

截取正文前 1000 个字符扔进去,让它返回一个 lang(en / zh / other)。

Prompt 短到一句话:”Identify text language. Only return JSON: {'lang': ...}“

第二步:纯翻译,别的都别干

根据上一步的结果:

英文的 → 翻成中文;

中文的 → 翻成英文;

其他语言 → 中英文各调一次单独的请求。

每个请求只让模型输出 zh_pen_p,禁止它加戏。

第三步:中文元数据提取

拿着翻译好的中文,提取一个不超过 10 字的标题和 3 个标签。

系统提示写得特别聚焦,绝不提一丁点英文要求。

第四步:英文元数据提取

基于英文内容,拿标题、标签、slug、分类。分类那三个选项直接写死在提示里,不给它产生幻觉的机会。

核心就一句:一次只让 AI 当一种专家,绝不让它同时干两件性质不同的事。


五、光拆分不够,还得加上监工

拆是拆了,但要真变成能扛住几万条的工程代码,还得靠这几个不起眼的细节:

1. 强制 JSON,缺一个字段就翻脸

每个请求都设了 response_format={"type": "json_object"},出来之后我对每个必填字段做一遍检查:

if expect_keys:
    for key in expect_keys:
        if key not in res or res[key] is None:
            raise ValueError(f"缺少字段或非法: {key}")
Enter fullscreen mode Exit fullscreen mode

这样只要少东西,马上扔异常去重试,不会悄咪咪把错误吃成空字符串。

2. 失败了就退几步再试,别跟服务器硬刚

网络波动、服务端限流谁都躲不过,我给每个请求塞了最多 3 次机会,每次的等待时间慢慢加长:

for i in range(6):
    try:
        ...
    except Exception as e:
        print(f"重试({i+1}/6): {str(e)[:50]}")
        time.sleep(3 * (i + 1))
Enter fullscreen mode Exit fullscreen mode

3. 随时可能崩,所以要能断点续跑

写文件的时候加锁,每次启动前先去读输出文件里已经搞完的 ID,绝不重复跑。

这样即使半夜脚本挂了,早上一键重启就能继续,不用心疼白花花的 token。

with write_lock:
    f_out.write(json.dumps(res, ensure_ascii=False) + '\n')
    f_out.flush()
Enter fullscreen mode Exit fullscreen mode

六、前后对比

同样的数据集,跑完两版直接拉了个表:

指标 以前那个大杂烩 现在这条流水线
一次性成功率 大概 96% 99.8% 往上
单条平均耗时 3.5 秒 3.8 秒(稍微多一丢丢,但稳)
格式错误导致失败 每千条崩三四十 几乎没有
白烧的 token 一堆 很少
分类编出白名单外 每百个有五六个 一个都没有

对我来说最爽的不是成功率,是我终于不用半夜盯着日志修 bug 了

让脚本自己跑,过几小时直接验收干净数据的感觉,懂的都懂。


七、怎么让自己别写出 AI 屎山

踩了这次坑,我给自己立了几条死规矩。

别让模型同时做两件不同质的事

翻译就翻译,提取就提取,分类就分类。宁愿多调两次也别合体。

给每次调用一个清晰的身份

提示词开头就像委任状:“你现在的工作只有一个,就是……”

对输出格式要像安检一样严格

开 JSON mode,列必填字段清单,少一个都不行。不通融。

把偶尔失败当日常设计

重试、日志、断点、并发控制,这些看着啰嗦,量产的时候能救命。

别上来就追求一步到位

先保证流程对,再提速。我一上来想少调一次 API,结果翻来覆去重试烧掉的钱更多,还累死人。


八、最后说几句

AI 时代,人人都在喊“写代码要被替代了”,但我反倒觉得,写代码的能力会贬值,做架构的能力会越来越贵

因为代码解决的是“怎么做”,架构解决的是“怎么选”。

选技术路线、拆模块边界、定容错策略——这些事儿,没有标准答案。

它依赖的是你对业务的判断、对风险的嗅觉、对组织里各种隐性约束的掂量。

而这些,全在黑盒里,在会议吵架里,在踩了十年坑攒下的直觉里。

AI 学不到,它就不可能替你做这些决定。

所以,未来真正稀缺的,不是能把功能写出来的人,而是能在无数条岔路里,拍板定方向的那个人

那个人,就是架构师。

抱拳了

感谢各位朋友捧场!要是觉得内容有有点意思,别客气,点赞、在看、转发,直接安排上!

想以后第一时间看着咱的文章,别忘了点个星标⭐,别到时候找不着了。

行了,今儿就到这儿。

image-20260501184936350

论成败,人生豪迈,我们下期再见!

Top comments (0)