DEV Community

shashank ms
shashank ms

Posted on

LLMs for Technical Writing: A Guide

I spend more time rewriting READMEs than I like to admit. In this guide, I will show you how I built a small CLI tool that turns bullet points and rough notes into production-ready technical documentation using an LLM hosted on Oxlo.ai. It is a single Python script that you can adapt for API docs, runbooks, or internal wikis.

What you'll need

Step 1: Initialize the Oxlo.ai client

Create a file named tech_writer.py. I use Llama 3.3 70B because it follows long system instructions reliably and outputs clean Markdown without fluff.

from openai import OpenAI
import os

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ.get("OXLO_API_KEY")
)

def draft_doc(notes: str) -> str:
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": notes},
        ],
        temperature=0.3,
    )
    return response.choices[0].message.content

Step 2: Lock down the system prompt

This prompt is the entire product. It constrains voice, structure, and formatting so the model acts like a senior technical writer instead of a chatbot.

SYSTEM_PROMPT = """You are a senior technical writer. Your job is to convert rough engineer notes into polished Markdown documentation.

Rules:
- Use clear, concise language. Avoid marketing speak.
- Structure output with a title, prerequisites, numbered steps, and a troubleshooting section if relevant.
- Use code blocks for commands, file paths, and config examples.
- If the input is ambiguous, make reasonable assumptions and note them in a "Notes" section.
- Output only the documentation, no meta commentary.
"""

Step 3: Add a self-review loop

First drafts always have gaps. I run a critique pass followed by a revision pass. On Oxlo.ai, this costs two extra requests, but because pricing is flat per request, the bill is predictable even when the notes and drafts are long. You can see the exact rates on the Oxlo.ai pricing page.

def critique_and_revise(draft: str, original_notes: str) -> str:
    critique_prompt = f"""Review the following technical draft against these original notes.

Original notes:
{original_notes}

Draft:
{draft}

List any missing steps, ambiguous instructions, or style issues. Be specific."""

    critique_response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": "You are a picky documentation reviewer."},
            {"role": "user", "content": critique_prompt},
        ],
        temperature=0.2,
    )
    critique = critique_response.choices[0].message.content

    revise_prompt = f"""Revise the draft based on this critique.

Draft:
{draft}

Critique:
{critique}

Output the full revised document only."""

    revised_response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": revise_prompt},
        ],
        temperature=0.3,
    )
    revised = revised_response.choices[0].message.content

    return revised

Step 4: Wire up the CLI

Add argument parsing and file I/O so you can pipe notes in from a text file.

import argparse

def main():
    parser = argparse.ArgumentParser(description="Generate tech docs from rough notes.")
    parser.add_argument("input", help="Path to a text file with rough notes")
    parser.add_argument("-o", "--output", help="Output Markdown file", default="output.md")
    args = parser.parse_args()

    with open(args.input, "r") as f:
        notes = f.read()

    print("Drafting...")
    draft = draft_doc(notes)

    print("Reviewing...")
    final = critique_and_revise(draft, notes)

    with open(args.output, "w") as f:
        f.write(final)

    print(f"Done. Wrote {args.output}")

if __name__ == "__main__":
    main()

Run it

Create notes.txt with rough bullet points:

Deploy the new auth service. Need Redis for sessions. Env vars: AUTH_SECRET, REDIS_URL. Docker build context is ./auth. Port 8080. Health check at /health. Remember to set memory limit to 512mb.

Then run the script:

export OXLO_API_KEY=your_key_here
python tech_writer.py notes.txt -o auth_deploy.md

The resulting auth_deploy.md looks like this:

# Deploy the Auth Service

This guide covers deploying the authentication service with Redis session storage.

## Prerequisites

- Docker installed locally
- Access to the container registry
- Redis instance reachable from the cluster

## Steps

1. Build the Docker image from the `./auth` directory:


   ```bash
   docker build -t auth-service:latest ./auth
   ```



2. Set the required environment variables:


   ```bash
   export AUTH_SECRET=your_secret_here
   export REDIS_URL=redis://host:6379
   ```



3. Run the container with the memory limit and port mapping:


   ```bash
   docker run -d \
     --memory="512mb" \
     -p 8080:8080 \
     -e AUTH_SECRET \
     -e REDIS_URL \
     auth-service:latest
   ```



4. Verify the deployment by checking the health endpoint:


   ```bash
   curl http://localhost:8080/health
   ```



## Troubleshooting

- If the container exits immediately, check that `REDIS_URL` is reachable.
- Ensure `AUTH_SECRET` is at least 32 characters long.

## Notes

- Memory limit is set to 512 MB as specified.

Wrap-up and next steps

You now have a working technical writer CLI backed by Oxlo.ai. Two concrete ways to extend it:

  1. Feed the final Markdown into a second Oxlo.ai call that generates a matching OpenAPI spec or JSON schema, reusing the same flat request cost.
  2. For runbooks that exceed tens of thousands of tokens in context, swap the model to Kimi K2.6. Oxlo.ai handles the 131K context window at the same per-request rate, which is useful for large migration guides or architecture decision records.

Top comments (0)