curl, a text editor, an API key, and a chat-completions-style endpoint. No specific model is required.
curl. Check them before starting.<your-model>, <your-api-endpoint>, and <your-api-key> with values from your provider documentation.Example: run the checks below. You should see a Python 3 version and a curl version, not a “command not found” error.
python3 --version
curl --version
What to do: create a working folder, generate one generic draft, and save it as your baseline. Then write a short style contract that names the voice, audience, sentence limit, and banned phrases.
mkdir -p style-lab/{prompts,drafts}
export API_URL="<your-api-endpoint>"
export API_KEY="<your-api-key>"
export MODEL="<your-model>"
curl -sS "$API_URL" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\":\"$MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"Write 150 words about why API logs matter. Use a generic, helpful tone.\"}],\"temperature\":0.7}" \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["choices"][0]["message"]["content"])' \
> style-lab/drafts/v1.md
wc -w style-lab/drafts/v1.md
Expected output: a word count close to 150 style-lab/drafts/v1.md.
Create the style contract and banned-phrase list:
cat > style-lab/style_guide.md <<'EOF'
Voice: direct, concrete, second person.
Audience: interns who know basic API calls.
Sentence limit: 25 words. Paragraph limit: 4 sentences.
Use active voice. Name the actor. Give one example per claim.
Do not invent facts, versions, prices, or URLs.
Mark unknowns as "check documentation".
Ban: in today's, it is important to note, delve, unlock, seamless, game-changer, not only.
EOF
cat > style-lab/banned_phrases.txt <<'EOF'
in today's
it is important to note
delve
unlock
seamless
game-changer
not only
EOF
Why: the baseline gives you something to compare against. The style contract turns vague instructions like “write naturally” into rules you can test with grep (a command that searches text for a pattern).
How to check: run the commands below. You should see the voice line in the style guide and seven banned phrases.
grep -n "Voice:" style-lab/style_guide.md
wc -l style-lab/banned_phrases.txt
Example: grep -n "Voice:" style-lab/style_guide.md prints 1:Voice: direct, concrete, second person.

What to do: create a system prompt, a small examples file, and a Python script that sends all three inputs to the model: the style guide, two before/after examples, and the draft to rewrite.
A system prompt is the instruction block sent before the user message. Few-shot examples are short sample inputs and outputs included in the prompt so the model can copy the target pattern.
cat > style-lab/prompts/system.md <<'EOF'
You are a line editor. Rewrite the draft for the stated audience.
Keep every fact. Replace vague claims with concrete actions.
Do not add model names, prices, URLs, or benchmark numbers.
If a fact is missing, write "check documentation".
Return only the revised text.
EOF
cat > style-lab/prompts/examples.md <<'EOF'
BAD: It is important to note that API logs are a game-changer for reliability.
GOOD: API logs record the request ID, status code, and latency for each call, so you can find the first failed request.
BAD: In today's fast-paced API landscape, teams must leverage observability.
GOOD: Add one log line at the API gateway: method, path, status, latency, and request ID.
EOF
Create style-lab/generate.py:
import json, os, pathlib, sys, urllib.request
root = pathlib.Path("style-lab")
system = (root / "prompts/system.md").read_text()
examples = (root / "prompts/examples.md").read_text()
style = (root / "style_guide.md").read_text()
draft = pathlib.Path(sys.argv[1]).read_text()
user = f"""STYLE GUIDE
{style}
EXAMPLES
{examples}
DRAFT TO REWRITE
{draft}
Rewrite the draft. Keep every fact. Replace generic claims with concrete actions. Return only the revised text."""
payload = json.dumps({
"model": os.environ["MODEL"],
"messages": [
{"role": "system", "content": system},
{"role": "user", "content": user},
],
"temperature": 0.4,
}).encode()
req = urllib.request.Request(
os.environ["API_URL"],
data=payload,
headers={
"Authorization": f"Bearer {os.environ['API_KEY']}",
"Content-Type": "application/json",
},
)
with urllib.request.urlopen(req) as response:
data = json.load(response)
print(data["choices"][0]["message"]["content"])
Run the rewrite:
python3 style-lab/generate.py style-lab/drafts/v1.md > style-lab/drafts/v2.md
Why: the model now receives positive targets, explicit bans, and a revision instruction. That leaves less room for generic filler than a one-line “make it human” prompt. Temperature is a sampling setting that controls randomness; 0.4 is a starting example, not a guarantee. Check your provider’s allowed range.
How to check: scan the revised file for banned phrases and compare word counts.
grep -nEi -f style-lab/banned_phrases.txt style-lab/drafts/v2.md || echo "PASS: no banned phrases"
wc -w style-lab/drafts/v1.md style-lab/drafts/v2.md
Expected: PASS: no banned phrases and two word counts in the same general range. If the count collapses, the model deleted content; rerun with the instruction “keep every fact.”
Example: a generic line such as “API logs are a game-changer for reliability” should become “API logs record the request ID, status code, and latency, so you can find the first failed request.”

What to do: check sentence length, inspect the diff, and edit only the lines that still sound generic. A diff shows what changed between two files.
python3 - <<'PY'
import re, pathlib
text = pathlib.Path("style-lab/drafts/v2.md").read_text()
sentences = re.split(r'(?<=[.!?])\s+', text)
long = [s for s in sentences if len(s.split()) > 25]
if long:
for s in long:
print("LONG:", s)
else:
print("PASS: 0 sentences over 25 words")
PY
Then inspect the change:
diff -u style-lab/drafts/v1.md style-lab/drafts/v2.md | sed -n '1,120p'
Expected: - lines contain vague phrases; + lines contain actors, actions, and concrete examples. If the diff is empty, the model ignored the prompt stack; rerun Step 2 and check that style-lab/prompts/system.md is not empty.
Use this checklist before publishing:
Why: automated checks catch repeated patterns; the diff catches silent deletions and invented facts. Human review is still required for accuracy.
How to check: the sentence-length script prints PASS: 0 sentences over 25 words, and the checklist has no unchecked boxes.
Example: if the script prints LONG: In today's fast-paced environment, teams must leverage..., rewrite it as Add one log line at the API gateway: method, path, status, latency, and request ID.
Before shipping a public prompt, run a robustness check with How to Test an LLM Application for Jailbreaks: Methodology and Ready-to-Use Prompts.
Problem. The banned-phrase check cannot find its file.
grep: style-lab/banned_phrases.txt: No such file or directorypwd, move to the project root with cd <your-project>, then recreate the file with the cat > style-lab/banned_phrases.txt <<'EOF' block from Step 1.Problem. The API rejects a request during a batch run.
429 Too Many Requestspython3 style-lab/generate.py style-lab/drafts/v1.md > style-lab/drafts/v2.md.Problem. The prompt is rejected as too long.
400 Bad Request: context_length_exceededwc -w style-lab/prompts/*.md style-lab/drafts/v1.md, keep only two example pairs, and shorten the style guide to the rules you actually test.You now have a repeatable loop: baseline, style contract, prompt stack, automated scan, and human edit. Next, turn the checklist into a pre-publish test and run a prompt-robustness check before shipping.
Can this make AI text undetectable?
No. AI detectors are unreliable, and the practical goal is clear, specific prose — not evasion.
Do I need a specific model?
No. Use any chat-completions-style endpoint that accepts system and user messages. Check your provider documentation for the exact request shape.
How many examples should I include?
Start with two short before/after pairs. Add another pair only when the same failure appears twice; check your context limit before expanding.
Should I lower the temperature?
Use a lower value when you need consistency, but test it. Temperature does not fix missing facts or a weak style contract.