从“AI 出版编辑“到“知识型 AI 产品专家“:一次主动的天花板突围







你已经把问题想得很清楚了,我接下来做的不是重复你的判断,而是把这套战略往下推一层——告诉你:为什么这条路在 2026 年是对的、它的真实难点在哪里、你具体怎么走才能不掉进坑里。
一、先回到一个根本问题:你为什么必须跳出"出版"这个词?
出版业不是没有未来,但它的经济结构决定了天花板。一个图书编辑年薪上限大概率卡在 25–40 万,即便你做到出版社数字化负责人,也很难突破。原因不在你的能力,而在于:
**出版业是一个"低 ARPU + 慢周转 + 文化属性强"的行业。**它的付费能力撑不起高薪 AI 岗位。哪怕你把 RAG 做到极致,出版社愿意为这件事付的预算,可能也就是几十万一年的项目费。
但是——同样的 RAG 能力,搬到下面这些场景里,价格立刻翻 5–20 倍:
| 场景 | 客户付费意愿 | 关键词 |
|---|---|---|
| 图书知识库 | 几万到几十万 | 内容资产 |
| 企业制度/SOP 知识库 | 几十万到几百万 | 合规、效率 |
| 法律法规知识库 | 上百万 | 风险、专业服务 |
| 医疗/金融研报知识库 | 数百万到千万 | 决策、收益 |
| 政府/央企知识中台 | 千万级 | 数字化转型预算 |
所以你"Publishing as a Case Study"这个定位非常精准。出版是你最熟的样板间,但客户不能只是出版社。你卖的是"处理高密度知识文本的能力",而不是"懂书"。
二、这个作品集真正的核心竞争力是什么?
你列出来的五大模块都对,但如果不抓住一根主线,外人看上去会觉得"什么都做了,又什么都不深"。我建议你把整个作品集的核心叙事收敛成一句话:
“我能把一堆非结构化的专业文本,变成可被 LLM 准确调用、可被人类信任的知识系统。”
这句话里有三个关键词,每一个都对应你作品集的一个底层能力,也对应市场上最稀缺的三种人:
1. “非结构化的专业文本” → 你懂内容
这是图书编辑的真实优势,不是劣势。市面上 90% 做 RAG 的工程师,看一本《资治通鉴》、一份招股说明书、一篇 SCI 论文,他们不知道哪里是重点、哪里是噪音、哪里会出歧义。你知道。这种"内容判断力",工程师团队请不到。
2. “可被 LLM 准确调用” → 你懂技术边界
这是你需要补的那一块——不是去写 CUDA 内核,而是要懂:
- chunking 策略对召回的影响
- embedding 模型选型
- rerank 的必要性
- 为什么有时候要用 GraphRAG,有时候不用
- 评测集怎么设计才能反映真实业务
3. “可被人类信任” → 你懂评估
这是被严重低估的能力。LLM 内容质量评估这件事,2026 年正在从"加分项"变成"刚需",尤其是在监管收紧之后。能做幻觉检测、忠实度评估、引用核查的人,市场极度稀缺。而这恰好是图书编辑的"校对、核查、勘误"能力的直接迁移。
所以你真正的人设不是"懂 AI 的编辑",而是"懂内容的 AI 评估与知识工程师"。
三、作品集的五大模块,应该按什么顺序做?
你列的五块都很好,但如果一起铺,会做不完、做不深。我建议按"先立信、再展深、后提产"的顺序:
第一阶段(1–2 个月):先做 LLM 内容质量评估
为什么先做这个?因为:
- 它最能体现你"编辑出身"的独特视角,别人做不出你这个味道。
- 它产出快,可以做成一篇篇 case study 文章,在知乎、公众号、即刻、CSDN、Medium 同步发。
- 它是当前最热的话题之一(2026 年大模型监管、Agent 落地都在催这件事)。
具体可以做:幻觉案例库(从你校过的真实书稿里找 LLM 改稿的失误)、引用准确性测试(让 GPT/Claude/Gemini/Qwen/DeepSeek 处理同一段学术原文,对比引用还原度)、忠实度评测集设计。
第二阶段(2–3 个月):RAG 知识库实验
做四个有代表性的小型 RAG 系统:
- 一本你编过的书(展示"内容理解" )
- 一份公开企业制度(比如某上市公司年报+员工手册,展示"商业场景")
- 一批学术文献(展示"研究场景")
- 一组法规文本(展示"合规场景")
**关键不是把它们做出来,而是写清楚每一个为什么这样切分、为什么这样设计元数据、踩了哪些坑。**这正是你作为编辑的叙事优势。
第三阶段(2 个月):AI 工作流设计
这一步你已经从"做实验的人"升级为"设计系统的人"。挑 2–3 个工作流深做,比如:
- 编辑审稿全流程(初审-复审-终审,每一步 AI 在哪里介入,人在哪里把关)
- 研报/政策解读流程(这块结合你的 fsQCA 背景特别有用)
第四阶段(持续):产品方案沉淀
等前面三步有了真东西,再开始写产品方案文档。反过来做会很虚——很多人就是从产品方案开始做,结果通篇 PPT 话术,没有实物。
四、你最容易踩的三个坑
坑 1:把作品集做成"博客合集"
五大模块全是文章,没有一个能跑起来的 demo,这样找工作时面试官一问"能不能现场演示",就垮掉。至少要有 1–2 个能在线访问的 RAG demo(用 Streamlit/Gradio + 一个轻量后端就行,部署在 HuggingFace Space 或 Vercel 上)。
坑 2:技术深度不够,被工程师面试官秒杀
“AI 知识产品经理"这个岗位的面试官,经常是技术背景。你要避免被问到"你这个 chunking 是怎么定的"时只能回答"我用了默认参数”。建议你在每个 RAG 实验里,至少跑一次 ablation(对比不同 chunk size、不同 embedding 模型、有无 rerank 的效果差异),数据写进作品集。
坑 3:目标行业太散,反而没有客户记得你
"知识密集型行业"包含太多——出版、教育、科研、法律、咨询、医疗、金融……一个人不可能全打。我建议你第一年聚焦三个:
- 出版/教育(你最熟,第一份样板间)
- 科研/学术(你正在读博考虑中,自己就是用户,容易做出真东西)
- 法律/合规(付费能力强,与编辑的"准确性洁癖"高度契合)
后面三个等你站稳了再扩展。
五、把"野心目标"翻译成可执行的 12 个月路线图
你说想成为 Dan Li 那样的人——有技术含量、有国际视野、做高价值产品。这背后其实是三个具体的能力门槛:
| 能力 | 当前你的水平(估计) | 12 个月目标 |
|---|---|---|
| 内容判断与知识组织 | 强(编辑本职) | 形成方法论,可以教人 |
| RAG/评估技术实操 | 入门到熟悉 | 能独立设计中等复杂度系统 |
| 英文产出与国际能见度 | 弱(估计) | Medium/LinkedIn 持续输出英文内容 |
**最后一点经常被中文环境的求职者忽视,但它恰恰是天花板的关键。**Dan Li 这类人的差异不只是技术,而是 ta 的内容能被全球同行看到。你完全可以把作品集做双语版本——中文发知乎/公众号,英文发 Medium/LinkedIn/Substack,同样一份工作,曝光面扩大 5 倍以上。
六、最后一句
你现在最大的资产其实不是"图书编辑的身份",也不是"AI 的兴趣",而是——你能在文本的细节里看到别人看不到的东西。这件事在 LLM 时代是稀缺品。
把这件事往技术和产品的方向延伸,而不是往传统出版的纵深方向钻,你的天花板会从 40 万抬到 80–150 万,甚至更高。出版只是你的第一块跳板,它的价值不在于你留在那里,而在于你曾经把它做透过。
id: knowledge_ai_lab_site_v01
name: Knowledge AI Lab 单页静态站点 v0.1
type: html
content: |-
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Knowledge AI Lab|RAG、内容评估与 AI 工作流实践</title>
<meta name="description" content="Knowledge AI Lab:面向知识型工作的 RAG、内容评估与 AI 工作流实践。Publishing as a Case Study." />
<style>
:root{
--bg:#0f172a;
--panel:#111827;
--panel2:#1e293b;
--text:#e5e7eb;
--muted:#94a3b8;
--line:#334155;
--accent:#38bdf8;
--accent2:#a78bfa;
--white:#ffffff;
--green:#34d399;
--yellow:#fbbf24;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",Arial,sans-serif;
color:var(--text);
background:
radial-gradient(circle at 20% 10%, rgba(56,189,248,.18), transparent 28%),
radial-gradient(circle at 80% 0%, rgba(167,139,250,.18), transparent 30%),
var(--bg);
line-height:1.7;
}
a{color:inherit;text-decoration:none}
.wrap{width:min(1120px,92vw);margin:0 auto}
header{
position:sticky;top:0;z-index:99;
backdrop-filter:blur(16px);
background:rgba(15,23,42,.76);
border-bottom:1px solid rgba(148,163,184,.18);
}
nav{
height:68px;
display:flex;
align-items:center;
justify-content:space-between;
}
.brand{
font-weight:800;
letter-spacing:.2px;
}
.brand span{color:var(--accent)}
.links{
display:flex;
gap:22px;
font-size:14px;
color:var(--muted);
}
.links a:hover{color:var(--white)}
.hero{
padding:96px 0 72px;
}
.badge{
display:inline-flex;
align-items:center;
gap:8px;
padding:7px 12px;
border:1px solid rgba(56,189,248,.3);
border-radius:999px;
color:#bae6fd;
background:rgba(2,132,199,.12);
font-size:14px;
margin-bottom:24px;
}
h1{
font-size:clamp(46px,8vw,84px);
line-height:1.02;
margin:0 0 20px;
letter-spacing:-2.8px;
}
.gradient{
background:linear-gradient(90deg,var(--white),#bae6fd,#ddd6fe);
-webkit-background-clip:text;
background-clip:text;
color:transparent;
}
.subtitle{
font-size:clamp(20px,3vw,30px);
line-height:1.35;
color:#cbd5e1;
max-width:920px;
margin:0 0 22px;
}
.lead{
font-size:18px;
color:var(--muted);
max-width:820px;
margin:0 0 34px;
}
.cta{
display:flex;
flex-wrap:wrap;
gap:14px;
}
.btn{
display:inline-flex;
align-items:center;
justify-content:center;
padding:13px 18px;
border-radius:12px;
font-weight:700;
border:1px solid rgba(148,163,184,.28);
}
.btn.primary{
background:linear-gradient(135deg,var(--accent),var(--accent2));
color:#020617;
border:none;
}
.btn.secondary{
background:rgba(15,23,42,.55);
color:#dbeafe;
}
section{
padding:58px 0;
border-top:1px solid rgba(148,163,184,.15);
}
.section-title{
display:flex;
align-items:flex-end;
justify-content:space-between;
gap:20px;
margin-bottom:26px;
}
h2{
font-size:34px;
line-height:1.2;
margin:0;
letter-spacing:-.8px;
}
.kicker{
color:var(--accent);
font-weight:800;
text-transform:uppercase;
letter-spacing:.12em;
font-size:12px;
margin-bottom:8px;
}
.muted{color:var(--muted)}
.grid{
display:grid;
grid-template-columns:repeat(4,1fr);
gap:16px;
}
.card{
background:linear-gradient(180deg,rgba(30,41,59,.92),rgba(15,23,42,.88));
border:1px solid rgba(148,163,184,.18);
border-radius:18px;
padding:22px;
box-shadow:0 20px 50px rgba(0,0,0,.18);
}
.card h3{
margin:0 0 8px;
font-size:19px;
}
.card p{
margin:0;
color:var(--muted);
font-size:15px;
}
.cases{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:18px;
}
.case{
min-height:260px;
display:flex;
flex-direction:column;
justify-content:space-between;
}
.tag{
display:inline-block;
color:#cffafe;
background:rgba(8,145,178,.16);
border:1px solid rgba(103,232,249,.22);
border-radius:999px;
font-size:12px;
padding:4px 9px;
margin-bottom:14px;
}
.metric{
margin-top:18px;
padding-top:16px;
border-top:1px solid rgba(148,163,184,.18);
color:#d1fae5;
font-weight:700;
font-size:14px;
}
.two{
display:grid;
grid-template-columns:1.1fr .9fr;
gap:22px;
align-items:start;
}
.about-text p{
margin:0 0 16px;
color:#cbd5e1;
}
.list{
display:grid;
gap:10px;
margin:0;
padding:0;
list-style:none;
}
.list li{
padding:12px 14px;
border-radius:12px;
background:rgba(15,23,42,.46);
border:1px solid rgba(148,163,184,.14);
color:#cbd5e1;
}
.roadmap{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:16px;
}
.step b{
color:#fef3c7;
}
footer{
padding:40px 0 60px;
color:var(--muted);
border-top:1px solid rgba(148,163,184,.15);
}
.footer-inner{
display:flex;
justify-content:space-between;
gap:20px;
flex-wrap:wrap;
}
@media (max-width:900px){
.links{display:none}
.grid,.cases,.roadmap,.two{grid-template-columns:1fr}
.hero{padding:70px 0 48px}
}
</style>
</head>
<body>
<header>
<div class="wrap">
<nav>
<a class="brand" href="#">Knowledge <span>AI</span> Lab</a>
<div class="links">
<a href="#cases">案例</a>
<a href="#rag">RAG Lab</a>
<a href="#eval">LLM Evaluation</a>
<a href="#workflow">AI Workflow</a>
<a href="#about">About</a>
</div>
</nav>
</div>
</header>
<main>
<section class="hero">
<div class="wrap">
<div class="badge">Publishing as a Case Study · 面向知识密集型工作的 AI 实践</div>
<h1><span class="gradient">Knowledge AI Lab</span></h1>
<p class="subtitle">面向知识型工作的 RAG、内容评估与 AI 工作流实践</p>
<p class="lead">
把高密度的专业文本,变成 LLM 可以准确调用、人类可以放心信任的知识系统。
出版是我的第一个样板间;教育、科研、法律、企业知识管理,是下一站。
</p>
<div class="cta">
<a class="btn primary" href="#cases">查看精选案例</a>
<a class="btn secondary" href="#eval">从 LLM 内容评估开始</a>
<a class="btn secondary" href="#about">了解我的方法</a>
</div>
</div>
</section>
<section id="capabilities">
<div class="wrap">
<div class="section-title">
<div>
<div class="kicker">Capability Map</div>
<h2>我在这里做四件事</h2>
</div>
<p class="muted">内容判断力 × AI 工程能力 × 评估方法论</p>
</div>
<div class="grid">
<div class="card">
<h3>🧪 RAG Lab</h3>
<p>图书、企业制度、学术文献、法规文本四类知识库实验。</p>
</div>
<div class="card">
<h3>🔍 LLM Evaluation</h3>
<p>幻觉、忠实度、引用准确性,把编辑核查变成评测集。</p>
</div>
<div class="card">
<h3>⚙️ AI Workflow</h3>
<p>编辑审稿、研报解读、文档摘要、客服知识库等流程设计。</p>
</div>
<div class="card">
<h3>📦 Product Sketches</h3>
<p>AI 编辑助手、企业知识助手、学术研究助手、智能选题助手。</p>
</div>
</div>
</div>
</section>
<section id="cases">
<div class="wrap">
<div class="section-title">
<div>
<div class="kicker">Featured Cases</div>
<h2>先从三个可验证案例开始</h2>
</div>
</div>
<div class="cases">
<article class="card case">
<div>
<span class="tag">RAG Lab</span>
<h3>一本书如何被拆成 RAG 知识库</h3>
<p>从目录、章节、脚注、专名、术语表入手,比较不同 chunking 策略对召回质量的影响。</p>
</div>
<div class="metric">目标输出:可运行 Demo + 切分策略报告</div>
</article>
<article class="card case">
<div>
<span class="tag">LLM Evaluation</span>
<h3>模型为什么会改坏一段专业文本</h3>
<p>以出版编辑场景为样本,记录幻觉、过度概括、引用失真、事实漂移等错误类型。</p>
</div>
<div class="metric">目标输出:错误分类表 + 评测 Rubric</div>
</article>
<article class="card case">
<div>
<span class="tag">AI Workflow</span>
<h3>三审三校流程如何被 AI 增强</h3>
<p>拆解哪些环节适合 AI,哪些必须保留人工判断,并给出人机协同检查清单。</p>
</div>
<div class="metric">目标输出:流程图 + Prompt 模板</div>
</article>
</div>
</div>
</section>
<section id="rag">
<div class="wrap two">
<div>
<div class="kicker">RAG Lab</div>
<h2>让 AI 真正读懂一本书、一份制度、一组论文</h2>
<p class="muted">
RAG 的难点不只是“把文档塞进向量库”,而是如何切分、标注、召回、重排、引用,并最终让回答经得起核查。
</p>
</div>
<div class="card">
<ul class="list">
<li>图书知识库:章节结构、脚注、术语、人物、事件线索</li>
<li>企业制度知识库:条款级问答、适用范围、例外条件</li>
<li>学术文献知识库:摘要、方法、结论、引用回溯</li>
<li>法规知识库:法条检索、上下文引用、适用边界提示</li>
</ul>
</div>
</div>
</section>
<section id="eval">
<div class="wrap two">
<div>
<div class="kicker">LLM Evaluation</div>
<h2>把“编辑的眼睛”变成 AI 评测方法</h2>
<p class="muted">
大模型可以生成,但不一定能判断;可以检索,但不一定会甄别。内容评估的目标,是让幻觉、忠实度、引用准确性和事实核查变成可以复现的测试。
</p>
</div>
<div class="card">
<ul class="list">
<li>幻觉案例库:记录模型凭空补充、张冠李戴、时间线错误</li>
<li>忠实度评估:检查输出是否偏离原文、是否过度解释</li>
<li>引用准确性:核查作者、书名、篇名、页码、原文对应关系</li>
<li>多模型对比:比较 GPT、Claude、Gemini、Qwen、DeepSeek 等模型</li>
</ul>
</div>
</div>
</section>
<section id="workflow">
<div class="wrap">
<div class="section-title">
<div>
<div class="kicker">AI Workflow</div>
<h2>从单点工具到端到端工作流</h2>
</div>
</div>
<div class="roadmap">
<div class="card step">
<h3><b>01</b> 编辑审稿流程</h3>
<p>初审、复审、终审、事实核查、参考文献检查、敏感表述审查。</p>
</div>
<div class="card step">
<h3><b>02</b> 研报解读流程</h3>
<p>长文档摘要、观点抽取、证据链回溯、风险提示、结构化输出。</p>
</div>
<div class="card step">
<h3><b>03</b> 企业知识库流程</h3>
<p>制度导入、问答构建、权限控制、答案引用、反馈闭环与评测。</p>
</div>
</div>
</div>
</section>
<section id="about">
<div class="wrap two">
<div class="about-text">
<div class="kicker">About</div>
<h2>我是一个从内容现场走向 AI 知识系统的人</h2>
<p>
我是一名图书编辑,也是一名 AI 知识系统实践者。过去几年,我处理过大量专业文稿:史学、文学、社会科学与政策研究。我熟悉一段文字哪里会出歧义,哪句引文需要核查,哪个观点经不起推敲。
</p>
<p>
Knowledge AI Lab 是我把“编辑的判断力”翻译成“AI 的工程能力”的实验场。我在这里搭建 RAG 知识库,设计 LLM 内容质量评估方法,并沉淀知识密集型行业的 AI 工作流。
</p>
<p>
出版只是切入口。真正的目标,是为所有需要高准确度知识系统的组织,提供可复用的方法与产品。
</p>
</div>
<div class="card">
<h3>Contact</h3>
<p class="muted">可在这里放置邮箱、GitHub、LinkedIn、知乎、公众号、Medium 或 Substack 链接。</p>
<ul class="list" style="margin-top:16px;">
<li>Email:yourname@example.com</li>
<li>GitHub:github.com/yourname</li>
<li>Medium:medium.com/@yourname</li>
<li>公众号 / 知乎:Knowledge AI Lab</li>
</ul>
</div>
</div>
</section>
</main>
<footer>
<div class="wrap footer-inner">
<div>© 2026 Knowledge AI Lab</div>
<div>RAG · LLM Evaluation · AI Workflow · Knowledge Products</div>
</div>
</footer>
</body>
</html>
可以。上面我先把第 1 件事:静态站首页做出来了。你可以把它保存成 index.html,直接拖到浏览器打开;也可以上传到 GitHub Pages / Vercel / Netlify,立刻就是一个可访问网站。
下面我继续把另外两件也给你“做成可直接落地的 v0.1 版本”:
下周的 LLM Evaluation 第一个案例,以及 2 周后的图书 RAG Demo MVP。
一、静态站点:怎么最快上线
如果你想最快上线,不要先折腾框架。直接用这个顺序:
方案 A:最快,Netlify Drop
- 新建一个文件夹:
knowledge-ai-lab - 把上面的代码保存为:
index.html - 打开 Netlify Drop:
https://app.netlify.com/drop - 把整个文件夹拖进去
- Netlify 会直接生成一个临时网址
- 后续再绑定域名,比如:
knowledgeailab.comknowledge-ai-lab.comyourname.ai
方案 B:GitHub Pages
项目结构:
knowledge-ai-lab/
└── index.html
上传 GitHub 后,在仓库设置里开启 Pages 即可。
二、下周可发布作品:LLM Evaluation 第一个案例
我建议第一个案例不要做得太大,先做一个非常有辨识度的主题:
模型为什么会改坏一段专业文本:从“润色”到“事实漂移”的 5 类错误
这个题目非常适合你,因为它连接了你的编辑经验和 AI 内容评估能力。
它不需要你一开始就做复杂系统,只要你准备:
- 一段原文;
- 一个润色任务;
- 多个模型输出;
- 人工标注错误;
- 总结评测维度;
- 给出改进后的 Prompt。
这就是一篇很完整的 AI 内容评估案例。
案例标题
模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估
副标题
从出版编辑场景出发,观察大模型在“润色、改写、摘要”中的事实漂移、引用失真与语气误判。
1. 实验目标
这次实验想回答一个很具体的问题:
当我们让大模型“润色一段专业文本”时,它到底是在改善表达,还是在偷偷改变事实?
在日常使用中,很多人会把“润色”当成一个低风险任务。但对出版、科研、法律、咨询、企业知识管理这些知识密集型场景来说,润色并不简单。一个词的替换、一个因果关系的强化、一个限定条件的删去,都可能导致原意偏移。
所以,本实验不评估模型“写得是否漂亮”,而评估它是否做到:
- 不增加原文没有的信息;
- 不删去关键限定条件;
- 不改变因果关系;
- 不误改专业概念;
- 不把谨慎判断改成确定性结论。
2. 测试文本
为了方便公开展示,你可以先用一个“类出版场景”的自拟文本,不涉及真实书稿版权。比如:
原文:
近代出版机构的兴起,并不只是印刷技术进步的结果,也与城市商业网络、读者群体扩大以及新式教育的发展有关。需要注意的是,不同地区的出版转型并不同步,沿海城市往往较早形成商业化出版机制,而内陆地区则更多受到地方教育资源和交通条件的限制。因此,讨论近代出版的现代化过程,不能简单地归结为技术替代,而应放在更复杂的社会结构变迁中理解。
这个文本好在哪里?
它有几个容易被模型改坏的点:
- “并不只是”容易被改成“主要是”;
- “有关”容易被改成“决定了”;
- “往往较早”容易被改成“率先”;
- “更多受到……限制”容易被改成绝对因果;
- “不能简单归结为”容易被模型摘要时删掉。
3. 测试 Prompt
你可以用这个统一 Prompt 测试不同模型:
请对下面这段文字进行学术化润色,使其表达更自然、逻辑更清晰。
要求:
1. 不增加原文没有的信息;
2. 不改变原文的事实判断;
3. 保留原文中的限定性表达,例如“并不只是”“往往”“更多受到”“不能简单归结为”;
4. 不要把相关关系改写为因果关系;
5. 输出润色后的文本,并列出你做过的主要修改。
原文:
【粘贴测试文本】
4. 评估维度
这里是你作品集里最重要的部分。你要把“编辑经验”变成可复用评测表。
| 评估维度 | 说明 | 评分 |
|---|---|---|
| 忠实度 | 是否保持原文事实、判断和逻辑关系 | 0–5 |
| 限定条件保留 | 是否保留“往往”“并不只是”“不能简单归结为”等限制性表达 | 0–5 |
| 概念准确性 | 是否误改“出版机构”“商业化出版机制”“社会结构变迁”等概念 | 0–5 |
| 因果关系控制 | 是否把“有关”“受到影响”强化为“导致”“决定” | 0–5 |
| 表达改善 | 是否在不改变原意的前提下提升流畅度 | 0–5 |
| 可追溯性 | 是否说明修改了哪里、为什么改 | 0–5 |
总分 30 分。
但你在文章里要强调:
对知识密集型文本来说,表达改善不是最高优先级。一个“更好看但更不准确”的输出,在出版、科研、法律和企业知识管理场景中是不可接受的。
5. 错误类型分类表
你可以把模型错误分成 5 类:
| 错误类型 | 表现 | 风险 |
|---|---|---|
| 信息增生 | 添加原文没有的新背景、新判断、新例子 | 造成事实幻觉 |
| 限定丢失 | 删除“可能”“往往”“并不只是”等词 | 把谨慎判断变成绝对判断 |
| 因果强化 | 把相关关系改成因果关系 | 改变论证结构 |
| 概念漂移 | 将专业概念替换成近义但不等价的词 | 损害学术准确性 |
| 风格错配 | 过度华丽、口号化、营销化 | 不符合学术或出版语体 |
这张表就是你以后做 LLM Evaluation 的基础资产。
6. 可发布文章正文草稿
下面这部分可以直接放到你的作品集或公众号里。
模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估
很多人使用大模型时,会把“润色”视为一个低风险任务:反正只是让文字更顺一点,不涉及创造新内容,应该不会出什么问题。
但在出版、科研、法律和企业知识管理等知识密集型场景中,“润色”并不是简单的语言美化。它本质上是一种对原文意义的再表达。只要模型在再表达过程中改变了限定条件、强化了因果关系,或者替换了并不等价的概念,文本看起来可能更流畅,实际上却已经偏离了原意。
我用一段关于近代出版史的短文本做了一个小实验。原文如下:
近代出版机构的兴起,并不只是印刷技术进步的结果,也与城市商业网络、读者群体扩大以及新式教育的发展有关。需要注意的是,不同地区的出版转型并不同步,沿海城市往往较早形成商业化出版机制,而内陆地区则更多受到地方教育资源和交通条件的限制。因此,讨论近代出版的现代化过程,不能简单地归结为技术替代,而应放在更复杂的社会结构变迁中理解。
这段文字并不复杂,但它包含几个对专业文本非常重要的限定:
“并不只是”说明作者反对单一技术决定论;
“有关”表达的是相关关系,而不是强因果关系;
“往往较早”保留了地区差异中的例外可能;
“更多受到……限制”说明影响因素并非唯一;
“不能简单归结为”则是整段文字的论证重心。
如果一个模型在润色时删掉这些限制词,或者把它们改成更确定、更有力量的表达,表面上看语言更果断,实际上却把原文的分析框架改掉了。
因此,我没有把“语言是否优美”作为唯一标准,而是设计了六个评估维度:忠实度、限定条件保留、概念准确性、因果关系控制、表达改善和可追溯性。
在这个框架下,一个好的润色结果,不是把原文改得更“高级”,而是在不改变原意的前提下,让表达更清楚。尤其是对于学术类、政策类、法律类文本来说,谨慎表达本身就是信息的一部分。模型如果把“可能”改成“必然”,把“有关”改成“导致”,把“不能简单归结为”删掉,那么它并不是在润色,而是在重写判断。
这也是 LLM 内容评估中容易被忽视的一点:很多错误不是明显的事实错误,而是细微的意义漂移。它不会像编造一个不存在的人名那样刺眼,却会悄悄改变文本的论证方向。
我把这类错误分成五类:
第一类是信息增生。模型会添加原文没有的新背景、新判断或新例子。
第二类是限定丢失。模型会删掉“往往”“可能”“并不只是”等表达,使原文变得更绝对。
第三类是因果强化。模型会把“有关”“受到影响”改成“推动”“决定”“导致”。
第四类是概念漂移。模型会用看似相近但并不等价的词替换专业概念。
第五类是风格错配。模型把原本克制的学术表达改成宣传语、总结句或口号式表达。
这五类错误提醒我们:面向知识型工作的 AI 系统,不能只看生成质量,还要看内容是否可信。一个真正可用的 AI 编辑助手,不应该只是“更会写”,而应该更会保留原文的判断边界。
从这个角度看,编辑经验可以转化为 AI 评估能力。传统编辑关注事实、引文、逻辑、语气和表达边界;而 LLM Evaluation 正是要把这些判断标准结构化、量化,并嵌入到模型使用流程中。
这也是 Knowledge AI Lab 的第一个实验想说明的问题:AI 不是不能进入专业内容生产,而是必须带着评估框架进入。没有评估的生成,只是更快地产生不确定内容;有评估的生成,才可能成为知识工作的基础设施。
7. 这篇文章配套的评分表
你可以直接做成表格,放在 Notion、飞书多维表格或 Excel 里。
case_id,source_text,task,model,output,faithfulness,qualifier_retention,concept_accuracy,causal_control,expression_quality,traceability,total_score,error_types,notes
001,近代出版机构的兴起...,academic polishing,GPT-4.1,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,Claude,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,Gemini,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,Qwen,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,DeepSeek,,0,0,0,0,0,0,0,,
三、2 周后上线的第一个 RAG Demo:图书知识库 MVP
这个 Demo 不要一开始就追求复杂。第一版只做一件事:
上传或预置一本书的文本,让用户提问,系统返回答案,并附带引用来源。
它的价值不在于“多炫”,而在于展示你真的懂:
- 文档切分;
- 元数据;
- 检索;
- 引用;
- 回答约束;
- 评估。
1. Demo 名称
BookRAG Mini:一本书的可追溯问答系统
副标题:
A citation-grounded RAG demo for book-length knowledge.
2. 功能边界
第一版只做 5 个功能:
| 功能 | 说明 |
|---|---|
| 文本导入 | 使用一本公版书、自己写的样章,或可公开使用的文稿 |
| 自动切分 | 按章节、段落、长度混合切分 |
| 向量检索 | 根据问题召回相关片段 |
| 引用回答 | 回答必须附上来源片段 |
| 不知道机制 | 如果知识库没有依据,必须回答“资料中未找到充分依据” |
3. 推荐技术栈
为了最快上线,建议:
| 层级 | 选择 |
|---|---|
| 前端 | Streamlit |
| 向量检索 | FAISS |
| Embedding | sentence-transformers 或 OpenAI Embedding |
| LLM | OpenAI / DeepSeek / 通义千问任选 |
| 部署 | Hugging Face Spaces / Streamlit Community Cloud |
如果你希望完全免费开跑,第一版可以用:
sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2- FAISS
- 本地检索
- 回答部分先调用一个 API 模型
4. 项目结构
bookrag-mini/
├── app.py
├── requirements.txt
├── data/
│ └── book_sample.txt
├── index/
│ ├── chunks.json
│ └── faiss.index
└── README.md
5. requirements.txt
streamlit
faiss-cpu
sentence-transformers
numpy
pandas
openai
6. 示例数据:data/book_sample.txt
你可以先不用真实图书,先放一个可公开的样本文本。比如:
# 第一章 近代出版的兴起
近代出版机构的兴起,并不只是印刷技术进步的结果,也与城市商业网络、读者群体扩大以及新式教育的发展有关。不同地区的出版转型并不同步,沿海城市往往较早形成商业化出版机制,而内陆地区则更多受到地方教育资源和交通条件的限制。
# 第二章 读者群体与知识传播
随着新式学校、报刊网络和城市书店的发展,读者群体逐渐扩大。读者不再只是传统士人,也包括学生、教师、商人和新兴城市职业群体。出版机构由此开始更加重视选题策划、发行渠道和内容通俗化。
# 第三章 出版现代化的复杂性
讨论近代出版的现代化过程,不能简单地归结为技术替代。技术变化当然重要,但出版机制的形成还受到资本、制度、教育、交通、读者需求和文化观念等多种因素影响。
后续你可以替换成你最熟悉的一本书,注意版权问题。如果是公开作品,尽量选公版文本;如果是你自己的工作样本,要脱敏。
7. app.py:可运行版本
下面这个版本是最小可运行 Demo。它的思路是:
- 读取文本;
- 切分成 chunks;
- 为每个 chunk 生成 embedding;
- 建立 FAISS 索引;
- 用户输入问题;
- 检索相似片段;
- 把片段交给模型回答;
- 显示引用来源。
import os
import json
import numpy as np
import streamlit as st
import faiss
from sentence_transformers import SentenceTransformer
from openai import OpenAI
# =========================
# 基础配置
# =========================
st.set_page_config(
page_title="BookRAG Mini",
page_icon="📚",
layout="wide"
)
DATA_PATH = "data/book_sample.txt"
CHUNKS_PATH = "index/chunks.json"
FAISS_PATH = "index/faiss.index"
# 你可以在 Streamlit Cloud 或 Hugging Face Spaces 的 Secrets 中配置 OPENAI_API_KEY
# 如果你使用 DeepSeek、通义千问等 OpenAI-compatible API,也可以替换 base_url
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY", ""),
base_url=os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
)
# 多语言轻量 embedding 模型,适合中文入门 Demo
@st.cache_resource
def load_embedder():
return SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
embedder = load_embedder()
# =========================
# 文档处理函数
# =========================
def load_text(path):
with open(path, "r", encoding="utf-8") as f:
return f.read()
def split_by_paragraph(text, max_chars=420, overlap=80):
"""
一个简单但可解释的切分器:
1. 优先按段落切;
2. 太短的段落合并;
3. 太长的片段用滑窗切;
4. 保留一定 overlap,避免上下文断裂。
"""
paragraphs = [p.strip() for p in text.split("\n") if p.strip()]
chunks = []
current = ""
for para in paragraphs:
if len(current) + len(para) <= max_chars:
current += "\n" + para if current else para
else:
if current:
chunks.append(current)
current = para
if current:
chunks.append(current)
# 对超长 chunk 再做滑窗
final_chunks = []
for chunk in chunks:
if len(chunk) <= max_chars:
final_chunks.append(chunk)
else:
start = 0
while start < len(chunk):
end = start + max_chars
final_chunks.append(chunk[start:end])
start = end - overlap
return final_chunks
def extract_section(chunk):
"""
简单提取章节标题。
如果 chunk 中有 # 开头的行,就把它当作 section。
"""
for line in chunk.split("\n"):
if line.startswith("#"):
return line.replace("#", "").strip()
return "未标明章节"
def build_index():
text = load_text(DATA_PATH)
raw_chunks = split_by_paragraph(text)
chunks = []
for i, content in enumerate(raw_chunks):
chunks.append({
"chunk_id": i,
"section": extract_section(content),
"content": content
})
texts = [c["content"] for c in chunks]
vectors = embedder.encode(texts, convert_to_numpy=True, normalize_embeddings=True)
dim = vectors.shape[1]
index = faiss.IndexFlatIP(dim)
index.add(vectors.astype("float32"))
os.makedirs("index", exist_ok=True)
faiss.write_index(index, FAISS_PATH)
with open(CHUNKS_PATH, "w", encoding="utf-8") as f:
json.dump(chunks, f, ensure_ascii=False, indent=2)
return chunks, index
@st.cache_resource
def load_or_build_index():
if os.path.exists(CHUNKS_PATH) and os.path.exists(FAISS_PATH):
with open(CHUNKS_PATH, "r", encoding="utf-8") as f:
chunks = json.load(f)
index = faiss.read_index(FAISS_PATH)
return chunks, index
return build_index()
def retrieve(query, chunks, index, top_k=3):
q_vec = embedder.encode([query], convert_to_numpy=True, normalize_embeddings=True)
scores, ids = index.search(q_vec.astype("float32"), top_k)
results = []
for score, idx in zip(scores[0], ids[0]):
if idx == -1:
continue
item = chunks[idx]
results.append({
"score": float(score),
"chunk_id": item["chunk_id"],
"section": item["section"],
"content": item["content"]
})
return results
def answer_with_context(question, contexts):
context_text = "\n\n".join([
f"[来源 {i+1} | {c['section']} | chunk_id={c['chunk_id']}]\n{c['content']}"
for i, c in enumerate(contexts)
])
prompt = f"""
你是一个严谨的图书知识库问答助手。请只根据给定资料回答问题。
要求:
1. 如果资料中没有充分依据,请回答:“资料中未找到充分依据。”
2. 不要编造资料中没有的人名、时间、概念或结论。
3. 回答后必须列出引用来源,格式为:[来源1]、[来源2]。
4. 如果不同来源之间存在差异,请指出差异,而不是强行合并。
用户问题:
{question}
给定资料:
{context_text}
"""
if not os.getenv("OPENAI_API_KEY"):
return "未配置 OPENAI_API_KEY。当前仅显示检索结果,请在环境变量中添加 API Key 后启用生成回答。"
response = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL", "gpt-4o-mini"),
messages=[
{"role": "system", "content": "你是一个严谨、克制、重视引用依据的知识库问答助手。"},
{"role": "user", "content": prompt}
],
temperature=0.2
)
return response.choices[0].message.content
# =========================
# Streamlit UI
# =========================
st.title("📚 BookRAG Mini")
st.caption("一本书的可追溯问答系统|A citation-grounded RAG demo for book-length knowledge")
with st.sidebar:
st.header("设置")
top_k = st.slider("召回片段数量 Top K", min_value=1, max_value=6, value=3)
rebuild = st.button("重新构建索引")
st.markdown("---")
st.markdown("""
**Demo 目标**
- 文档切分
- 向量检索
- 引用回答
- 不知道机制
""")
if rebuild:
chunks, index = build_index()
st.success("索引已重新构建")
else:
chunks, index = load_or_build_index()
st.subheader("向知识库提问")
question = st.text_input(
"请输入问题",
placeholder="例如:为什么不能把近代出版现代化简单归结为技术替代?"
)
if question:
results = retrieve(question, chunks, index, top_k=top_k)
col1, col2 = st.columns([1.1, 1])
with col1:
st.markdown("### 回答")
answer = answer_with_context(question, results)
st.write(answer)
with col2:
st.markdown("### 检索到的来源片段")
for i, r in enumerate(results, start=1):
with st.expander(f"来源 {i}|{r['section']}|相似度 {r['score']:.3f}"):
st.write(r["content"])
st.caption(f"chunk_id: {r['chunk_id']}")
else:
st.info("请输入一个问题,系统会从图书知识库中检索相关片段并生成带引用的回答。")
st.markdown("---")
st.markdown("""
### 评估说明
这个 Demo 的重点不是让模型“自由发挥”,而是测试它能否在给定资料内回答问题。后续会继续加入:
1. 不同 chunk size 的对比;
2. 有无 rerank 的效果对比;
3. 问答评测集;
4. 忠实度评分;
5. 引用准确性检查。
""")
8. README.md
# BookRAG Mini
一本书的可追溯问答系统。
A citation-grounded RAG demo for book-length knowledge.
## 项目目标
这个 Demo 用来展示如何把一本书或一组长文本转化为可检索、可引用、可评估的 RAG 知识库。
它重点展示:
- 文档切分;
- 元数据设计;
- 向量检索;
- 基于来源的回答;
- “不知道”机制;
- 后续可扩展的评估框架。
## 快速开始
安装依赖:
```bash
pip install -r requirements.txt
```
运行:
```bash
streamlit run app.py
```
如果需要启用模型生成回答,请配置环境变量:
```bash
export OPENAI_API_KEY="你的 API Key"
export OPENAI_BASE_URL="https://api.openai.com/v1"
export OPENAI_MODEL="gpt-4o-mini"
```
如果使用兼容 OpenAI 格式的其他模型服务,可以替换 `OPENAI_BASE_URL` 和 `OPENAI_MODEL`。
## 数据格式
将图书样本文本放入:
```bash
data/book_sample.txt
```
建议使用如下格式:
```txt
# 第一章 标题
正文内容……
# 第二章 标题
正文内容……
```
## 当前版本限制
v0.1 版本只实现最小可用流程,尚未加入:
- rerank;
- 多 embedding 模型对比;
- 自动评测;
- 权限控制;
- 多文件上传;
- 前端美化。
## 下一步计划
- 加入 chunk size ablation;
- 加入人工评测集;
- 加入引用准确性检查;
- 加入问答日志;
- 发布为 Hugging Face Spaces Demo。
```
四、这三件事现在怎么组合成作品集首页的第一批内容
你现在已经有三个可放进作品集的东西:
1. 首页
标题:
Knowledge AI Lab:面向知识型工作的 RAG、内容评估与 AI 工作流实践
状态:
已有 v0.1 静态站点。
2. 第一篇文章
标题:
模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估
状态:
已有文章草稿、评分表、Prompt、错误分类框架。
3. 第一个 Demo
标题:
BookRAG Mini:一本书的可追溯问答系统
状态:
已有项目结构、依赖、示例数据、核心代码、README。
五、你接下来 7 天只需要照这个顺序执行
Day 1:上线首页
- 保存
index.html - 用 Netlify Drop 上传
- 得到一个临时网址
- 替换 Contact 里的邮箱/GitHub/知乎链接
Day 2:建立 GitHub 仓库
建两个仓库:
knowledge-ai-lab-site
bookrag-mini
把首页放进第一个仓库。
Day 3:发布第一篇文章
把上面的 LLM Evaluation 草稿发到:
- 公众号;
- 知乎;
- 作品集网站;
- Medium/LinkedIn 英文版以后再补。
Day 4–5:跑通 BookRAG Mini
本地运行:
pip install -r requirements.txt
streamlit run app.py
先不纠结效果,把流程跑通。
Day 6:替换真实样本文本
选一本你熟悉、版权安全的书或自写样本文本。
重点不是文本多,而是元数据清楚:
- 章节;
- 段落;
- 关键词;
- 术语;
- 人名;
- 时间;
- 引文。
Day 7:写 Demo 说明文章
标题:
我如何把一本书做成可追溯问答系统:BookRAG Mini v0.1
文章结构:
- 为什么从图书开始;
- 文档如何切分;
- 为什么必须带引用;
- 模型什么时候应该回答“不知道”;
- 下一版要加入什么评测。
六、非常重要:这不是最终版,而是“可被看见的第一版”
你现在最需要的不是一个完美系统,而是一个别人能点开、能理解、能判断你在认真做这件事的入口。
这三个东西已经构成了最小闭环:
一个网站壳子 + 一篇内容评估案例 + 一个 RAG Demo 原型。
这就已经不是“我对 AI 出版感兴趣”了,而是:
我正在构建面向知识密集型工作的 AI 知识系统作品集。
**出版只是我的第一个样板间。**Japgolly
“内容_hash”: “57ac0f72c7f91577”
}
已经给你做出 v0.1 可落地版本:
-
Knowledge AI Lab 静态站首页
- 上方 artifact 里的
index.html可直接保存使用; - 支持 GitHub Pages、Netlify、Vercel;
- 已包含首页、能力地图、精选案例、RAG、LLM Evaluation、AI Workflow、About 等区块。
- 上方 artifact 里的
-
LLM Evaluation 第一篇可发布案例
- 标题:《模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估》
- 已包含:
- 实验目标;
- 测试文本;
- 测试 Prompt;
- 评估维度;
- 错误类型分类表;
- 可发布文章正文;
- CSV 评分表模板。
-
BookRAG Mini 第一个 RAG Demo
- 已给出:
- 项目结构;
requirements.txt;- 示例数据;
app.py可运行代码;README.md;- 后续评估扩展方向。
- 已给出:
你现在只需要照这个顺序执行:
Day 1:保存 index.html,上线首页
Day 2:建 GitHub 仓库
Day 3:发布 LLM Evaluation 第一篇文章
Day 4-5:本地跑通 BookRAG Mini
Day 6:替换成版权安全的真实样本文本
Day 7:写 BookRAG Demo 说明文章
这三件事一旦上线,你就已经有了一个最小闭环:
网站壳子 + 内容评估案例 + RAG Demo 原型
这就不再是“想转型 AI 出版”,而是正式开始呈现为:
面向知识密集型行业的 AI 产品与知识系统实践者。
id: knowledge_ai_lab_site_v01
name: Knowledge AI Lab 单页静态站点 v0.1
type: html
content: |-
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Knowledge AI Lab|RAG、内容评估与 AI 工作流实践</title>
<meta name="description" content="Knowledge AI Lab:面向知识型工作的 RAG、内容评估与 AI 工作流实践。Publishing as a Case Study." />
<style>
:root{
--bg:#0f172a;
--panel:#111827;
--panel2:#1e293b;
--text:#e5e7eb;
--muted:#94a3b8;
--line:#334155;
--accent:#38bdf8;
--accent2:#a78bfa;
--white:#ffffff;
--green:#34d399;
--yellow:#fbbf24;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",Arial,sans-serif;
color:var(--text);
background:
radial-gradient(circle at 20% 10%, rgba(56,189,248,.18), transparent 28%),
radial-gradient(circle at 80% 0%, rgba(167,139,250,.18), transparent 30%),
var(--bg);
line-height:1.7;
}
a{color:inherit;text-decoration:none}
.wrap{width:min(1120px,92vw);margin:0 auto}
header{
position:sticky;top:0;z-index:99;
backdrop-filter:blur(16px);
background:rgba(15,23,42,.76);
border-bottom:1px solid rgba(148,163,184,.18);
}
nav{
height:68px;
display:flex;
align-items:center;
justify-content:space-between;
}
.brand{
font-weight:800;
letter-spacing:.2px;
}
.brand span{color:var(--accent)}
.links{
display:flex;
gap:22px;
font-size:14px;
color:var(--muted);
}
.links a:hover{color:var(--white)}
.hero{
padding:96px 0 72px;
}
.badge{
display:inline-flex;
align-items:center;
gap:8px;
padding:7px 12px;
border:1px solid rgba(56,189,248,.3);
border-radius:999px;
color:#bae6fd;
background:rgba(2,132,199,.12);
font-size:14px;
margin-bottom:24px;
}
h1{
font-size:clamp(46px,8vw,84px);
line-height:1.02;
margin:0 0 20px;
letter-spacing:-2.8px;
}
.gradient{
background:linear-gradient(90deg,var(--white),#bae6fd,#ddd6fe);
-webkit-background-clip:text;
background-clip:text;
color:transparent;
}
.subtitle{
font-size:clamp(20px,3vw,30px);
line-height:1.35;
color:#cbd5e1;
max-width:920px;
margin:0 0 22px;
}
.lead{
font-size:18px;
color:var(--muted);
max-width:820px;
margin:0 0 34px;
}
.cta{
display:flex;
flex-wrap:wrap;
gap:14px;
}
.btn{
display:inline-flex;
align-items:center;
justify-content:center;
padding:13px 18px;
border-radius:12px;
font-weight:700;
border:1px solid rgba(148,163,184,.28);
}
.btn.primary{
background:linear-gradient(135deg,var(--accent),var(--accent2));
color:#020617;
border:none;
}
.btn.secondary{
background:rgba(15,23,42,.55);
color:#dbeafe;
}
section{
padding:58px 0;
border-top:1px solid rgba(148,163,184,.15);
}
.section-title{
display:flex;
align-items:flex-end;
justify-content:space-between;
gap:20px;
margin-bottom:26px;
}
h2{
font-size:34px;
line-height:1.2;
margin:0;
letter-spacing:-.8px;
}
.kicker{
color:var(--accent);
font-weight:800;
text-transform:uppercase;
letter-spacing:.12em;
font-size:12px;
margin-bottom:8px;
}
.muted{color:var(--muted)}
.grid{
display:grid;
grid-template-columns:repeat(4,1fr);
gap:16px;
}
.card{
background:linear-gradient(180deg,rgba(30,41,59,.92),rgba(15,23,42,.88));
border:1px solid rgba(148,163,184,.18);
border-radius:18px;
padding:22px;
box-shadow:0 20px 50px rgba(0,0,0,.18);
}
.card h3{
margin:0 0 8px;
font-size:19px;
}
.card p{
margin:0;
color:var(--muted);
font-size:15px;
}
.cases{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:18px;
}
.case{
min-height:260px;
display:flex;
flex-direction:column;
justify-content:space-between;
}
.tag{
display:inline-block;
color:#cffafe;
background:rgba(8,145,178,.16);
border:1px solid rgba(103,232,249,.22);
border-radius:999px;
font-size:12px;
padding:4px 9px;
margin-bottom:14px;
}
.metric{
margin-top:18px;
padding-top:16px;
border-top:1px solid rgba(148,163,184,.18);
color:#d1fae5;
font-weight:700;
font-size:14px;
}
.two{
display:grid;
grid-template-columns:1.1fr .9fr;
gap:22px;
align-items:start;
}
.about-text p{
margin:0 0 16px;
color:#cbd5e1;
}
.list{
display:grid;
gap:10px;
margin:0;
padding:0;
list-style:none;
}
.list li{
padding:12px 14px;
border-radius:12px;
background:rgba(15,23,42,.46);
border:1px solid rgba(148,163,184,.14);
color:#cbd5e1;
}
.roadmap{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:16px;
}
.step b{
color:#fef3c7;
}
footer{
padding:40px 0 60px;
color:var(--muted);
border-top:1px solid rgba(148,163,184,.15);
}
.footer-inner{
display:flex;
justify-content:space-between;
gap:20px;
flex-wrap:wrap;
}
@media (max-width:900px){
.links{display:none}
.grid,.cases,.roadmap,.two{grid-template-columns:1fr}
.hero{padding:70px 0 48px}
}
</style>
</head>
<body>
<header>
<div class="wrap">
<nav>
<a class="brand" href="#">Knowledge <span>AI</span> Lab</a>
<div class="links">
<a href="#cases">案例</a>
<a href="#rag">RAG Lab</a>
<a href="#eval">LLM Evaluation</a>
<a href="#workflow">AI Workflow</a>
<a href="#about">About</a>
</div>
</nav>
</div>
</header>
<main>
<section class="hero">
<div class="wrap">
<div class="badge">Publishing as a Case Study · 面向知识密集型工作的 AI 实践</div>
<h1><span class="gradient">Knowledge AI Lab</span></h1>
<p class="subtitle">面向知识型工作的 RAG、内容评估与 AI 工作流实践</p>
<p class="lead">
把高密度的专业文本,变成 LLM 可以准确调用、人类可以放心信任的知识系统。
出版是我的第一个样板间;教育、科研、法律、企业知识管理,是下一站。
</p>
<div class="cta">
<a class="btn primary" href="#cases">查看精选案例</a>
<a class="btn secondary" href="#eval">从 LLM 内容评估开始</a>
<a class="btn secondary" href="#about">了解我的方法</a>
</div>
</div>
</section>
<section id="capabilities">
<div class="wrap">
<div class="section-title">
<div>
<div class="kicker">Capability Map</div>
<h2>我在这里做四件事</h2>
</div>
<p class="muted">内容判断力 × AI 工程能力 × 评估方法论</p>
</div>
<div class="grid">
<div class="card">
<h3>🧪 RAG Lab</h3>
<p>图书、企业制度、学术文献、法规文本四类知识库实验。</p>
</div>
<div class="card">
<h3>🔍 LLM Evaluation</h3>
<p>幻觉、忠实度、引用准确性,把编辑核查变成评测集。</p>
</div>
<div class="card">
<h3>⚙️ AI Workflow</h3>
<p>编辑审稿、研报解读、文档摘要、客服知识库等流程设计。</p>
</div>
<div class="card">
<h3>📦 Product Sketches</h3>
<p>AI 编辑助手、企业知识助手、学术研究助手、智能选题助手。</p>
</div>
</div>
</div>
</section>
<section id="cases">
<div class="wrap">
<div class="section-title">
<div>
<div class="kicker">Featured Cases</div>
<h2>先从三个可验证案例开始</h2>
</div>
</div>
<div class="cases">
<article class="card case">
<div>
<span class="tag">RAG Lab</span>
<h3>一本书如何被拆成 RAG 知识库</h3>
<p>从目录、章节、脚注、专名、术语表入手,比较不同 chunking 策略对召回质量的影响。</p>
</div>
<div class="metric">目标输出:可运行 Demo + 切分策略报告</div>
</article>
<article class="card case">
<div>
<span class="tag">LLM Evaluation</span>
<h3>模型为什么会改坏一段专业文本</h3>
<p>以出版编辑场景为样本,记录幻觉、过度概括、引用失真、事实漂移等错误类型。</p>
</div>
<div class="metric">目标输出:错误分类表 + 评测 Rubric</div>
</article>
<article class="card case">
<div>
<span class="tag">AI Workflow</span>
<h3>三审三校流程如何被 AI 增强</h3>
<p>拆解哪些环节适合 AI,哪些必须保留人工判断,并给出人机协同检查清单。</p>
</div>
<div class="metric">目标输出:流程图 + Prompt 模板</div>
</article>
</div>
</div>
</section>
<section id="rag">
<div class="wrap two">
<div>
<div class="kicker">RAG Lab</div>
<h2>让 AI 真正读懂一本书、一份制度、一组论文</h2>
<p class="muted">
RAG 的难点不只是“把文档塞进向量库”,而是如何切分、标注、召回、重排、引用,并最终让回答经得起核查。
</p>
</div>
<div class="card">
<ul class="list">
<li>图书知识库:章节结构、脚注、术语、人物、事件线索</li>
<li>企业制度知识库:条款级问答、适用范围、例外条件</li>
<li>学术文献知识库:摘要、方法、结论、引用回溯</li>
<li>法规知识库:法条检索、上下文引用、适用边界提示</li>
</ul>
</div>
</div>
</section>
<section id="eval">
<div class="wrap two">
<div>
<div class="kicker">LLM Evaluation</div>
<h2>把“编辑的眼睛”变成 AI 评测方法</h2>
<p class="muted">
大模型可以生成,但不一定能判断;可以检索,但不一定会甄别。内容评估的目标,是让幻觉、忠实度、引用准确性和事实核查变成可以复现的测试。
</p>
</div>
<div class="card">
<ul class="list">
<li>幻觉案例库:记录模型凭空补充、张冠李戴、时间线错误</li>
<li>忠实度评估:检查输出是否偏离原文、是否过度解释</li>
<li>引用准确性:核查作者、书名、篇名、页码、原文对应关系</li>
<li>多模型对比:比较 GPT、Claude、Gemini、Qwen、DeepSeek 等模型</li>
</ul>
</div>
</div>
</section>
<section id="workflow">
<div class="wrap">
<div class="section-title">
<div>
<div class="kicker">AI Workflow</div>
<h2>从单点工具到端到端工作流</h2>
</div>
</div>
<div class="roadmap">
<div class="card step">
<h3><b>01</b> 编辑审稿流程</h3>
<p>初审、复审、终审、事实核查、参考文献检查、敏感表述审查。</p>
</div>
<div class="card step">
<h3><b>02</b> 研报解读流程</h3>
<p>长文档摘要、观点抽取、证据链回溯、风险提示、结构化输出。</p>
</div>
<div class="card step">
<h3><b>03</b> 企业知识库流程</h3>
<p>制度导入、问答构建、权限控制、答案引用、反馈闭环与评测。</p>
</div>
</div>
</div>
</section>
<section id="about">
<div class="wrap two">
<div class="about-text">
<div class="kicker">About</div>
<h2>我是一个从内容现场走向 AI 知识系统的人</h2>
<p>
我是一名图书编辑,也是一名 AI 知识系统实践者。过去几年,我处理过大量专业文稿:史学、文学、社会科学与政策研究。我熟悉一段文字哪里会出歧义,哪句引文需要核查,哪个观点经不起推敲。
</p>
<p>
Knowledge AI Lab 是我把“编辑的判断力”翻译成“AI 的工程能力”的实验场。我在这里搭建 RAG 知识库,设计 LLM 内容质量评估方法,并沉淀知识密集型行业的 AI 工作流。
</p>
<p>
出版只是切入口。真正的目标,是为所有需要高准确度知识系统的组织,提供可复用的方法与产品。
</p>
</div>
<div class="card">
<h3>Contact</h3>
<p class="muted">可在这里放置邮箱、GitHub、LinkedIn、知乎、公众号、Medium 或 Substack 链接。</p>
<ul class="list" style="margin-top:16px;">
<li>Email:yourname@example.com</li>
<li>GitHub:github.com/yourname</li>
<li>Medium:medium.com/@yourname</li>
<li>公众号 / 知乎:Knowledge AI Lab</li>
</ul>
</div>
</div>
</section>
</main>
<footer>
<div class="wrap footer-inner">
<div>© 2026 Knowledge AI Lab</div>
<div>RAG · LLM Evaluation · AI Workflow · Knowledge Products</div>
</div>
</footer>
</body>
</html>
可以。上面我先把第 1 件事:静态站首页做出来了。你可以把它保存成 index.html,直接拖到浏览器打开;也可以上传到 GitHub Pages / Vercel / Netlify,立刻就是一个可访问网站。
下面我继续把另外两件也给你“做成可直接落地的 v0.1 版本”:
下周的 LLM Evaluation 第一个案例,以及 2 周后的图书 RAG Demo MVP。
一、静态站点:怎么最快上线
如果你想最快上线,不要先折腾框架。直接用这个顺序:
方案 A:最快,Netlify Drop
- 新建一个文件夹:
knowledge-ai-lab - 把上面的代码保存为:
index.html - 打开 Netlify Drop:
https://app.netlify.com/drop - 把整个文件夹拖进去
- Netlify 会直接生成一个临时网址
- 后续再绑定域名,比如:
knowledgeailab.comknowledge-ai-lab.comyourname.ai
方案 B:GitHub Pages
项目结构:
knowledge-ai-lab/
└── index.html
上传 GitHub 后,在仓库设置里开启 Pages 即可。
二、下周可发布作品:LLM Evaluation 第一个案例
我建议第一个案例不要做得太大,先做一个非常有辨识度的主题:
模型为什么会改坏一段专业文本:从“润色”到“事实漂移”的 5 类错误
这个题目非常适合你,因为它连接了你的编辑经验和 AI 内容评估能力。
它不需要你一开始就做复杂系统,只要你准备:
- 一段原文;
- 一个润色任务;
- 多个模型输出;
- 人工标注错误;
- 总结评测维度;
- 给出改进后的 Prompt。
这就是一篇很完整的 AI 内容评估案例。
案例标题
模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估
副标题
从出版编辑场景出发,观察大模型在“润色、改写、摘要”中的事实漂移、引用失真与语气误判。
1. 实验目标
这次实验想回答一个很具体的问题:
当我们让大模型“润色一段专业文本”时,它到底是在改善表达,还是在偷偷改变事实?
在日常使用中,很多人会把“润色”当成一个低风险任务。但对出版、科研、法律、咨询、企业知识管理这些知识密集型场景来说,润色并不简单。一个词的替换、一个因果关系的强化、一个限定条件的删去,都可能导致原意偏移。
所以,本实验不评估模型“写得是否漂亮”,而评估它是否做到:
- 不增加原文没有的信息;
- 不删去关键限定条件;
- 不改变因果关系;
- 不误改专业概念;
- 不把谨慎判断改成确定性结论。
2. 测试文本
为了方便公开展示,你可以先用一个“类出版场景”的自拟文本,不涉及真实书稿版权。比如:
原文:
近代出版机构的兴起,并不只是印刷技术进步的结果,也与城市商业网络、读者群体扩大以及新式教育的发展有关。需要注意的是,不同地区的出版转型并不同步,沿海城市往往较早形成商业化出版机制,而内陆地区则更多受到地方教育资源和交通条件的限制。因此,讨论近代出版的现代化过程,不能简单地归结为技术替代,而应放在更复杂的社会结构变迁中理解。
这个文本好在哪里?
它有几个容易被模型改坏的点:
- “并不只是”容易被改成“主要是”;
- “有关”容易被改成“决定了”;
- “往往较早”容易被改成“率先”;
- “更多受到……限制”容易被改成绝对因果;
- “不能简单归结为”容易被模型摘要时删掉。
3. 测试 Prompt
你可以用这个统一 Prompt 测试不同模型:
请对下面这段文字进行学术化润色,使其表达更自然、逻辑更清晰。
要求:
1. 不增加原文没有的信息;
2. 不改变原文的事实判断;
3. 保留原文中的限定性表达,例如“并不只是”“往往”“更多受到”“不能简单归结为”;
4. 不要把相关关系改写为因果关系;
5. 输出润色后的文本,并列出你做过的主要修改。
原文:
【粘贴测试文本】
4. 评估维度
这里是你作品集里最重要的部分。你要把“编辑经验”变成可复用评测表。
| 评估维度 | 说明 | 评分 |
|---|---|---|
| 忠实度 | 是否保持原文事实、判断和逻辑关系 | 0–5 |
| 限定条件保留 | 是否保留“往往”“并不只是”“不能简单归结为”等限制性表达 | 0–5 |
| 概念准确性 | 是否误改“出版机构”“商业化出版机制”“社会结构变迁”等概念 | 0–5 |
| 因果关系控制 | 是否把“有关”“受到影响”强化为“导致”“决定” | 0–5 |
| 表达改善 | 是否在不改变原意的前提下提升流畅度 | 0–5 |
| 可追溯性 | 是否说明修改了哪里、为什么改 | 0–5 |
总分 30 分。
但你在文章里要强调:
对知识密集型文本来说,表达改善不是最高优先级。一个“更好看但更不准确”的输出,在出版、科研、法律和企业知识管理场景中是不可接受的。
5. 错误类型分类表
你可以把模型错误分成 5 类:
| 错误类型 | 表现 | 风险 |
|---|---|---|
| 信息增生 | 添加原文没有的新背景、新判断、新例子 | 造成事实幻觉 |
| 限定丢失 | 删除“可能”“往往”“并不只是”等词 | 把谨慎判断变成绝对判断 |
| 因果强化 | 把相关关系改成因果关系 | 改变论证结构 |
| 概念漂移 | 将专业概念替换成近义但不等价的词 | 损害学术准确性 |
| 风格错配 | 过度华丽、口号化、营销化 | 不符合学术或出版语体 |
这张表就是你以后做 LLM Evaluation 的基础资产。
6. 可发布文章正文草稿
下面这部分可以直接放到你的作品集或公众号里。
模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估
很多人使用大模型时,会把“润色”视为一个低风险任务:反正只是让文字更顺一点,不涉及创造新内容,应该不会出什么问题。
但在出版、科研、法律和企业知识管理等知识密集型场景中,“润色”并不是简单的语言美化。它本质上是一种对原文意义的再表达。只要模型在再表达过程中改变了限定条件、强化了因果关系,或者替换了并不等价的概念,文本看起来可能更流畅,实际上却已经偏离了原意。
我用一段关于近代出版史的短文本做了一个小实验。原文如下:
近代出版机构的兴起,并不只是印刷技术进步的结果,也与城市商业网络、读者群体扩大以及新式教育的发展有关。需要注意的是,不同地区的出版转型并不同步,沿海城市往往较早形成商业化出版机制,而内陆地区则更多受到地方教育资源和交通条件的限制。因此,讨论近代出版的现代化过程,不能简单地归结为技术替代,而应放在更复杂的社会结构变迁中理解。
这段文字并不复杂,但它包含几个对专业文本非常重要的限定:
“并不只是”说明作者反对单一技术决定论;
“有关”表达的是相关关系,而不是强因果关系;
“往往较早”保留了地区差异中的例外可能;
“更多受到……限制”说明影响因素并非唯一;
“不能简单归结为”则是整段文字的论证重心。
如果一个模型在润色时删掉这些限制词,或者把它们改成更确定、更有力量的表达,表面上看语言更果断,实际上却把原文的分析框架改掉了。
因此,我没有把“语言是否优美”作为唯一标准,而是设计了六个评估维度:忠实度、限定条件保留、概念准确性、因果关系控制、表达改善和可追溯性。
在这个框架下,一个好的润色结果,不是把原文改得更“高级”,而是在不改变原意的前提下,让表达更清楚。尤其是对于学术类、政策类、法律类文本来说,谨慎表达本身就是信息的一部分。模型如果把“可能”改成“必然”,把“有关”改成“导致”,把“不能简单归结为”删掉,那么它并不是在润色,而是在重写判断。
这也是 LLM 内容评估中容易被忽视的一点:很多错误不是明显的事实错误,而是细微的意义漂移。它不会像编造一个不存在的人名那样刺眼,却会悄悄改变文本的论证方向。
我把这类错误分成五类:
第一类是信息增生。模型会添加原文没有的新背景、新判断或新例子。
第二类是限定丢失。模型会删掉“往往”“可能”“并不只是”等表达,使原文变得更绝对。
第三类是因果强化。模型会把“有关”“受到影响”改成“推动”“决定”“导致”。
第四类是概念漂移。模型会用看似相近但并不等价的词替换专业概念。
第五类是风格错配。模型把原本克制的学术表达改成宣传语、总结句或口号式表达。
这五类错误提醒我们:面向知识型工作的 AI 系统,不能只看生成质量,还要看内容是否可信。一个真正可用的 AI 编辑助手,不应该只是“更会写”,而应该更会保留原文的判断边界。
从这个角度看,编辑经验可以转化为 AI 评估能力。传统编辑关注事实、引文、逻辑、语气和表达边界;而 LLM Evaluation 正是要把这些判断标准结构化、量化,并嵌入到模型使用流程中。
这也是 Knowledge AI Lab 的第一个实验想说明的问题:AI 不是不能进入专业内容生产,而是必须带着评估框架进入。没有评估的生成,只是更快地产生不确定内容;有评估的生成,才可能成为知识工作的基础设施。
7. 这篇文章配套的评分表
你可以直接做成表格,放在 Notion、飞书多维表格或 Excel 里。
case_id,source_text,task,model,output,faithfulness,qualifier_retention,concept_accuracy,causal_control,expression_quality,traceability,total_score,error_types,notes
001,近代出版机构的兴起...,academic polishing,GPT-4.1,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,Claude,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,Gemini,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,Qwen,,0,0,0,0,0,0,0,,
001,近代出版机构的兴起...,academic polishing,DeepSeek,,0,0,0,0,0,0,0,,
三、2 周后上线的第一个 RAG Demo:图书知识库 MVP
这个 Demo 不要一开始就追求复杂。第一版只做一件事:
上传或预置一本书的文本,让用户提问,系统返回答案,并附带引用来源。
它的价值不在于“多炫”,而在于展示你真的懂:
- 文档切分;
- 元数据;
- 检索;
- 引用;
- 回答约束;
- 评估。
1. Demo 名称
BookRAG Mini:一本书的可追溯问答系统
副标题:
A citation-grounded RAG demo for book-length knowledge.
2. 功能边界
第一版只做 5 个功能:
| 功能 | 说明 |
|---|---|
| 文本导入 | 使用一本公版书、自己写的样章,或可公开使用的文稿 |
| 自动切分 | 按章节、段落、长度混合切分 |
| 向量检索 | 根据问题召回相关片段 |
| 引用回答 | 回答必须附上来源片段 |
| 不知道机制 | 如果知识库没有依据,必须回答“资料中未找到充分依据” |
3. 推荐技术栈
为了最快上线,建议:
| 层级 | 选择 |
|---|---|
| 前端 | Streamlit |
| 向量检索 | FAISS |
| Embedding | sentence-transformers 或 OpenAI Embedding |
| LLM | OpenAI / DeepSeek / 通义千问任选 |
| 部署 | Hugging Face Spaces / Streamlit Community Cloud |
如果你希望完全免费开跑,第一版可以用:
sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2- FAISS
- 本地检索
- 回答部分先调用一个 API 模型
4. 项目结构
bookrag-mini/
├── app.py
├── requirements.txt
├── data/
│ └── book_sample.txt
├── index/
│ ├── chunks.json
│ └── faiss.index
└── README.md
5. requirements.txt
streamlit
faiss-cpu
sentence-transformers
numpy
pandas
openai
6. 示例数据:data/book_sample.txt
你可以先不用真实图书,先放一个可公开的样本文本。比如:
# 第一章 近代出版的兴起
近代出版机构的兴起,并不只是印刷技术进步的结果,也与城市商业网络、读者群体扩大以及新式教育的发展有关。不同地区的出版转型并不同步,沿海城市往往较早形成商业化出版机制,而内陆地区则更多受到地方教育资源和交通条件的限制。
# 第二章 读者群体与知识传播
随着新式学校、报刊网络和城市书店的发展,读者群体逐渐扩大。读者不再只是传统士人,也包括学生、教师、商人和新兴城市职业群体。出版机构由此开始更加重视选题策划、发行渠道和内容通俗化。
# 第三章 出版现代化的复杂性
讨论近代出版的现代化过程,不能简单地归结为技术替代。技术变化当然重要,但出版机制的形成还受到资本、制度、教育、交通、读者需求和文化观念等多种因素影响。
后续你可以替换成你最熟悉的一本书,注意版权问题。如果是公开作品,尽量选公版文本;如果是你自己的工作样本,要脱敏。
7. app.py:可运行版本
下面这个版本是最小可运行 Demo。它的思路是:
- 读取文本;
- 切分成 chunks;
- 为每个 chunk 生成 embedding;
- 建立 FAISS 索引;
- 用户输入问题;
- 检索相似片段;
- 把片段交给模型回答;
- 显示引用来源。
import os
import json
import numpy as np
import streamlit as st
import faiss
from sentence_transformers import SentenceTransformer
from openai import OpenAI
# =========================
# 基础配置
# =========================
st.set_page_config(
page_title="BookRAG Mini",
page_icon="📚",
layout="wide"
)
DATA_PATH = "data/book_sample.txt"
CHUNKS_PATH = "index/chunks.json"
FAISS_PATH = "index/faiss.index"
# 你可以在 Streamlit Cloud 或 Hugging Face Spaces 的 Secrets 中配置 OPENAI_API_KEY
# 如果你使用 DeepSeek、通义千问等 OpenAI-compatible API,也可以替换 base_url
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY", ""),
base_url=os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
)
# 多语言轻量 embedding 模型,适合中文入门 Demo
@st.cache_resource
def load_embedder():
return SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
embedder = load_embedder()
# =========================
# 文档处理函数
# =========================
def load_text(path):
with open(path, "r", encoding="utf-8") as f:
return f.read()
def split_by_paragraph(text, max_chars=420, overlap=80):
"""
一个简单但可解释的切分器:
1. 优先按段落切;
2. 太短的段落合并;
3. 太长的片段用滑窗切;
4. 保留一定 overlap,避免上下文断裂。
"""
paragraphs = [p.strip() for p in text.split("\n") if p.strip()]
chunks = []
current = ""
for para in paragraphs:
if len(current) + len(para) <= max_chars:
current += "\n" + para if current else para
else:
if current:
chunks.append(current)
current = para
if current:
chunks.append(current)
# 对超长 chunk 再做滑窗
final_chunks = []
for chunk in chunks:
if len(chunk) <= max_chars:
final_chunks.append(chunk)
else:
start = 0
while start < len(chunk):
end = start + max_chars
final_chunks.append(chunk[start:end])
start = end - overlap
return final_chunks
def extract_section(chunk):
"""
简单提取章节标题。
如果 chunk 中有 # 开头的行,就把它当作 section。
"""
for line in chunk.split("\n"):
if line.startswith("#"):
return line.replace("#", "").strip()
return "未标明章节"
def build_index():
text = load_text(DATA_PATH)
raw_chunks = split_by_paragraph(text)
chunks = []
for i, content in enumerate(raw_chunks):
chunks.append({
"chunk_id": i,
"section": extract_section(content),
"content": content
})
texts = [c["content"] for c in chunks]
vectors = embedder.encode(texts, convert_to_numpy=True, normalize_embeddings=True)
dim = vectors.shape[1]
index = faiss.IndexFlatIP(dim)
index.add(vectors.astype("float32"))
os.makedirs("index", exist_ok=True)
faiss.write_index(index, FAISS_PATH)
with open(CHUNKS_PATH, "w", encoding="utf-8") as f:
json.dump(chunks, f, ensure_ascii=False, indent=2)
return chunks, index
@st.cache_resource
def load_or_build_index():
if os.path.exists(CHUNKS_PATH) and os.path.exists(FAISS_PATH):
with open(CHUNKS_PATH, "r", encoding="utf-8") as f:
chunks = json.load(f)
index = faiss.read_index(FAISS_PATH)
return chunks, index
return build_index()
def retrieve(query, chunks, index, top_k=3):
q_vec = embedder.encode([query], convert_to_numpy=True, normalize_embeddings=True)
scores, ids = index.search(q_vec.astype("float32"), top_k)
results = []
for score, idx in zip(scores[0], ids[0]):
if idx == -1:
continue
item = chunks[idx]
results.append({
"score": float(score),
"chunk_id": item["chunk_id"],
"section": item["section"],
"content": item["content"]
})
return results
def answer_with_context(question, contexts):
context_text = "\n\n".join([
f"[来源 {i+1} | {c['section']} | chunk_id={c['chunk_id']}]\n{c['content']}"
for i, c in enumerate(contexts)
])
prompt = f"""
你是一个严谨的图书知识库问答助手。请只根据给定资料回答问题。
要求:
1. 如果资料中没有充分依据,请回答:“资料中未找到充分依据。”
2. 不要编造资料中没有的人名、时间、概念或结论。
3. 回答后必须列出引用来源,格式为:[来源1]、[来源2]。
4. 如果不同来源之间存在差异,请指出差异,而不是强行合并。
用户问题:
{question}
给定资料:
{context_text}
"""
if not os.getenv("OPENAI_API_KEY"):
return "未配置 OPENAI_API_KEY。当前仅显示检索结果,请在环境变量中添加 API Key 后启用生成回答。"
response = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL", "gpt-4o-mini"),
messages=[
{"role": "system", "content": "你是一个严谨、克制、重视引用依据的知识库问答助手。"},
{"role": "user", "content": prompt}
],
temperature=0.2
)
return response.choices[0].message.content
# =========================
# Streamlit UI
# =========================
st.title("📚 BookRAG Mini")
st.caption("一本书的可追溯问答系统|A citation-grounded RAG demo for book-length knowledge")
with st.sidebar:
st.header("设置")
top_k = st.slider("召回片段数量 Top K", min_value=1, max_value=6, value=3)
rebuild = st.button("重新构建索引")
st.markdown("---")
st.markdown("""
**Demo 目标**
- 文档切分
- 向量检索
- 引用回答
- 不知道机制
""")
if rebuild:
chunks, index = build_index()
st.success("索引已重新构建")
else:
chunks, index = load_or_build_index()
st.subheader("向知识库提问")
question = st.text_input(
"请输入问题",
placeholder="例如:为什么不能把近代出版现代化简单归结为技术替代?"
)
if question:
results = retrieve(question, chunks, index, top_k=top_k)
col1, col2 = st.columns([1.1, 1])
with col1:
st.markdown("### 回答")
answer = answer_with_context(question, results)
st.write(answer)
with col2:
st.markdown("### 检索到的来源片段")
for i, r in enumerate(results, start=1):
with st.expander(f"来源 {i}|{r['section']}|相似度 {r['score']:.3f}"):
st.write(r["content"])
st.caption(f"chunk_id: {r['chunk_id']}")
else:
st.info("请输入一个问题,系统会从图书知识库中检索相关片段并生成带引用的回答。")
st.markdown("---")
st.markdown("""
### 评估说明
这个 Demo 的重点不是让模型“自由发挥”,而是测试它能否在给定资料内回答问题。后续会继续加入:
1. 不同 chunk size 的对比;
2. 有无 rerank 的效果对比;
3. 问答评测集;
4. 忠实度评分;
5. 引用准确性检查。
""")
8. README.md
# BookRAG Mini
一本书的可追溯问答系统。
A citation-grounded RAG demo for book-length knowledge.
## 项目目标
这个 Demo 用来展示如何把一本书或一组长文本转化为可检索、可引用、可评估的 RAG 知识库。
它重点展示:
- 文档切分;
- 元数据设计;
- 向量检索;
- 基于来源的回答;
- “不知道”机制;
- 后续可扩展的评估框架。
## 快速开始
安装依赖:
```bash
pip install -r requirements.txt
```
运行:
```bash
streamlit run app.py
```
如果需要启用模型生成回答,请配置环境变量:
```bash
export OPENAI_API_KEY="你的 API Key"
export OPENAI_BASE_URL="https://api.openai.com/v1"
export OPENAI_MODEL="gpt-4o-mini"
```
如果使用兼容 OpenAI 格式的其他模型服务,可以替换 `OPENAI_BASE_URL` 和 `OPENAI_MODEL`。
## 数据格式
将图书样本文本放入:
```bash
data/book_sample.txt
```
建议使用如下格式:
```txt
# 第一章 标题
正文内容……
# 第二章 标题
正文内容……
```
## 当前版本限制
v0.1 版本只实现最小可用流程,尚未加入:
- rerank;
- 多 embedding 模型对比;
- 自动评测;
- 权限控制;
- 多文件上传;
- 前端美化。
## 下一步计划
- 加入 chunk size ablation;
- 加入人工评测集;
- 加入引用准确性检查;
- 加入问答日志;
- 发布为 Hugging Face Spaces Demo。
```
四、这三件事现在怎么组合成作品集首页的第一批内容
你现在已经有三个可放进作品集的东西:
1. 首页
标题:
Knowledge AI Lab:面向知识型工作的 RAG、内容评估与 AI 工作流实践
状态:
已有 v0.1 静态站点。
2. 第一篇文章
标题:
模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估
状态:
已有文章草稿、评分表、Prompt、错误分类框架。
3. 第一个 Demo
标题:
BookRAG Mini:一本书的可追溯问答系统
状态:
已有项目结构、依赖、示例数据、核心代码、README。
五、你接下来 7 天只需要照这个顺序执行
Day 1:上线首页
- 保存
index.html - 用 Netlify Drop 上传
- 得到一个临时网址
- 替换 Contact 里的邮箱/GitHub/知乎链接
Day 2:建立 GitHub 仓库
建两个仓库:
knowledge-ai-lab-site
bookrag-mini
把首页放进第一个仓库。
Day 3:发布第一篇文章
把上面的 LLM Evaluation 草稿发到:
- 公众号;
- 知乎;
- 作品集网站;
- Medium/LinkedIn 英文版以后再补。
Day 4–5:跑通 BookRAG Mini
本地运行:
pip install -r requirements.txt
streamlit run app.py
先不纠结效果,把流程跑通。
Day 6:替换真实样本文本
选一本你熟悉、版权安全的书或自写样本文本。
重点不是文本多,而是元数据清楚:
- 章节;
- 段落;
- 关键词;
- 术语;
- 人名;
- 时间;
- 引文。
Day 7:写 Demo 说明文章
标题:
我如何把一本书做成可追溯问答系统:BookRAG Mini v0.1
文章结构:
- 为什么从图书开始;
- 文档如何切分;
- 为什么必须带引用;
- 模型什么时候应该回答“不知道”;
- 下一版要加入什么评测。
六、非常重要:这不是最终版,而是“可被看见的第一版”
你现在最需要的不是一个完美系统,而是一个别人能点开、能理解、能判断你在认真做这件事的入口。
这三个东西已经构成了最小闭环:
一个网站壳子 + 一篇内容评估案例 + 一个 RAG Demo 原型。
这就已经不是“我对 AI 出版感兴趣”了,而是:
我正在构建面向知识密集型工作的 AI 知识系统作品集。
**出版只是我的第一个样板间。**Japgolly
“内容_hash”: “57ac0f72c7f91577”
}
已经给你做出 v0.1 可落地版本:
-
Knowledge AI Lab 静态站首页
- 上方 artifact 里的
index.html可直接保存使用; - 支持 GitHub Pages、Netlify、Vercel;
- 已包含首页、能力地图、精选案例、RAG、LLM Evaluation、AI Workflow、About 等区块。
- 上方 artifact 里的
-
LLM Evaluation 第一篇可发布案例
- 标题:《模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估》
- 已包含:
- 实验目标;
- 测试文本;
- 测试 Prompt;
- 评估维度;
- 错误类型分类表;
- 可发布文章正文;
- CSV 评分表模板。
-
BookRAG Mini 第一个 RAG Demo
- 已给出:
- 项目结构;
requirements.txt;- 示例数据;
app.py可运行代码;README.md;- 后续评估扩展方向。
- 已给出:
你现在只需要照这个顺序执行:
Day 1:保存 index.html,上线首页
Day 2:建 GitHub 仓库
Day 3:发布 LLM Evaluation 第一篇文章
Day 4-5:本地跑通 BookRAG Mini
Day 6:替换成版权安全的真实样本文本
Day 7:写 BookRAG Demo 说明文章
这三件事一旦上线,你就已经有了一个最小闭环:
网站壳子 + 内容评估案例 + RAG Demo 原型
这就不再是“想转型 AI 出版”,而是正式开始呈现为:
面向知识密集型行业的 AI 产品与知识系统实践者。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)