基于 Qwen/Qwen2.5-1.5B-Instruct 微调(SFT + LoRA),并自建 Agent 全链路(ReAct 循环 + 工具调用 + RAG 检索 + 长短期记忆 + 提示注入防御 + 护栏)的游戏 NPC 对话系统。
玩家输入 → NpcAgent(ReAct 循环)
├─ think :LLM 结构化决策动作(retrieve_lore / recall_memory / query_environment / none)
├─ act :ToolRegistry 执行工具(检索 / 记忆 / 环境)
├─ observe :工具结果回填上下文
├─ generate :LLM 生成回复
├─ guardrail:输出护栏(角色跳出 / system 泄露 / 禁忌)
└─ 写回 :记忆保存 + 超预算滚动压缩
核心模块(三端分离):
agent/:ReAct 循环(agent.py)、工具调用(tools.py)、长短期记忆与压缩(memory.py)、提示注入防御与护栏(guardrails.py)、人设(persona.py)、评估(eval.py)rag/:检索(retriever.py)、向量索引(index.py,NumPy 点积 + 元数据过滤 + 阈值)、embedding(embedder.py,char-ngram 词法 / bge-m3 语义)、评估(eval.py,hit@k)llm/:生成引擎(engine.py,支持 dry-run 预览,不占显存)api/:FastAPI 服务化(server.py)01_download~05_inference:SFT 微调流水线(下载 → EDA → 清洗 → LoRA 训练 → 合并 → 推理对比)
01_download/:下载模型与数据集02_analysis/:EDA、tokenizer 与长度分布统计03_clean/:清洗、统一 ChatML、划分数据集04_training/:LoRA 训练、合并、评测05_inference/:聊天、基准、前后对比agent/、rag/、llm/、api/、core/、scripts/:Agent 应用层lore/:世界观知识库(RAG 检索源)personas/:NPC 人设卡(YAML)
pip install -r GameDialogue/requirements.txt
pip install -e . # 可编辑安装,解决 ModuleNotFoundError语义 embedding 后端 bge-m3 需额外安装:
pip install sentence-transformers(默认 charngram 零依赖)。 FastAPI 服务需额外安装:pip install fastapi uvicorn。
# 下载数据与模型(需 HuggingFace 令牌)
python GameDialogue/01_download/download_dataset.py
python GameDialogue/01_download/download_model.py
python GameDialogue/01_download/verify.py
# EDA
python GameDialogue/02_analysis/dataset_statistics.py
python GameDialogue/02_analysis/length_distribution.py
# 清洗(去空 → NFKC 归一化 → SHA-1 去重 → ChatML 统一 → 划分)
python GameDialogue/03_clean/remove_null.py
python GameDialogue/03_clean/normalize_text.py
python GameDialogue/03_clean/remove_duplicate.py
python GameDialogue/03_clean/convert_chatml.py
python GameDialogue/03_clean/split_dataset.py
# LoRA 训练(r=4 / alpha=8 / q-k-v-o / 梯度累积 / checkpointing)
python GameDialogue/04_training/train_lora.py
# 合并 LoRA
python GameDialogue/04_training/merge_lora.py
# 推理对比
python GameDialogue/05_inference/compare_before_after.py支持 6 个子命令,默认 dry-run(不加载模型、只预览 prompt/轨迹,无需 GPU),加 --live 才真实生成:
# 建向量索引(增量缓存),--eval 顺带跑检索命中率
python GameDialogue/run_agent.py build-index --embedder charngram --eval
# 纯检索检查(不加载生成模型)
python GameDialogue/run_agent.py search --query "官银是谁偷的?" --embedder charngram --k 3
# M2 对话(人设 + 检索)
python GameDialogue/run_agent.py chat --persona elder_li --rag --once "官银是谁偷的?"
# M3 Agent 模式(记忆 + 工具 + ReAct 循环)
python GameDialogue/run_agent.py run --persona elder_li --rag --once "官银是谁偷的?"
# 对比实验(有无 persona / 有无 RAG)
python GameDialogue/run_agent.py compare --rag
# 单条回复一致性检查
python GameDialogue/run_agent.py eval --reply "..." --persona elder_li真实生成加 --live,例如:
python GameDialogue/run_agent.py run --persona elder_li --rag --live --once "官银是谁偷的?"uvicorn GameDialogue.api.server:build_app --factory --port 8000models/、datasets/、outputs/(模型权重、数据集、训练产物)已 gitignore,需按上面步骤自行下载 / 生成。- 生成参数(temperature / top-p / top-k / max-new-tokens)在
llm/config.py的GenerationConfig中定义,运行时可通过命令行覆盖。