跳到正文
博客园· 粉紫系超人气月兔铃仙·· 3 小时前AI 评分34

两天烧100亿token,如何用DeepSeek做游戏攻略信息收集

两天烧100亿token,如何驾驶大肥鱼进行信息收集工作? - 粉紫系超人气月兔铃仙

AI 导读

一名游戏公司实习生两天消耗约100亿token(含缓存命中),用DeepSeek为海量异构攻略站点现场编写爬虫脚本并解析PDF,最高缓存命中率99.9%、成本降至原来的1/10以下、速度超200 token/s。

正文

这篇文章比较长,大概5k字

目录

背景

这一周的主要工作是收集和整理资料,顺便把 DeepSeek(下文简称 DS)蹬到冒烟。算上缓存命中的部分,两天用了一百亿 token。
可以说是非常多了。在我当时使用的 DSH 中,一个对话框最多能开 8 个子代理。我一般还要同时开很多个对话框,消耗自然极大。

由于工作的具体内容不方便透露,本文省略了部分细节。

这里解释一下背景

我们公司是游戏公司,最近在做 AI 相关的业务,游戏里要内置一个能回答攻略问题的 AI。
问题在于,游戏攻略数据比较小众,通用模型很难准确回答这类问题。于是,我们决定自建知识库,收集资料就成了重中之重。

工作拆成两块:

  1. 上各大论坛收集高质量的攻略文本;
  2. 处理这些文本,把其中重要的字段解析出来。

第一阶段:查找信息,以及为什么蹬 DS?

收集文本比较简单,本实习生人肉去搜索各大游戏论坛的攻略聚合站点,手动把链接记进本地表格,后续交给爬虫处理。
但从这一步开始,问题就初见端倪了:各大游戏论坛的站点极为复杂,样式不同,结构不同,有的甚至根本找不到入口。
即使是一些比较火爆的游戏,也有大量攻略网站访问报错。把国内外站点分别标记完,再估算一下规模,大约有几百万条攻略。

这个任务的难度确实有点大,让本实习生来做,多少有点犯难。
好在有很多实习生同事一起工作(强强联合!),大家收集得很快。领导也没有给压力,说这是实验性的工作。

那就放心大胆开干吧!

在人肉收集大量网址之后,理应写爬虫去爬取文章。但正如上面所说,一套通用爬虫很难直接适配海量异构的网页。对我们当时的任务来说,让人工智能参与站点适配和爬取,是一个更合适的选择。

一开始,我们尝试用当时考虑的方案中最便宜的 GLM 5.3F,可是这玩意太™慢了。换成 FlashX 会快很多,但成本极高,旁边的同事一天跑了 500 元。综合成本和速度考虑,我们没有继续使用 GLM 方案。

之后我们发现,在这批任务中,DS 有很大的优势:一是缓存命中率特别高,最高能达到 99.9%,成本降到了原来的 1/10 以下;二是速度很快,能达到 200 token/s 以上,足以支撑这个量级的需求。

在下载方面,我们整理出了一套方法:收集好站点地址之后,调用 DS,为每个站点编写适配的爬虫脚本。

有人要问了:铃仙铃仙!你刚才不是说爬虫搞不定海量异构的网页吗?怎么这次还是让 DS 写爬虫?

区别在于“谁来适配”。每个站点的结构确实都不一样,但同一站点内采用相同模板的文章,版式通常比较统一。让 DS 现场摸清站点结构,写一套适配的爬虫,再自己调用,就能批量爬取这个站点的内容。当然,同一站点也可能有多种模板,后续仍然需要处理例外。

我们在 DSH 中开启了大量对话框,使用同一套提示词,让各个对话框里的 DS 爬取不同站点的网页。最多的时候,同时开了四十多个子代理。
整个工作流最大的瓶颈是网络传输,我们当时能让四十多个子代理并发工作。在那台配备 16 核 CPU 的机器上,CPU 占用率大约为 70%。

第二阶段:怎么解析文件?

全部爬取下载到本地之后,最难办的事情就来了。
为了方便后续处理,我们把爬取到的网页都保存成了 PDF。结果,这批 PDF 什么问题都有:全文乱码、文件重复、版式奇异、广告比正文还多、正文为空、页面显示正常但文本层全是乱码……几乎一切能想到的问题都出现了。

补采网页信息

解析网页信息是很困难的一步:时间不能错,重点不能错,步骤不能错。因此,针对每篇攻略,我们至少需要两步操作:

  1. 回到原网页再取一遍信息;
  2. 读取正文再取一遍信息。

采集网页时,我们犯了一个大错:应该在采集之前就明确需要收集哪些信息,尽可能一次取全,避免后续大量重复访问网页。
这消耗了大量额外的 token,也为后续工作埋下了隐患。

于是,新问题来了:如果回到原网页收集信息,得消耗多少 token、花多少钱?这似乎取决于具体的处理方式。我属于用量较大的,印象中,每处理一万个文件大概要 20 元,还仅仅是“联网过一遍”的消耗。更精确的数字我已经记不清了,涉及内部细节的部分也不便公开。

百万级别的文件,到底要多少钱?这很犯难。
在实验阶段,我是这样处理信息的:针对我所需要的多列信息,每一列我都写一个专用的脚本去收集。
这样的好处是足够专一,且收集效果很好,但很快就发现 token 消耗太大、速度也太慢。
原因很简单:网页结构差异很大,即使是同一个站点,不同栏目或不同模板下的页面,结构也可能截然不同。

一个脚本完全做不到通用,并且一个脚本只能收集一列信息,效率很低下。
为什么不同时收集多列信息呢?我们也尝试过。但字段一多,不同版式、异常情况和字段之间的依赖就会交织在一起,需要处理的情况迅速增多。DS 当时还无法稳定处理这么复杂的问题。

最终的解决方式,还是人工智能,只是换了任务组织方式。在当时的条件下,既要效率,又要降低成本,我们只能在准确率上做一点妥协。
参考实习生同事的做法,我们让每个对话框里的 DS 单独负责某个领域和站点。这样一来,它反而能比较顺畅地收集该站点所需的各项信息。多开几个对话框,一个上午就能处理上万条信息。
不过,这里特别不建议盲目多开。多开对人的心智负担太大,实在记不住那么多上下文。

我们观察了 DS 的做法,发现它其实还是在用脚本,但思路完全不同。
它抓取了该网页的全部信息,写一个处理脚本,把其中一大段相关内容整块切出来,然后它自己直接把结果写出来。
这样一批能同时处理好几十条,成本和准确率都在可接受范围内。

提取正文与 OCR

再之后,就是读取正文、解析数据。这一步其实一直没有好的办法:有些 PDF 的文本层混乱或损坏,有些正文则以图片形式嵌在 PDF 中,无法直接提取文字。

使用 OCR(光学字符识别)似乎是个很自然的选择。我原以为可以直接让 DS 识别这些内容,但当时使用的环境里,它表示没有这个功能。

那好吧,我们又考察了一些 OCR 和 PDF 文本提取方案。下面是当时在我们的设备和文件样本上的体验:

方案 优点 遇到的问题
使用 GPU 的 OCR 模型 准确率很高! 资源占用大,在现有设备上难以提高并发;部署麻烦,经常报错;部分工作机没有可用 GPU
使用 CPU 的 OCR 模型 部署相对简单,可以并发! 当时测试的方案速度较慢,不到 GPU 方案的 1/5
用 pypdf / PyMuPDF 直接提取文本层 方便、快! 受源文件文本层质量影响,这批文件中大约一半提取失败,或结果不可用

我们的需求其实很明确:轻量、快、可并发,精度不用太高,毕竟要认的只是网页截图里那种规规矩矩的印刷体文字,不是手写件。

可是一直没找到合适的。

就这样研究了两天,和旁边的同事交流后,发现 Windows 提供了 OCR 接口(Windows.Media.Ocr 命名空间下的 OcrEngine)。
它很符合我们当时的要求,能快速获取可用的正文内容。在当时的设备和文件样本上,处理速度大约是每小时 3,000 份文件。

我立刻在本机封装了一个 Python 服务,前面挂了个队列来调度任务。这里还踩了个坑:服务没写好,多个对话框并发调用时,会导致整个 DSH 卡死,具体原因还不清楚。

取得了突破性的进展,我们获取了几乎所有文件的正文……除了部分损坏的文件。

第三阶段:如何拷打 DS 来整理信息?

收集完信息后,还需要按字段整理,再依次填进数据表。我们继续交给人工智能处理。

DS 确实很好,但是,慢工出烂活,欲速则一坨。说白了,你把这事交给大肥鱼,你也没把这事当回事。

批量处理与字段提取

我们处理的游戏,攻略数量差距极大:多的十万条以上,少的只有几十条。
照着采集阶段的经验,分别给大肥鱼两个任务,一个任务是处理几十条攻略,一个任务是处理几千条攻略。
令人惊讶的事实是,这两个任务的处理效率很接近。

如果让 DS 去处理几十条信息,它大概率会一次读一条信息,然后输出一条信息。
如果让 DS 去处理几千条信息,它大概率会一次读几十条信息,然后一次输出几十条信息。

这个差异很恐怖,这说明常规的处理思路行不通。

  1. 你不能强制它固定批量。 因为信息与信息之间区别很大,这样整理出来的信息质量差距很大。
  2. 你也不能让它自行分配。 它大概率按文件字数来分,遇到长文件就会保守地切成极多批次,效率反而低得离谱。
  3. 用规则匹配看似可行,实则很复杂。 OCR 输出的正文依然有不少错误(哪怕原文全是印刷体),规则一旦错配,就可能影响后续字段。因此,需要加入大量容错逻辑;而容错分支和字段越多,规则之间的冲突与误匹配也就越难控制。

这个问题其实很难处理。到了任务后期,处理出来的信息大概只能填满数据表的 95%,而且已填写的内容仍有不少错误。

最终的处理方法是:用匹配条件较宽松的正则表达式做粗筛。针对每个文件,把匹配到的相关文本交给 DS,要求它直接阅读并提取信息,禁止再次使用规则匹配,完成后写回数据。
好处是成本较为低廉,并且效率很高,至于准确性……

补全信息与多轮纠错

这时候有的小伙伴要说了:铃仙铃仙!你说的这些问题不是很基本的吗?AI 读一遍就处理完了,哪有技术含量?

此时,潜藏已久的问题浮出了水面:网页信息是由 AI 采集的,准确率一坨。
回头看,第一轮收集之后,我们的填写率只有 60% 左右。很多网页的信息没有采集完整,或者采集结果有误,直到后续检验时,我们才重新重视起来。

错误处理方面,依旧是人工智能代替能工智人(本实习生敲冒烟了,都比不上 DS 的效率啊)。

成本最高的大概也就是这方面,针对缺失的信息,我们还是得把整个网页重新读一遍;第二轮处理时,顺便把第一轮的错误也捞出来修。
DS 的大手发力了,但它不太能稳定地完成纠错:修正一段信息时,往往又会改错另一段,错误率居高不下。
这里只能强行硬撑了:收束每个对话框的任务范围,减少需要同时处理的上下文,尽量提高准确率。这样做确实提高了处理效率。
有时还要重新调用 OCR 服务来处理正文,或者回到游戏论坛抓取原网页(又能顺便看一遍游戏!)。
我们访问的大部分站点都有访问限制,短时间内请求过于频繁,就可能触发限制,导致任务无法继续。这使得我们操作时很谨慎。
但是 DS 就不一样了,它写的脚本经常没有考虑访问频率。某次,它以每秒 1,300 次请求的频率访问网站,结果我们的 IP 直接被封禁了。唉唉……

纠错是多轮的,我们花了很多很多的时间去纠错。

统一信息格式

纠错结束后,就是梳理信息格式。这里要求 DS 读取每列信息的去重值集合,直接检查格式或内容上的明显错误,再修改对应数据,而不是另写规则来判断。
这一步比较简单,处理起来很方便。

高血压:使用体验与吐槽

写这篇文章时,我正好用上了 DS 的 1017 版本。网上吹得很牛逼,但是我用起来,高血压犯了。
指令遵从度不行,能力不行,智商不行。记忆(memory)里的东西记不住,上一句刚定好的规则,下一句就忘。
经常无视沟通要求(即使我明确要求“做之前先问我”),自顾自跑十几分钟的神秘代码,然后回来告诉我某个任务做完了,留下一地错误。

“有两件事需要你拍板。”

“我发的模板指纹错了两次。”

“有一件事我没法自己决定。”

“我核对了一下,事实分三部分,其中两种是我的错。”

它根本不知道自己在做的东西是什么。针对这一点,群友说得很好:

群友对 DS 使用体验的评论截图

用起来血压很高。

个人感觉,不完全是上下文过长的问题,因为有时第二轮对话就开始犯错。

我总结了一个观察信号:如果已经要求“做之前先问我”,但发完交接文档后,它还是直接开始任务,那这个对话框的指令遵从表现可能不太行。

某些聊天框存在神魔二象性,某些聊天框很聪明,某些聊天框则蠢完了。

它“智力低下”的具体表现还有很多:

  • 不会用子代理。 让它开大量子代理并发处理任务,它会先自己把活儿干得差不多,然后让子代理去执行脚本收个尾,白白浪费大量时间。
  • 记不住事。 上文刚说“不要管时间相关的东西”,下文就问“你要改时间 A 还是时间 B,你确认之后我们就开始执行”;要么就是看到交接文档后一声不吭,直接静默执行。
  • 无限套娃式自测。 先测试一遍,再试运行(dry run)一遍,回头又是十几分钟思考、改脚本、再测试一遍、再试运行一遍……
  • 文档写得巨史无比。 全文充斥无意义的语义噪声,不说人话,几乎完全是为 AI 服务的。我强制要求它写得像人话一点,一轮之后直接忘光,还顺带开启了几十分钟的静默大思考。
  • 项目意识薄弱。 工具和文档乱放,特别喜欢在垃圾桶文件夹里操作。即使我明令禁止,它也会先说“好的,接下来我不会在垃圾桶里操作”,然后——继续在垃圾桶里操作。

问题实在太多了。即使整理出了和 DS 的聊天记录,我也不想再总结了,心智负担实在太大。

最后的最后

推销一下自己:有没有项目缺人?本人 Go 全栈 😭

来源:博客园 · cnblogs.com