←   Back to projectsCASE STUDY   /   01

RAG-POWERED BILINGUAL EDITORIAL WORKFLOW

AI BOOK INTELLIGENCE

A human-reviewed content production system spanning book discovery, source refinement, RAG retrieval and reranking, evidence-card generation, bilingual writing, and editorial delivery.

300+books screened
75book profiles
3thematic editions
1–2weeks per assisted cycle

Commercial-grade book content requires more than fluent generation. The system had to preserve source fidelity, handle dense context, surface useful evidence, support editorial judgment, and produce consistent bilingual output at scale.

01 / SYSTEM MAP

From source books to governed editorial output

The workflow deliberately inserts inspectable intermediate artifacts between retrieval and writing. Generation is never allowed to jump directly from a book file to a publishable article.
01

Prepare

Clean text, split chunks, build a structural memo and book analysis.

02

Index

Build BM25 and chunk-embedding indexes for local retrieval.

03

Materialize

Run three independent retrieval paths.

SUMMARY RAGKEYWORD RAGQUOTE RAG
04

Govern

Validate schemas, fingerprint sources, deduplicate and record card consumption.

05

Compose

Create a writing brief, bilingual summaries, A–Z essays and quote selections.

06

Review

Human editorial QA checks grounding, usefulness, overlap, tone and delivery.

02 / REAL INTERMEDIATE ARTIFACT

A material card is evidence, interpretation and risk in one object

This sanitized card was generated in the production workflow for The Light Eaters. It preserves the query, source chunks, excerpts, confidence and a review flag—not just fluent prose.
material_card.json
CARD ID
18_the_light_eaters…::summary::sq1::c0014::card001
TYPE
argument
TITLE
Plant intelligence: a scientific paradigm shift in progress
CONFIDENCE
0.78
RISK FLAG
needs_context
EVIDENCE TRACE

c0014 · “paradigm shift in science”

c0014 · “distributed neuronic substrates”

c0014 · “brainless mind”

03 / SELECTED IMPLEMENTATION

The control layer behind the writing workflow

These excerpts come from the project source. They show how retrieval confidence, traceability and model failure are handled in code.
retriever.pyIntersection-first hybrid retrieval+

Prioritizes chunks found by both BM25 and embeddings, then backfills with reciprocal-rank fusion. The retrieval method remains auditable downstream.

def _intersection_first_hybrid(
    bm25_results: list[SearchResult],
    embed_results: list[SearchResult],
    *,
    top_k: int,
    min_intersection: int = 0,
) -> list[SearchResult]:
    bm25_rank = {r.chunk_id: i for i, r in enumerate(bm25_results)}
    embed_rank = {r.chunk_id: i for i, r in enumerate(embed_results)}
    intersect_ids = [cid for cid in bm25_rank if cid in embed_rank]
    intersect_ids.sort(key=_rrf, reverse=True)

    for cid in intersect_ids:
        base = bm25_by_id.get(cid) or embed_by_id.get(cid)
        out.append(SearchResult(
            chunk_id=cid,
            score=HYBRID_INTERSECT_CONFIDENCE,
            method="hybrid_intersect",
            chapter=base.chapter,
            text=base.text,
        ))

    # Backfill via RRF when intersect is too small.
    for cid, _ in rrf_pool:
        base = bm25_by_id.get(cid) or embed_by_id.get(cid)
        out.append(SearchResult(
            chunk_id=cid,
            score=HYBRID_SINGLE_CONFIDENCE,
            method="hybrid_rrf",
            chapter=base.chapter,
            text=base.text,
        ))
schemas/cards.pyEvidence is a schema requirement+

A card cannot validate without source chunks and evidence. Fingerprints, risk flags and confidence travel with the writing material.

class SummaryMaterialCard(SchemaModel):
    card_id: CardIdStr
    query_id: QueryId
    card_type: CardType
    title: str = Field(min_length=1, max_length=80)
    summary: str = Field(min_length=1)

    source_chunks: list[ChunkId] = Field(min_length=1)
    source_fingerprint: FingerprintStr
    evidence: list[EvidenceItem] = Field(min_length=1)
    risk_flags: list[RiskFlag] = Field(default_factory=list)
    confidence: UnitFloat = Field(default=0.0)
materialize_book.pyStructured-output recovery+

Three progressively stricter attempts lower temperature, preserve raw responses for diagnosis and validate normalized cards before acceptance.

retry_configs = [
    {
        "system": "你是学术素材编辑。直接续写 JSON,不要任何前言或解释。",
        "prompt_builder": lambda: _build_llm_prompt(
            branch, query_data, chunk_dicts
        ),
        "temperature": TEMP_MATERIALIZE,
        "max_tokens": max_tokens,
    },
    # Second attempt tightens JSON constraints and lowers temperature.
    # Third attempt uses the minimal fallback prompt at temperature 0.0.
]

for attempt, config in enumerate(retry_configs):
    user_msg, prefill = config["prompt_builder"]()
    response = call_llm(
        client, model, config["system"], user_msg,
        max_tokens=config["max_tokens"],
        temperature=config["temperature"],
        prefill=prefill,
    )
    data = extract_json_from_response(response)
    if data:
        items = _normalize_llm_cards(branch, data, book_slug, qid)
        if items:
            return items

04 / SHIPPED ARTIFACT

The workflow produced complete bilingual editorial editions

The World of Plants is one of three completed EPUB editions. Its delivered structure includes a bilingual overview, 26 A–Z topic essays, 25 individual book summaries, author information and selected quotations.
Cover of The World of Plants bilingual ReadingCub edition
REAL DELIVERED ARTIFACT · SELECTIVELY SHOWN
25books in this edition
26A–Z topics
2writing languages
3completed editions
  • Three completed bilingual thematic editions covering 75 books.
  • An estimated AI-assisted production cycle of 1–2 weeks, compared with roughly one month of fully manual work.
  • A reusable process that connects research evidence to final editorial output rather than treating generation as a one-step task.
Time savings are practical estimates from production experience, not controlled benchmark results. Project materials shown publicly are selectively anonymized.