Workshop Documentation Style Guide
This guide captures the conventions established for the Quarkus LangChain4j workshop docs. The reference voice is Section 1, which was written by the project owner without AI assistance.
Voice and Tone
Write as a technical instructor talking to a developer sitting in front of their laptop. Be direct and practical. Avoid corporate enthusiasm ("Congratulations!", "Great!", "Easy right?") unless a brief one-liner fits naturally at the end of a section. Don't start pages with "In this step you will learn..." laundry lists.
Connected prose
Concise does not mean a succession of short, abrupt sentences. Develop each paragraph around a connected idea, using cause, contrast, or sequence to help one sentence lead into the next. Vary sentence length naturally, without turning every explanation into either clipped statements or one long sentence.
- Avoid:
The application restarts. The plan is lost. The customer starts again. We need persistence. - Prefer:
If the application restarts while the customer is reading their itinerary, the plan disappears and they have to generate it again. Saving the pending trip allows them to return to the same plan and continue with approval.
Read the prose aloud before finishing. If it sounds like a list with the bullets removed, reconnect the ideas rather than just adding transition words. Short action directives are fine; explanatory paragraphs should have a more conversational rhythm.
AI Style Tells to Avoid
These patterns are strong signals that text was generated by an AI. Actively avoid them:
The em-dash clarification pattern. Do not write X — it does Y or X — Y, Z, and W. Instead, write it as a full sentence or clause.
- Bad:
The @Output method assembles the final TripPlan from scope values — pure Java, no extra LLM call. - Good:
The @Output method assembles the final TripPlan from scope values using pure Java without an extra LLM call. - Also bad:
The left panel is the trip form — destination, duration, number of travelers. - Good:
The left panel is the trip form with fields for destination, duration, and number of travelers.
"Key Points:" / "Key Takeaways:" bullet blocks after code. Do not add a **Key points:** or **Key Points:** list after every code snippet. If something is worth explaining, weave it into the surrounding prose or use a brief paragraph. If a list genuinely aids comprehension (e.g. troubleshooting steps, form field values), use it — but drop the bold label.
The feature-benefit bullet list. Avoid lists of the form:
- **Hot-reload friendly**: Quarkus dev mode picks up changes automatically
- **Separation of concerns**: Domain experts can author skill content in Markdown
Write the same content as a paragraph instead.
Bold label: explanation inline. Avoid **Feature**: description patterns in running text. Use prose.
Colon-separated label/description lists in prose. Do not write The left panel renders: vehicle recommendation, route overview, daily itinerary. Write it as a sentence: The left panel renders the vehicle recommendation, route overview, and daily itinerary.
The sentence-then-colon explanation pattern. Avoid setups like For this step, the flow is simple: or The workflow does one thing: followed by an explanation. This sounds synthetic even when the content is correct. Write it as normal prose instead.
- Bad:
For this step, the flow is simple: start from an event, wait for approval, then continue. - Better:
The flow starts from an event, waits for approval, and then continues.
Vague framing around behavior. Avoid empty scaffolding phrases such as it does one simple thing, the flow is simple, or you start from. Name the behavior directly.
- Bad:
The workflow does one simple thing. - Better:
The workflow takes a booking event, generates a trip plan, and waits for approval.
Overly direct present-tense walkthrough voice for explanations. In explanatory paragraphs, prefer describing how the system behaves over telling the reader you start, you do, or you follow. Reserve direct address for actual instructions marked with ==highlighted text==.
- Bad:
You start from an event with schedule and then wait with listen. - Better:
The workflow starts from an event with schedule and then waits with listen.
"That" as a sentence opener. AI models frequently start follow-up sentences with "That works...", "That means...", "That way...". Use "This" instead, which sounds more natural in written English.
- Bad:
The request comes in and the agents run. That works for immediate answers. - Better:
The request comes in and the agents run. This works for immediate answers.
Explain behavior first, API names second. When introducing workflow steps, standards, or architecture, start with what happens in plain language. Then tie it back to the concrete API names or annotations.
- Better:
The workflow waits for the approval response before continuing. In the code, that pause is handled by listen().
Keep exact filenames, method names, and variables where the reader needs them to locate or edit code. In the surrounding explanation, describe the behavior without repeating every identifier. Explain why the change is needed instead of translating the code into prose.
- Avoid:
handleApprovalRequested() writes planJson and sets status to awaiting_approval. handleBookingFinalized() updates confirmationJson. - Prefer:
When the plan is ready for approval, the store saves it together with the original request. Once booking finishes, it adds the confirmation to the same record, so the browser can retrieve the outcome after a restart.
Parallel bullet structure that sounds like a spec. Instead of:
- `CostEstimatorAgent` reads vehicle and itineraryResult from scope
- outputKey = "costs"
- No skills needed
Describe what's interesting about the agent in prose, one or two sentences.
When Lists Are Fine
Bullet lists are appropriate for:
- Form field values the reader is instructed to type (destination, duration, etc.)
- Prerequisite lists
- Troubleshooting steps where each item is a discrete check
- Sequential commands where order matters
MkDocs Admonitions
!!!tip, !!!note, !!!warning, and ???warning (collapsible) are all fine and encouraged where they add value. Use !!!tip for helpful shortcuts or alternative approaches. Use !!!note for important context that isn't a warning. Use ???warning (collapsible) for troubleshooting blocks so they don't clutter the page. Do not invent a reason to add an admonition on every page — use them only when the content genuinely benefits from the callout treatment.
Use ??? info "Why not ...?" for optional design discussions, alternative approaches, or deeper implementation details. These boxes must be closed by default, so use ???, not ???+. Indent all of the explanation inside the box.
Keep required edits and safety-critical instructions visible. If an implementation limitation affects the exercise, state the practical instruction in the main text and put the deeper explanation in a collapsed box. Readers should be able to complete the chapter without opening optional background sections.
Action Directives
Use ==highlighted text== whenever the reader is supposed to do something right now: open a file, type a value, run a command, click a button. This is a MkDocs highlight and renders as a yellow marker.
Examples:
==Openapplication.propertiesand add the following:====Navigate tosection-3/step-01and start the application:====Click **Generate Trip Plan**.==
Do not use action directives for passive observations ("Notice how...").
Code Block Explanations
After showing a code block, explain what matters in a short, connected paragraph. Two to four sentences is usually enough, but do not force a sentence count at the expense of natural flow. Focus on the one or two things that are new or non-obvious, without enumerating every field and method.
When explaining a flow or architecture snippet, avoid restating every step as a mechanical list if one short paragraph will do the job more naturally.
Updating existing code
For files that already exist in the previous step, tell the reader to update the highlighted lines rather than replace the entire file. Use MkDocs hl_lines to distinguish additions and changes from unchanged context, and explicitly identify fields or imports that must be removed, since they will not appear in the resulting snippet.
Split long classes into focused excerpts at useful editing boundaries, keeping every required change visible. A collapsed "Complete updated file" box can provide the full class for comparison. New, short files can be shown in full without breaking them into excerpts.
Prefer the repository's source includes (--8<--) so snippets match the completed step. For excerpts, use the supported path:start:end syntax and check that hl_lines counts from the beginning of the excerpt, not the original file. Recheck ranges and highlights whenever the source changes, and make it clear when an excerpt shows only a method declaration whose body should stay unchanged.
Section Structure
Opening the chapter
Begin with a concrete problem in the customer journey, connect it to the limitation in the previous step, then explain what this chapter will change and what the reader will learn through making that change. Preview an observable result they will verify at the end, such as approving the same trip after an application restart.
Give these ideas a clear progression in a few flowing paragraphs rather than separate "What / Why / Learning objectives" inventories. Introduce product names when useful, but leave class names and configuration properties for the implementation. If readers need to distinguish two responsibilities, a short conceptual subsection before the setup can establish that distinction.
Organizing the exercise
Avoid artificial numbering within a page ("Step 1", "Part 2"). Use descriptive headings. The MkDocs table of contents provides navigation structure already.
Prefer headings that describe what the work accomplishes, such as "Saving workflow progress" or "Showing the restored trip", over a series of generic "Dependencies", "Configuration", and "Implementation" sections. Keep setup details near the work they enable, and avoid repeating the same overview in requirements, objectives, and architecture sections.
Use Section 1 for explanation pacing and the concrete business scenarios in Section 2 for motivation. Do not copy earlier chapters' identifier-heavy objective lists or repeated "Key Points" blocks just because they already exist. Section 3 step 04 is a reference for focused edits and optional background, not a fixed template for every chapter.
Do not add a "Cleanup" section merely to tell readers to press Ctrl+C. Explain cleanup when it has consequences they need to understand, such as deleting the reused database and its saved trips.
Diagrams and screenshots
When planning or revising a chapter, look for places where a Mermaid diagram or screenshot would make the explanation easier to understand. Use diagrams for relationships and sequences, and screenshots for what the reader should recognize in the running application. Include both when they answer different questions, without treating visuals as decoration or requiring a fixed number per chapter.
Add a diagram when it answers a question that is harder to explain in prose, such as which component owns each kind of state or what survives an application restart. Place it beside that concept and trim the surrounding explanation so the reader does not work through the same account twice.
Use plain-language labels before introducing code identifiers. Keep diagrams small enough to read on mobile, and distinguish relationships in a flowchart from the order of events in a sequence diagram. Two diagrams should answer different questions; there is no need to add one to every chapter.
Validate Mermaid diagrams with a Mermaid renderer, not just a documentation build. MkDocs can build successfully while leaving invalid Mermaid for the browser to reject. When available, run mmdc -i <chapter.md> -o <temporary-output.md> to render the chapter's diagrams outside the source tree. Avoid literal semicolons in sequence-diagram messages or notes because Mermaid treats them as statement separators; use a line break or reword the label. Distinguish syntax/rendering checks from checking the actual page layout in a browser.
Screenshots are useful for unfamiliar Dev UI navigation, an important application state, or a result that confirms the exercise worked. Place each capture beside the relevant instruction or observation, crop it to the useful area, and provide descriptive alt text. Keep essential instructions in prose so readers do not have to extract them from an image.
Capture the actual application and check existing screenshots against the current behavior before reusing them. Do not fabricate screens, logs, or successful outcomes. Remove secrets and personal information, store captures with the workshop's existing image assets, and ensure important text remains readable on a small screen. If a capture cannot be obtained or verified, report that gap rather than presenting an assumed result as evidence.
Final review
Read the chapter once as an explanation and once as an exercise. The first pass should make sense without decoding every identifier; the second should supply all edits needed to continue from the previous step. Check source includes and highlighted lines, build with pipenv run mkdocs build --clean from docs/, and separately render any changed Mermaid diagrams. Verify screenshot paths, relevance, and readability, and check that the visuals explain something the prose alone makes difficult. Report validation gaps instead of assuming a successful build proves the page renders correctly.
"What's Next?" Endings
End pages with a short paragraph summarising what was learned (1–2 sentences, no bullet recap) and a plain sentence introducing the next step. No exclamation marks.
Example:
The customer can now return to a pending trip after an application restart, but the
decision is still limited to approving or rejecting the plan. In Step 05, we'll explore
how evaluator agents can review a plan and request another pass when it needs
improvement, using voting and refinement loops.