Pass text through a chain of 20 LLM translations and watch the meaning drift
Project description
llm-telephone
Pass text through a chain of 20 LLM translations and watch the meaning drift.
What is this?
llm-telephone is a command-line tool that feeds a piece of text through a configurable chain of language-to-language translations via the OpenRouter API, then brings it back to your chosen return language.
Like the childhood game of "telephone", each translation step introduces small distortions. After 20 hops through English → Japanese → French → German → … → Simplified Chinese, you can observe how meaning drifts, idioms break down, and cultural context gets lost.
Why is it interesting?
| Round | Language | Output |
|---|---|---|
| 0 | (original) | 龙,可是帝王之征啊 |
| 1 | English | The dragon is a symbol of imperial power. |
| 2 | Japanese | 龍は帝国の力の象徴です。 |
| 3 | French | Le dragon est un symbole de la puissance impériale. |
| … | … | … |
| 20 | Simplified Chinese | 龙是皇权的象征。 |
The original poetic exclamation (龙,可是帝王之征啊) loses its rhetorical flourish and emerges as a dry factual statement — same core meaning, completely different register.
Installation
pip install llm-telephone
Requirements
- Python 3.10 or newer
- An OpenRouter API key
Configuration
Set your OpenRouter API key in the environment before running:
export OPENROUTER_API_KEY="sk-or-..."
Alternatively, OPENROUTER_KEY is also accepted.
Quick start
# Translate a single phrase through the default 20-language chain
llm-telephone "The quick brown fox jumps over the lazy dog"
# Read from a file instead
llm-telephone --text-file origin.txt
# Only run 5 rounds
llm-telephone "Hello world" --rounds 5
# End the chain in English instead of Simplified Chinese
llm-telephone "Hello world" --rounds 10 --return-lang English
# Output structured JSON (useful for piping / analysis)
llm-telephone "Hello world" --rounds 5 --output-format json
# Save logs to files
llm-telephone "Hello world" \
--process-output process.txt \
--final-output final.txt
All options
Usage: llm-telephone [OPTIONS] [TEXT]
Pass TEXT through a chain of LLM translations and watch the meaning drift.
Options:
--model TEXT OpenRouter model ID. [default: google/gemini-3-flash-preview]
--rounds INTEGER Number of translation rounds. [default: 20]
--text-file PATH Read initial text from a UTF-8 file.
--process-output TEXT Write per-round log to this file path.
--final-output TEXT Write the final text to this file path.
--output-format [text|json] Output format. [default: text]
--return-lang TEXT Language to end the chain with. [default: Simplified Chinese]
--version Show the version and exit.
-h, --help Show this message and exit.
JSON output format
When --output-format json is used, the tool writes a single JSON object to stdout:
{
"model": "google/gemini-3-flash-preview",
"rounds": 5,
"return_lang": "Simplified Chinese",
"initial_text": "Hello world",
"final_text": "你好,世界",
"chain": [
{
"round": 1,
"target_language": "English",
"input": "Hello world",
"output": "Hello, world!",
"elapsed_s": 0.823
}
]
}
Python API
You can also use llm-telephone as a library:
from llm_telephone import run_chain
from llm_telephone.api_client import OpenRouterClient
from llm_telephone.languages import get_chain
client = OpenRouterClient(api_key="sk-or-...", model="google/gemini-3-flash-preview")
records = run_chain("Hello world", client, rounds=5, output_format="json")
for r in records:
print(f"Round {r['round']:02d} [{r['target_language']}]: {r['output']}")
Development
See CONTRIBUTING.md for setup instructions.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llm_telephone-0.1.0.tar.gz.
File metadata
- Download URL: llm_telephone-0.1.0.tar.gz
- Upload date:
- Size: 15.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7bca9f220bb77cfe83eb6d1e25bb26c46ae823e87c5f1800565cf3eaeba721b
|
|
| MD5 |
128ea857747d6b1d87eb6b19718827e6
|
|
| BLAKE2b-256 |
d7316972022a4ce5e315c96872d4f436f02df2697b46b1356c27edcd10630374
|
File details
Details for the file llm_telephone-0.1.0-py3-none-any.whl.
File metadata
- Download URL: llm_telephone-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaa5734c6b83bedc3442679beb93705117dfa13510159e459f43eb331ec1ee4a
|
|
| MD5 |
299bfb1a474202313f2c11517f790ced
|
|
| BLAKE2b-256 |
bc292ba604e9b7eb6084de4415e6ccc6788dac8f61d270709728d43ba04c0da8
|