weir36/novel-config-copilot
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.
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%
AIREADME.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里的答案 —— 否则等于把答案喂给系统,评测就没意义了。
在线:意图 → 追问 → 检索 → 生成 → 校验 → 记住
- 意图识别:解释 / 推荐 / 优化 3 类 + 越界。bge 句向量 + 逻辑回归 + 关键词先验,越界问题直接短路, 不进检索和 Agent。"作者为什么没拿到全勤"这类排查问题归在解释类,提示词单独要求定位到具体规则编号。
- 追问识别:判断这一句是不是接着上文问的。信号有四个:指代承接词、本轮配置项和上一轮焦点 在图上相邻、在改上一轮的方案、短问且没提配置项。是追问才带相关的历史轮次、做检索剪枝; 新话题两样都不做,免得上一个话题干扰这一轮。
- 两阶段检索(GraphRAG):
- 第一阶段:把口语对应到标准配置项(向量 + 别名 + key 三路),在图上沿依赖、互斥扩展 1~2 跳;
- 第二阶段:拿子图里每个实体的描述分别去做向量 + BM25 召回,加权融合,阈值过滤, 连同图谱三元组一起作为参考上下文。
- 生成:解释类单次生成;推荐 / 优化类走 ReAct Agent,7 个工具把必须精确的事交给代码 (查定义、查当前配置、校验、试算影响……)。
- 规则兜底:从回答里抽出方案,合并那本书 / 那个作者的当前配置后交给规则引擎,检查依赖、互斥、 取值、维度和 R001~R004。这一步是 Agent 收尾的闸门:有 error 就把违规项退回让它改(最多 2 轮), 还改不对就在回答上明确标「未通过,请勿直接使用」。
- 会话记忆:存结构化状态(每轮焦点实体、工作区方案),不是聊天原文。
三、评测
完整报告见 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/ 零构建前端
六、已知局限
- 语料规模小。 16 个配置项、6 篇文档、40 个 chunk,图上 2 跳几乎能走遍, 评测结论在更大规模语料上不一定同样成立。
- 文档是自己和ai写的。 关系抽取的指标因此偏乐观;真实场景要用编辑真正写的文档重新评测。
- 端到端样本小:12 条用例里只有 5 条出方案,方案合法率的差距是 5/5 vs 3/5,统计上站不住。 要下更强的结论需要扩充用例。
estimate_impact的影响系数是人工设定的,只用来给 Agent 一个量级感,不是精确预测。- 识别"哪本书"靠正则(
B\d{3}/W\d{4}),用户说书名而不是编号时,校验不会合并当前配置。 - 追问识别是规则做的,漏判偏多;"那 X 呢"这类追问在意图识别上也容易判错类别(比如判成优化), 可以考虑追问时继承上一轮的意图。