Writing

Building a compiler pipeline for a 300-page AI bookWriting Elements of Agentic System Design with Claude.

Source notes become ordered paragraph specifications and an open book.

At two in the morning, I was rereading hundreds of pages of technically coherent prose that sounded like nobody. Every section contained the same phrases and rhythms: "it's important to note," "let's delve into," "this approach offers several advantages." The facts were mostly right. The emphasis and voice were wrong.

I was using AI to write Elements of Agentic System Design, a 300-page technical book about building AI applications. My source material included interviews, notes, examples, and years of project work. The problem was turning that material into a book without letting the model invent the argument between the notes.

I eventually split the work into a pipeline. A move-annotated outline specified what each paragraph needed to do. Generation expanded those moves into prose. A style linter found recurring AI patterns. Separate revision passes repaired structure and voice at different stages.

One-shot generation lost my emphasis

My first attempt began with a long interview prompt. An agent asked questions about state, orchestration, tools, and context construction. I answered for hours and produced about fifty pages of organized transcript.

I gave the transcript to Claude and asked for the book. It generated plausible chapters, but their emphasis bore little relation to mine. Topics I had mentioned briefly became major sections. Ideas I had spent an hour explaining were compressed into a paragraph.

The transcript preserved my words without specifying how those words should become an argument. Claude had to decide which ideas were central, how they related, and where they belonged. Those decisions were exactly the work I needed to retain.

Source notes containing ideas of different emphasis become a manuscript with their proportions distorted.
Source material preserves the ideas, but it leaves their emphasis and order undecided.

I discarded the draft and added an intermediate step.

Chapter outlines improved coverage but remained too vague

In the second attempt, I worked chapter by chapter. Each chapter received an outline listing the topics, sequence, examples, and approximate length. Claude generated one section at a time.

This version had the right broad shape. It also contained two persistent problems.

The first was style. Stock phrases, symmetrical lists, generic transitions, and empty conclusions appeared throughout the manuscript.

The second was emphasis inside each section. An outline item such as "explain context construction" did not record the specific claim, mechanism, distinction, or example I wanted. Claude filled that missing structure with a reasonable interpretation of the topic. Reasonable was insufficient when the point of the book was my interpretation.

The outline told the model what a section was about. It did not tell the model what each paragraph needed to accomplish.

I separated those two failures. Style needed a verification pass after prose existed. Missing argument structure needed a richer representation before generation began.

An argument checkpoint precedes generation, and a style checkpoint follows the resulting prose.
The argument needs decisions before generation; sentence style needs a check afterward.

I turned my edits into a style linter

I first tried a larger style prompt. It banned phrases such as "delve" and "it's worth noting," supplied good and bad examples, and described the voice I wanted. Claude followed the rules briefly and then returned to its defaults across a long chapter.

I stopped asking the generation pass to handle content and style simultaneously. The first pass could focus on explaining the specified material. A second pass would find and repair known style defects.

I collected my repeated editing comments from the manuscript: "generic," "nobody says this," "empty transition," "same sentence shape again." I grouped them into concrete patterns a tool could detect:

  • banned phrases and stock transitions
  • paragraphs beginning with abstract throat-clearing
  • repeated contrast templates
  • excessive parallel lists
  • conclusions that restated the section without adding information
  • claims framed as universal lessons when the source described one project

The linter marked passages matching those rules. A rewrite pass received the flagged sentence, its surrounding paragraph, and the violated rule. It revised only the affected passage, then the linter ran again.

A style check isolates one phrase and replaces it while retaining the surrounding page.
The linter directs a rewrite to the passage that failed its check.

This did not define good prose. It removed defects I already knew how to identify. More importantly, it made those defects visible across hundreds of pages without requiring me to find every instance manually.

I specified the function of each paragraph

The linter improved the voice, while chapters still required heavy substantive editing. I could clean a paragraph perfectly and still have the wrong paragraph in the argument.

I needed an outline that preserved rhetorical function as well as topic. I used the idea of rhetorical moves from John Swales: a passage can make a claim, explain a mechanism, give an example, establish a contrast, ask a question, or resolve one.

I assigned each planned paragraph a primary move:

  • CLAIM states the position.
  • MECHANISM explains how or why it is true.
  • EXAMPLE makes the mechanism concrete.
  • CONTRAST distinguishes the claim from a nearby alternative.
  • QUESTION identifies a tension the section must resolve.
  • ANSWER resolves that tension.
  • CONSEQUENCE explains what changes for the reader or system.

The outline became more specific:

Context Construction:
  p1:
    CLAIM: Context is the model's complete input for one call
    KEY: Everything needed for that decision must reach the call

  p2:
    MECHANISM: Why the system must reconstruct context
    DETAIL: The model has no persistent memory between calls

  p3:
    CONSEQUENCE: What this requires from the application
    PRACTICAL: Load state and relevant history before every inference

I could now inspect the argument without reading generated prose. A claim with no mechanism lacked support. A mechanism with no example risked remaining abstract. A question with no answer left the section open. Repeated claims often indicated that two paragraphs were doing the same job.

Claim, mechanism and example specifications become three corresponding paragraphs.
Paragraph moves make the argument inspectable before generation.

The move notation also constrained generation. Claude received one paragraph specification at a time and could focus on expanding that move instead of inventing the section's structure while writing it.

The manuscript became a staged build

The final pipeline separated decisions that I had previously asked one generation call to make:

source material
  ↓
chapter structure
  ↓
paragraph moves
  ↓
prose generation
  ↓
style linting and local rewrites
  ↓
substantive review

Each stage preserved a different part of the book.

The source material contained the ideas and examples. The chapter structure assigned those ideas to an argument. The move outline specified the work of each paragraph. Generation chose sentences. The linter enforced recurring voice constraints. My final review judged whether the explanation actually landed.

Errors became easier to locate. Missing coverage belonged in the chapter structure. A weak explanation belonged in a mechanism move. An irrelevant paragraph belonged in the move outline. A stock phrase belonged in the style pass. I no longer regenerated an entire chapter to fix one local problem.

Coverage, explanation and stock-phrase defects point to chapter structure, a mechanism move and the style pass.
Each defect points to the part of the manuscript's structure that can repair it.

The intermediate representation made verification possible

Traditional outlines preserve headings and topic order. That was insufficient for this project because topic coverage was not the only thing I needed to verify. I needed to verify the argument carried my claims, distinctions, mechanisms, and examples.

The move outline recorded those elements directly. It became the source I reviewed most carefully because mistakes there propagated into every later stage. Prose remained easier to regenerate than the reasoning it expressed.

A corrected move specification supplies several regenerated prose pages.
One correction to the move outline can carry through every later version of the prose.

The linter served the same role after generation. It turned my recurring style objections into explicit checks and attached each failure to a small passage. Neither representation guaranteed a good book. Together they reduced two large, vague editing problems to inspectable units.

I still wrote the argument. I selected the material, decided the chapter sequence, specified the moves, and judged the final explanation. AI expanded those decisions into prose and helped repair known defects.

That division finally made a 300-page manuscript manageable. I stopped asking a model to infer the book from a pile of source material. I gave it an argument detailed enough to inspect before generation and a set of checks precise enough to run afterward.