请添加图片描述
请添加图片描述
请添加图片描述

请添加图片描述

请添加图片描述
请添加图片描述
![请添加图片描述](https://i-blog.csdnimg.cn/direct/e6933d9606694369a91df4a04f496fbe.png请添加图片描述

你已经把问题想得很清楚了,我接下来做的不是重复你的判断,而是把这套战略往下推一层——告诉你:为什么这条路在 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

  1. 新建一个文件夹:knowledge-ai-lab
  2. 把上面的代码保存为:index.html
  3. 打开 Netlify Drop:https://app.netlify.com/drop
  4. 把整个文件夹拖进去
  5. Netlify 会直接生成一个临时网址
  6. 后续再绑定域名,比如:
    knowledgeailab.com
    knowledge-ai-lab.com
    yourname.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。它的思路是:

  1. 读取文本;
  2. 切分成 chunks;
  3. 为每个 chunk 生成 embedding;
  4. 建立 FAISS 索引;
  5. 用户输入问题;
  6. 检索相似片段;
  7. 把片段交给模型回答;
  8. 显示引用来源。
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

文章结构:

  1. 为什么从图书开始;
  2. 文档如何切分;
  3. 为什么必须带引用;
  4. 模型什么时候应该回答“不知道”;
  5. 下一版要加入什么评测。

六、非常重要:这不是最终版,而是“可被看见的第一版”

你现在最需要的不是一个完美系统,而是一个别人能点开、能理解、能判断你在认真做这件事的入口。

这三个东西已经构成了最小闭环:

一个网站壳子 + 一篇内容评估案例 + 一个 RAG Demo 原型。

这就已经不是“我对 AI 出版感兴趣”了,而是:

我正在构建面向知识密集型工作的 AI 知识系统作品集。
**出版只是我的第一个样板间。**Japgolly
“内容_hash”: “57ac0f72c7f91577”
}
已经给你做出 v0.1 可落地版本

  1. Knowledge AI Lab 静态站首页

    • 上方 artifact 里的 index.html 可直接保存使用;
    • 支持 GitHub Pages、Netlify、Vercel;
    • 已包含首页、能力地图、精选案例、RAG、LLM Evaluation、AI Workflow、About 等区块。
  2. LLM Evaluation 第一篇可发布案例

    • 标题:《模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估》
    • 已包含:
      • 实验目标;
      • 测试文本;
      • 测试 Prompt;
      • 评估维度;
      • 错误类型分类表;
      • 可发布文章正文;
      • CSV 评分表模板。
  3. 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

  1. 新建一个文件夹:knowledge-ai-lab
  2. 把上面的代码保存为:index.html
  3. 打开 Netlify Drop:https://app.netlify.com/drop
  4. 把整个文件夹拖进去
  5. Netlify 会直接生成一个临时网址
  6. 后续再绑定域名,比如:
    knowledgeailab.com
    knowledge-ai-lab.com
    yourname.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。它的思路是:

  1. 读取文本;
  2. 切分成 chunks;
  3. 为每个 chunk 生成 embedding;
  4. 建立 FAISS 索引;
  5. 用户输入问题;
  6. 检索相似片段;
  7. 把片段交给模型回答;
  8. 显示引用来源。
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

文章结构:

  1. 为什么从图书开始;
  2. 文档如何切分;
  3. 为什么必须带引用;
  4. 模型什么时候应该回答“不知道”;
  5. 下一版要加入什么评测。

六、非常重要:这不是最终版,而是“可被看见的第一版”

你现在最需要的不是一个完美系统,而是一个别人能点开、能理解、能判断你在认真做这件事的入口。

这三个东西已经构成了最小闭环:

一个网站壳子 + 一篇内容评估案例 + 一个 RAG Demo 原型。

这就已经不是“我对 AI 出版感兴趣”了,而是:

我正在构建面向知识密集型工作的 AI 知识系统作品集。
**出版只是我的第一个样板间。**Japgolly
“内容_hash”: “57ac0f72c7f91577”
}
已经给你做出 v0.1 可落地版本

  1. Knowledge AI Lab 静态站首页

    • 上方 artifact 里的 index.html 可直接保存使用;
    • 支持 GitHub Pages、Netlify、Vercel;
    • 已包含首页、能力地图、精选案例、RAG、LLM Evaluation、AI Workflow、About 等区块。
  2. LLM Evaluation 第一篇可发布案例

    • 标题:《模型为什么会改坏一段专业文本:一次 LLM 内容忠实度评估》
    • 已包含:
      • 实验目标;
      • 测试文本;
      • 测试 Prompt;
      • 评估维度;
      • 错误类型分类表;
      • 可发布文章正文;
      • CSV 评分表模板。
  3. 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 产品与知识系统实践者。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐