Skip to content
Projects

weir36/novel-config-copilot

View on GitHub

weir36/novel-config-copilot has 27 GitHub stars and 0 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 03:22 UTC. Last push 2026-11-03.

How these counts are measured

Measured star growth

in 24h
0
in 7 days
Collecting history
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

About

网文平台资源配置决策助手:GraphRAG 两阶段检索 + ReAct Agent + 规则引擎兜底,方案合法率 60%→100%

AI

README.md

Original

网文作品资源配置助手

面向网文平台编辑的资源配置决策系统。把散落在政策文档里的配置知识结构化成知识图谱, 用 GraphRAG 做检索、ReAct Agent 做多步推理、确定性规则引擎做兜底校验, 回答「这个配置项怎么开」「给这本书配一套方案」「作者为什么没拿到全勤」。

项目里的政策、比例、金额、门槛、作品和作者全部是模拟数据,不代表任何真实平台。

┌──────────┐   ┌──────────┐   ┌──────────┐   ┌─────────────┐   ┌──────────┐
│ 意图识别 │ → │ 追问识别 │ → │ GraphRAG │ → │ ReAct Agent │ → │ 规则引擎 │
│ 3 类+越界│   │ 挑相关轮 │   │  两阶段  │   │  7 个工具   │   │ R001~004 │
└──────────┘   └──────────┘   └──────────┘   └─────────────┘   └──────────┘
   越界短路     新话题不带历史   实体→子图→文本     查/校验/试算      确定性判定

跑起来

make demo      # 装依赖 → 离线建库 → 跑测试 → 跑全部离线评测
make serve     # 打开 http://localhost:8000

想要真实的生成质量,复制 .env.example 为 .env 填上 LLM_API_KEY(任意 OpenAI-compatible 网关:DeepSeek / 豆包方舟 / 通义千问 / 自建 vLLM 都行),然后:

make build                                              # 用 LLM 做关系抽取重建图谱
.venv/bin/python -m app.indexing.build --entities llm   # 实体也用 LLM 抽 + 四层消歧
make eval-all                                           # 含端到端和纯大模型对照

想跑生产形态的组件:make up(Neo4j + Redis + Elasticsearch)+ make install-full。


一、背景(STAR)

背景。 编辑要给签约作品配资源:新书要冷启动拿曝光,头部作品要冲榜保更新, 不同作品的配法完全不一样。后台的配置项分在签约、作者福利、推荐与扶持、阅读模式四类, 每一项还可能配在 频道 / 作者 / 作品 三个维度上,后者覆盖前者。

挑战。 配置项之间有依赖、互斥和组合约束,而且分散在不同的政策文档里:

  • 依赖链:日更字数要求 → 全勤奖 → 加更活动,只开最后一项会被拦
  • 互斥:新人作者扶持计划 ⊥ 大神作者计划、免费阅读模式 ⊥ 付费章节
  • 组合规则:买断作品不能开完本奖(R001)、开全勤奖时日更不低于 4000 字(R002)、 保底分成作品的作者分成不超过 50%(R003)、付费起点早于第 20 章会提示留存风险(R004)

最难的是组合规则:它涉及的配置项分在不同文档、不同页面,编辑配 A 时看不到 B 的当前值, 很容易出现「新配的项 × 没动的老项」组合违规。新编辑只能反复翻文档、问老编辑。

行动。 把政策文档结构化成知识图谱,用 GraphRAG 把跨文档的关系找全, 用 Agent 查当前配置、试算影响,用规则引擎对方案做确定性校验。

结果。 这是个人项目,没有真实用户,所以不写耗时、配错率这类线上指标。 能写的是下面「评测」一节里实测、可复现的过程指标; 「配错减少多少」用「纯大模型 vs 完整系统」的对照实验替代(需要 API key,见评测报告第五节)。


二、架构

离线:把政策文档变成可推理的结构

data/raw_docs/*.md(6 篇政策文档)
   ↓ 语义切块(按标题,不按固定字数)
chunks ──┬─→ embedding ─→ 文本向量索引
         ├─→ BM25      ─→ 关键词索引
         └─→ 实体 + 关系抽取 ─→ 知识图谱 ─→ 实体向量索引
  • 切块按标题。 "免费阅读模式与付费章节互斥"要和"免费阅读模式"这个主语留在同一段, 固定窗口切开的话,召回到哪一半都是残缺的。
  • 实体两种抽法(--entities vocab|llm):
    • 词表:配置项是封闭词表,按定义 100% 准,零成本,线上默认用它;
    • 大模型按 schema 抽 + 四层消歧(名字完全一致 → 统一大小写全半角后匹配 → 相似度够高的合并 → 对不上的进待审核,不自动进图)。它的价值是发现词表里还没有的新实体。
  • 关系靠抽。 规则(正则)/ 大模型 / 两者结合三种,对比见评测报告第三节。
  • 离线只从名单里拿名字和别名,关系一律从文档抽,不读 config_registry.yaml 里的答案 —— 否则等于把答案喂给系统,评测就没意义了。

在线:意图 → 追问 → 检索 → 生成 → 校验 → 记住

  1. 意图识别:解释 / 推荐 / 优化 3 类 + 越界。bge 句向量 + 逻辑回归 + 关键词先验,越界问题直接短路, 不进检索和 Agent。"作者为什么没拿到全勤"这类排查问题归在解释类,提示词单独要求定位到具体规则编号。
  2. 追问识别:判断这一句是不是接着上文问的。信号有四个:指代承接词、本轮配置项和上一轮焦点 在图上相邻、在改上一轮的方案、短问且没提配置项。是追问才带相关的历史轮次、做检索剪枝; 新话题两样都不做,免得上一个话题干扰这一轮。
  3. 两阶段检索(GraphRAG):
    • 第一阶段:把口语对应到标准配置项(向量 + 别名 + key 三路),在图上沿依赖、互斥扩展 1~2 跳;
    • 第二阶段:拿子图里每个实体的描述分别去做向量 + BM25 召回,加权融合,阈值过滤, 连同图谱三元组一起作为参考上下文。
  4. 生成:解释类单次生成;推荐 / 优化类走 ReAct Agent,7 个工具把必须精确的事交给代码 (查定义、查当前配置、校验、试算影响……)。
  5. 规则兜底:从回答里抽出方案,合并那本书 / 那个作者的当前配置后交给规则引擎,检查依赖、互斥、 取值、维度和 R001~R004。这一步是 Agent 收尾的闸门:有 error 就把违规项退回让它改(最多 2 轮), 还改不对就在回答上明确标「未通过,请勿直接使用」。
  6. 会话记忆:存结构化状态(每轮焦点实体、工作区方案),不是聊天原文。

三、评测

完整报告见 docs/eval-report.md(make eval 即可复现)。 所有题库都和训练样本分开;需要调参的两项(意图、追问)另有调参集,测试集只在定稿后测一次。

下表全部是 生产形态组件(bge + FAISS + Elasticsearch + Neo4j + Redis)实测,LLM 为 gemini-4-argon。

模块 指标 实测 口径
端到端 方案合法率 纯大模型 0.60 → 1.00 5 条出方案用例,规则引擎判定;12 条用例
端到端 关键信息覆盖率 纯大模型 0.77 → 1.00 回答是否提到必需的配置项 / 规则编号
意图识别 准确率 / 越界召回 0.917 / 1.000 测试集 36 条
检索 召回率(严格) 0.784 → 0.986 18 条;朴素向量 RAG → GraphRAG
检索 2 跳问题召回 0.723 → 1.000 增益集中在多跳问题上
检索 精确率 0.798 → 0.474 代价,见下
关系抽取 F1 规则 0.911 / LLM 0.851 37 条 gold 关系;规则偏乐观,见下
实体抽取 F1(LLM + 四层消歧) 0.962 24 个实体进待审核,不自动进图
追问识别 准确率 0.750 测试集 10 组对话、20 个轮次
单元测试 通过 71 / 71 make test

四、工程细节

每一类外部依赖都有 auto 模式:探测得到就用真实组件,探测不到降级到本地实现, 并在启动日志和 /api/health 里明确打印实际选中的后端。

组件 生产形态 本地降级
向量检索 FAISS IndexFlatIP numpy 矩阵乘法
关键词检索 Elasticsearch BM25 rank_bm25
知识图谱 Neo4j(变长路径 Cypher) networkx BFS
会话状态 Redis(TTL) 进程内 LRU
Embedding bge-small-zh-v1.5 内置 TF-IDF
LLM 任意 OpenAI-compatible MockLLM(确定性占位)

五、目录结构

app/               按模块划分,每个文件夹是一个完整的功能模块
  foundation/      底座:models(数据格式)、settings(设置)、registry(配置项名单)
  indexing/        离线建库:chunker(切块)/ extract(实体与关系抽取、消歧)/ build(建库主流程)
  retrieval/       检索:embedder / vector_store / keyword_store / graph_store /
                   entity_linker / fusion / graphrag(两阶段编排,含 4 种消融模式)
  intent/          意图识别
  generation/      生成:llm_client(OpenAI-compatible + MockLLM)/ prompts(分意图提示词)
  validation/      校验:rule_engine(R001~R004)/ plan_extract(回答 → 结构化方案)
  agent/           Agent:ReAct 循环 / 7 个工具
  session/         会话记忆 + 追问识别
  chat/            主流程:pipeline(含流式)
  server/          对外接口:FastAPI

data/
  raw_docs/        6 篇政策文档(模拟,在线链路唯一的知识来源)
  gold/            config_registry.yaml(16 个配置项 + 4 条规则)+ 题库(调参集 / 测试集分开)
  config_store/    模拟的当前配置(2 个频道 / 3 个作者 / 4 本书)
eval/              意图 / 检索消融 / 图谱与实体抽取 / 追问识别 / 端到端 + report 汇总
tests/             71 个单元测试
web/               零构建前端

六、已知局限

  1. 语料规模小。 16 个配置项、6 篇文档、40 个 chunk,图上 2 跳几乎能走遍, 评测结论在更大规模语料上不一定同样成立。
  2. 文档是自己和ai写的。 关系抽取的指标因此偏乐观;真实场景要用编辑真正写的文档重新评测。
  3. 端到端样本小:12 条用例里只有 5 条出方案,方案合法率的差距是 5/5 vs 3/5,统计上站不住。 要下更强的结论需要扩充用例。
  4. estimate_impact 的影响系数是人工设定的,只用来给 Agent 一个量级感,不是精确预测。
  5. 识别"哪本书"靠正则(B\d{3} / W\d{4}),用户说书名而不是编号时,校验不会合并当前配置。
  6. 追问识别是规则做的,漏判偏多;"那 X 呢"这类追问在意图识别上也容易判错类别(比如判成优化), 可以考虑追问时继承上一轮的意图。