Inkwell MCP
一个对抗性的图表审阅者,帮助您提高数据墨水比率,并与图表进行更多沟通。
Inkwell分两次审核图表-- 物质 (数据是真实的吗?标题匹配吗?)那么 风格 (数据墨水比例、直接标签、颜色限制、空白)。如果它一直只在风格上拒绝,它就会升级为人类,而不是永远循环。
之前/之后
同样的数据(美国国家航空航天局GISS全球温度异常,1880-2024)。BEFORE未通过Inkwell的物质检查——标题描述了轴,而不是陈述发现。AFTER得分16/16。
之前:彩虹渐变条、网格线、通用标题(“随时间”)、不必要的图例、旋转标签,当数据位于-0.3/+1.3时,y轴延伸到-1/+2。Inkwell判决: SUBSTANCE_FAIL (S3:标题没有说明发现)。
之后:标题陈述了发现,副标题将NASA GISS命名为来源,在端点上直接标记,一种颜色,范围帧,在加速点进行有意义的注释。Inkwell判决: 批准,16/16.
自己生成这些: python examples/before_after.py
为什么
LLM驱动的图表审查听起来很棒,直到你尝试它。我们遇到的问题:
- 无限的拒绝循环。 “残忍”的提示会导致评论者永远拒绝一切。你解决它的问题,它就会发现新的投诉。没有终点线。
- 实质和风格纠缠在一起。 字体投诉会覆盖有效数据。当数据正确时,审阅者告诉您更改可视化类型。
- 评论者产生了幻觉。 视觉模型声称衬线字体为“无衬线”,在无网格图表上标记“网格线”,并发明不存在的违规行为。
- 回合之间没有记忆。 审阅者要求格式A,你遵守,然后它拒绝格式A并要求格式B。
Inkwell修复了这四个问题:
- 双通道架构 --内容和风格是独立的提示,有独立的判断。字体抖动不能覆盖有效数据。
- 有限评分 --风格在8个标准上得分为0/1/2。总分为16分。你确切地知道自己的立场。
- 抗幻觉说明 --“只对你能看到的进行评分。如果你不能识别字体,不要猜测。”
- HITL升级 --在同一张图表上只被拒绝了3次后,Inkwell停下来说:“给人看看。”不再循环了。
安装
pip install mcp anthropic # Anthropic backend
# or
pip install mcp openai # OpenAI-compatible backend (Gemini, Nemotron, Ollama, etc.)设置
克劳德代码
添加 .mcp.json 在项目根目录中:
{
"mcpServers": {
"inkwell": {
"command": "python3",
"args": ["/absolute/path/to/inkwell.py"],
"env": {
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}重新启动Claude Code以获取新服务器。
克劳德桌面版
添加 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)或 %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"inkwell": {
"command": "python3",
"args": ["/absolute/path/to/inkwell.py"],
"env": {
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}OpenAI兼容API
通过OpenAI SDK使用任何具有视觉能力的模型(Gemini、Nemotron、Ollama、vLLM、LiteLLM等):
{
"mcpServers": {
"inkwell": {
"command": "python3",
"args": ["/absolute/path/to/inkwell.py"],
"env": {
"INKWELL_BACKEND": "openai",
"INKWELL_OPENAI_API_KEY": "your-key",
"INKWELL_OPENAI_BASE_URL": "https://generativelanguage.googleapis.com/v1beta/openai",
"INKWELL_MODEL": "gemini-2.0-flash"
}
}
}
}配置
环境变量:
| 变量 | 默认值 | 描述 |
|---|---|---|
INKWELL_BACKEND | (自动检测) | "anthropic", "openai",或 "bedrock" |
INKWELL_MODEL | (每个后端) | 评审模型(必须支持愿景) |
ANTHROPIC_API_KEY | 无烟煤API键 | |
INKWELL_OPENAI_API_KEY | OpenAI兼容终结点的API密钥 | |
INKWELL_OPENAI_BASE_URL | OpenAI兼容端点的基本URL | |
INKWELL_HITL_THRESHOLD | 3 | 在人类升级之前拒绝风格 |
AWS_REGION | us-east-1 | 基岩区 |
INKWELL_BEDROCK_MODEL | us.anthropic.claude-sonnet-4-20250514-v1:0 | 基岩模型ID |
工具
review_chart
对图表图像进行两遍审查。
review_chart(
image_path="/path/to/chart.png",
context="Sales by region, Q1-Q4 2025. Source: internal CRM. Finding: APAC grew 3x while NA was flat.",
code=""
)第一关——实质内容 (二进制,快速失败):
- S1:真实数据(非虚构数字)
- S2:正确形式(图表类型适合数据)
- S3:可见的论点(5秒内找到)
- S4:数据完整性(标题与图表所示内容匹配)
如果实质内容失败,则跳过样式审查。先修复数据。
第二关——风格 (得分/16):
- C1:数据墨水比例
- C2:直接标签(无需图例)
- C3:颜色限制(最多2种有意义的颜色)
- C4:排版(标题=查找,副标题=数据描述)
- C5:空白(没有狭窄的标签)
- C6:范围帧(轴跨度数据,而非整数)
- C7:有意义的注释
- C8:背景(谁的数据、测量的内容、样本量)
得分:>=12通过,8-11需要努力,\", paper_title="Quarterly Sales Analysis" )
返回图表规格,包括确切的数据要求、推荐的表格和要省略的内容。会告诉你文本是否没有足够的定量数据来制作图表。
## HITL门
在3次风格拒绝(每次实质性通过)后,Inkwell停止审核并返回:
HITL ESCALATION: This chart has been rejected 3 times on style alone (substance passes every time). Style scores across rounds: [11, 10, 11]. The automated reviewer may be looping. Show the chart to a human and ask: 'Does this chart communicate its finding clearly? Any label overlaps or readability issues?'
这避免了LLM驱动的审查中最常见的失败模式:无限的挑剔循环,审查人员不断发现新的问题要抱怨。
## 工作流示例
1. 使用matplotlib/seaborn/plotly生成图表
1. 让克劳德复习一下: *“查看我在figures/sales.png上的图表——它按地区显示了第1季度至第4季度的收入”*
1. 克劳德打电话来 `review_chart` → 获得实质+风格反馈
1. 修复失败的问题,重新生成,重新提交
1. 批准(或HITL升级)后,您就完成了
典型的图表在第一次尝试时就通过了实质性内容,并在1-3轮内达到风格认可。
## 起源
建造于 [气动](https://github.com/ekras-doloop) 研究项目,我们需要审查11篇论文中的18个数据可视化。v1评论者(“残忍点。你几乎从不赞成。”)创建了无限的拒绝循环。v2(Inkwell)通过双通道架构和HITL门解决了这个问题。所有18张图表均在1-3轮内获得批准。
## 许可证
麻省理工学院