Warning: A lot of this was written with AI. You have been warned.
A command-line tool for analyzing and editing text files using large language models (LLMs). It provides several types of checks, including typo/grammar detection, clarity analysis, reader accessibility, value assessment, and function evaluation, all powered by the llm Python library.
This scaffolding is intended to be used after writing, preferably after a first or second draft, but before you send it to a friend or human editor.
When used with openrouter/anthropic/claude-sonnet-4.5, typo checking 600 lines (9000 tokens) costs around $0.05 to $0.15 per check. I've tended to need at least 5 runs to get most typos.
None of these prompts are instructed to make suggestions; ignore any suggestions that the LLM sneaks through. You can see the exact system and user prompt with "
typo- Spelling, grammar, and typo detection.clarity- Identifies unclear or confusing sentences.reader- Checks if text is accessible to a specific reader (e.g., "a beginner programmer"). Requiresreaderfield in profile.value- Assesses whether text provides value to the target reader. Requiresreaderfield.function- Checks if text accomplishes its intended function (inform, convince, entertain). Requiresreaderandfunctionfields.guess-function- Infers the text's intended purpose.guess-value- Infers the main value or benefit for readers.guess-reader- Infers the intended audience.
- Clone this repository:
git clone https://github.com/josephmckinsey/editing-with-llms cd editing-with-llms - Install:
pip install .
uv tool install /path/to/package --with llm-openrouteruvx --from editing-with-llms writing-buddy ...
- Make an
.editing-config.yamllike in the repository:
profiles:
quick-spell:
checks: [typo]
# Specify the model with name from `llm models list`.
model: openrouter/google/gemini-2.5-pro-preview
normal-reader:
reader: "a Bachelor's in mathematics who mostly knows what formal verification is"
checks: [reader, clarity, value]
model: openrouter/anthropic/claude-sonnet-4.5
math-doc:
checks: [typo]
model: openrouter/google/gemini-2.5-pro-preview
prompt_config:
scope_restriction: false # Broader check
custom_instructions: |
Ignore LaTeX commands like \textbf, \cite, etc.
The terms "morphism", "functor", and "category" are intentional jargon.
Do not flag mathematical notation in $...$ blocks.
# Streaming output for these modes
guess-audience:
checks: [guess-reader, guess-function, guess-value]
model: gpt-4o-mini
output_format: streamingIt is recommended that you use a powerful enough reasoning model. I've found that even low or medium reasoning improves the precision and recall dramatically.
I also recommend thinking quite hard about what readers and functions your work is supposed to serve.
- Run the tool from the command line:
writing-buddy [OPTIONS] INPUT_FILE--config PATH: Path to config file (default: search for .editing-config.yaml)--model TEXT: Override profile model--output-format [compiler|streaming|json]: Override output format--no-scope-restriction: Disable scope restriction--list-profiles: List available profiles and exit--dry-run: Print prompts without calling LLM--char-limit INTEGER: Warn if input exceeds this many characters (default: 50000)--help: Show this message and exit.
- Being able to reuse an LLM may allow you to have lower costs. For instance, you may ask for typos, get 10 errors, then you say "fixed", and it gives another 10. This can save on costs. Just being able to drop into "chat" mode is helpful often. We could even have a nice interface to responding to specific types of errors.
- This could be part of some generic prompt templating where mustache templated prompts can read input from yaml files.
- The request for a specific task should probably be given after the actual work itself, so that prompt cacheing works effectively.
- We could try merging all the prompts into one super system prompt, which could then be cached for different queries and chats.
So our options are:
{ALL INSTRUCTIONS} {TEXT} {SPECIFIC REQUEST}{GENERIC INSTRUCTIONS} {TEXT} {TASK SYSTEM PROMPT}{TEXT} {TASK SYSTEM PROMPT} "Can you check my work?"{TASK SYSTEM PROMPT} "Check the following: " {TEXT}Current process
MIT License