内容
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/logo-dark.svg">
<img src="assets/logo.svg" width="180" alt="Timbro">
</picture>
</p>
<h1 align="center">Timbro</h1>
<p align="center">
<em>让你的写作听起来像你自己——即使在人工智能写作的情况下。</em>
</p>
<p align="center">
<img src="https://img.shields.io/badge/python-3.11%2B-111111?style=flat-square" alt="Python 3.11+">
<img src="https://img.shields.io/badge/inference-local%20·%20CPU--only-111111?style=flat-square" alt="本地CPU独占推理">
<img src="https://img.shields.io/badge/MCP-ready-111111?style=flat-square" alt="MCP就绪">
<img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT许可证">
</p>
---
LLM写作风格会漂移。今天的草稿听起来不像上周的,而上周的也不像人类或发布它的公司。Timbro解决了*一致性*问题:用你接受的写作作为你的声音种子,它会为你的草稿评分,判断它距离你的声音有多远,以及朝哪个方向修改——以明确的特征,而不是改变内容。
Timbro在你的AI代理中提供了一个可衡量的声音目标。
## 为什么
- **你,一致性。** 个人博客或新闻通讯应该听起来像一个人,而不是像哪个模型写的。
- **公司品牌一致。** 市场营销、文档和帖子在作者和工具之间漂移。用Timbro的品牌语料库作为种子,每份草稿都针对它进行衡量。
- **自我纠正的代理。** LLM流利但风格不一致。Timbro为代理提供了一个*可衡量的目标*和一个*明确的方向*,以便它可以朝着声音修改,而不是猜测。
## 数据
本README由Claude(Opus 4.8)编写。使用Timbro,您可以准确地看到它如何评估[我的实际博客声音](https://nicolobrandizzi.com/blog/)——与您的代理监视的数字相同:
<p align="center">
<img src="assets/distance.svg" width="780" alt="0到远轴:我的博客声音位于9-35区间;本README位于47,刚好在外面;营销炒作则在86处">
</p>
它位于47——在我的博客范围内(9-35)之外:可以识别但*不是*我的论文声音(代码量大,文档为主),但与销售语言在86处相差甚远。Timbro还会返回*方向*以缩小差距:**更多连词,更少抽象名词,更少代码块标点**。评估标准:[Horizon AI Fragmentation](https://nicolobrandizzi.com/blog/horizon-analysis/)、[Teaching Machines to Think](https://nicolobrandizzi.com/blog/rl-reasoning-llm/)、[The Digital Poisoners](https://nicolobrandizzi.com/blog/pravda-grooming/)、[The SOTA Trap](https://nicolobrandizzi.com/blog/sota-trap/)、[AI Gigafactories](https://nicolobrandizzi.com/blog/ai-gigafactories-tool/)。
## 工作原理
您的代理运行一个循环,Timbro评估每个循环:
```
评分 → 距离您的声音有多远,朝哪个方向移动
编辑 → 朝着指定的方向修改
重新评分 → 距离是否下降且含义是否保留?
重复 → 直到距离停止下降
```
每个评分都有三个清晰的层次和一个保护措施:
- **标量 - “距离有多远”** - 一个预训练的[StyleDistance](https://huggingface.co/StyleDistance/styledistance)嵌入,通过多模态**kNN**评估。
- **方向 - “朝哪个方向”** - **POS-unigram**比率,根据您的语料库进行z评分,并根据每个特征的R²加权。每次移动都是一个明确的习惯。
- **流畅度** - 段落嵌入轨迹(速度、容量、迂回程度)+ Schimel“回环”(`cos(first, last)`)。
- **内容保护** - 通过通用模型(all-MiniLM)的语义余弦:改变*如何*阅读,而不是*内容*。
## 安装
### 作为Claude Code插件(一条命令)
```
/plugin marketplace add nicofirst1/timbro
/plugin install timbro@timbro
```
这会一键安装**技能**并连接**MCP工具**(`score_voice`、`accept_rewrite`)。然后询问Claude *"让这篇文章听起来像我的声音"* 或 *"保持与我们的博客品牌一致"*。
安装后一次性设置(声音是个人化的,模型是本地的——插件不附带任何内容):
```bash
cd "$(/plugin path timbro)" # 已安装的插件目录
uv run python -m spacy download en_core_web_sm # 启用POS标记器
# 将您的帖子放入data/exemplars/(他人的帖子放入data/contrast/)
```
### 作为技能
仅复制技能,以便代理知道何时以及如何使用Timbro:
```bash
cp -r skills/timbro ~/.claude/skills/ # 个人,或按项目存储在.claude/skills/中
```
现在用同样的方式询问Claude——它会运行Timbro,读取方向,并提出保留内容的编辑。
### 作为MCP服务器(Claude Code、Cursor、Windsurf、Claude Desktop等)
```bash
# Claude 代码
claude mcp add timbro \
-e TIMBRO_EXEMPLARS=$PWD/data/exemplars \
-e TIMBRO_CONTRAST=$PWD/data/contrast \
-- uv run --directory $PWD timbro-mcp
```
或将此内容放入任意代理的`.mcp.json` / MCP设置中:
```json
{
"mcpServers": {
"timbro": {
"command": "uv",
"args": ["run", "--directory", "/abs/path/to/timbro", "timbro-mcp"],
"env": {
"TIMBRO_EXEMPLARS": "/abs/path/to/timbro/data/exemplars",
"TIMBRO_CONTRAST": "/abs/path/to/timbro/data/contrast"
}
}
}
}
```
代理获得两个工具:
| 工具 | 返回值 |
|---|---|
| `score_voice(text)` | `{distance, direction, flow}` |
| `accept_rewrite(original, revised)` | `{accepted, content_ok, similarity, distance_before, distance_after, improved}` |
### 作为一次性CLI
无需服务器,无需代理——只需评估一个文件:
```bash
uv run timbro score draft.md
cat draft.md | uv run timbro score - # 标准输入
uv run timbro score draft.md --json # 原始数据
```
### 从源代码(需用于上述MCP和CLI选项)
需要Python ≥ 3.11和[`uv`](https://docs.astral.sh/uv/)。
```bash
git clone git@github.com:nicofirst1/timbro.git && cd timbro
uv sync
uv run python -m spacy download en_core_web_sm # POS标记器(非pip依赖)
# 自带语料库(两个目录都忽略git——您的写作保持私密)
mkdir -p data/exemplars data/contrast
# data/exemplars/ → 定义您(或您的公司)的声音的帖子 — 6+
# data/contrast/ → 其他作者的帖子(“非我们声音”集),可选但更精确
uv run python eval/harness.py data/exemplars data/contrast # 确认它能区分您的声音
```
两个句子转换器模型在首次使用时从Hugging Face下载。所有推理**本地且仅限CPU**——无需API调用。
## 常见问题
**我需要对比集吗?** 不需要,但它可以使方向更加精确——没有它,每个特征看起来同样重要。
**它适用于单个作者/整个公司吗?** 两者皆可。“声音”就是您在`data/exemplars/`中放入的内容。混合语体(博客 + 论文)可以接受——评估者是多模态的。
**它会为您重写吗?** 不会,这是故意的。Timbro *衡量*;您的代理重写,Timbro评估结果(更接近声音 **和** 相同含义)。保持评分诚实和本地化。
## 布局
```
src/timbro/
├── core.py # 语料库 → POS特征 + StyleDistance嵌入 → VoiceModel
├── flow.py # 段落轨迹,循环返回,顺序门控
├── rewrite.py # 内容保留保护 + 接受-重写循环
├── report.py # 共享 {distance, direction, flow} 数据
├── cli.py # `timbro score`
└── mcp_server.py # MCP包装器:score_voice, accept_rewrite
skills/timbro/ # Claude Code技能
eval/harness.py # LOO-AUC,排列基准,方向符号测试
```