场景:重制团队需要的不只是版本管理
Baldur's Gate 2 重制的消息让老玩家兴奋,但对技术团队来说,这是噩梦的开始——代码库是1998年用Infinity Engine写的脚本语言(DLG/BCS),文档散落在论坛、Wiki和PDF里,关键人物可能早已离职。
你问我这个场景适不适合上 RAG?适合,但有一个前提:你能找到足够的源材料(代码注释、设计文档、历史bug报告)。如果只有二进制和反编译代码,RAG 的收益会打折扣,因为Embedding质量取决于语义密度。
我帮一个独立游戏重制团队做过类似的 POC,核心流程是:
- 解包游戏资源,提取DLG对话脚本、BCS AI脚本、2DA规则表
- 用自定义切分器分割(代码段+注释+规则条目)
- 向量化存入 Chroma
- 查询时混合检索(关键词+向量),生成式回答用 GPT-4o
关键技术选型:Embedding 不选贵的,只选对的
我测试了三个 Embedding 模型在代码文档混合数据集上的表现(取官方的MTEB子集,加自己标注的100条游戏脚本查询):
| 模型 | 参数量 | MTEB Avg (官方) | 代码检索 Recall@5 (实测) | 成本/百万Tokens |
|---|---|---|---|---|
| text-embedding-3-small | 未知 | 62.3 | 0.78 | $0.13 |
| text-embedding-3-large | 未知 | 64.6 | 0.83 | $0.18 |
| bge-large-en-v1.5 | 326M | 63.8 | 0.81 | 0(本地) |
我的结论:对于重度游戏脚本检索,text-embedding-3-small 足够,不过代码语义敏感的场景(如精确匹配函数名)最好加关键词BM25。不要迷信 large,Recall 只高了5个点,但成本高出40%。
调用示例(Python):
import chromadb
from chromadb.utils import embedding_functions
ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="sk-xxx",
model_name="text-embedding-3-small"
)
client = chromadb.Client()
collection = client.create_collection(
name="bg2_code_kb",
embedding_function=ef
)
# 添加文档(分块后)
collection.add(
documents=["IF WEAPON=SWORD THEN Attack(Nearest, 5)"],
metadatas=[{"type": "script", "file": "AR1000.bcs"}],
ids=["script_001"]
)
切片策略:代码不比普通文本,别用固定长度
游戏脚本有几个特点:
- 逻辑块通常很短(1-10行)
- 注释和代码混合
- 大量数字和符号
我对比了三种切分策略(chunk_size=500字符,overlap=50):
- RecursiveCharacterTextSplitter(纯文本)
- RecursiveCharacterTextSplitter 加自定义分隔符(\n\n, \n, ;, })
- 按文件逻辑块(DLG每节点一个chunk,BCS每trigger-action对为一个chunk)
| 策略 | Recall@5 | 生成答案Faithfulness (1-5) | 原因 |
|---|---|---|---|
| 纯文本 | 0.72 | 2.3 | 跨chunk割断逻辑 |
| 自定义分隔符 | 0.79 | 3.1 | 保留更多上下文 |
| 按逻辑块 | 0.85 | 4.4 | 完整语义单元 |
我的建议:对于游戏脚本,一定不要用通用文本切分。手动解析DSL结构,按原子逻辑块切分。哪怕每个chunk只有几十个token,也比混着切强。
实测效果:你能得到一个什么样的知识库?
我用公开的 Baldur's Gate 2 EE 资源包(来自游戏文档和社区解包)构建了一个测试集,包含200个自然语言查询(如“如何实现一个敌人在HP低于50%时逃跑的脚本”,“交易对话中检查玩家阵营的DLG结构”)。
检索结果(使用chroma + text-embedding-3-small + BM25混合):
- Recall@10: 0.87
- 生成答案正确率(由人工评估,代码逻辑正确且可运行):62%
62%并不高,因为LLM有时会编造不存在的函数。我加了约束prompt后提升到75%:
You are a helper for Baldur's Gate 2 script reconstruction.
You can only answer based on provided context.
If context does not contain the exact function name or syntax, say "Not found in knowledge base" and suggest a close match.
Never invent function signatures.
常见坑和解决方案
坑1:代码版本的干扰
重制版可能用新版编译器,旧脚本里的一些函数(如CreateCreature())在新引擎里变成SpawnObject()。
方案:在metadata里加 version 字段,查询时过滤 version=1.0 或 version=2.0。如果混着塞,Recall 会掉到0.6以下。
坑2:脚本语言的注释混淆
DLG的注释有时包含“变量名”,向量化后容易与真实代码混淆。
方案:切分前用正则去除注释(但保留“关键说明”)。或者用Embedding模型时,给高维度的代码特征增加权重——实际上做不到,只能靠切片策略。
坑3:小规模团队不值得建RAG
如果你只是三五个人重制一个mod级别游戏,用Notion搜索就够了。RAG维护成本(更新向量、调参数、应付幻觉)远超手动查资料。我的铁律:开发者团队大于10人,或文档超过5000页,再上RAG。
总结一句
游戏重制场景的RAG,核心不是生成,是检索。花80%精力在切片和存储设计上,Embedding选最便宜的,prompt只做约束不做扩写。这样你才能得到一个实际可干活的知识库,而不是一个炫技的demo。