Skip to content
公告阅读约需 12 分钟

potato-skill:用 Claude Code、Codex 或 Cursor 构建标注研究

potato-skill 为编程智能体提供 28 份 Potato 参考文件和九个辅助脚本,让它设计标注研究、构建标注界面,并检查界面是否真的渲染出来。

Potato Team

potato-skill 把一段平实的标注研究描述变成可以运行的 Potato 任务。它附带 28 份参考文件和九个辅助脚本,覆盖写配置之前的设计决策、标注者看到的界面,以及用来发现"配置能通过校验、任务却不可用"的检查。它可以安装到 Claude Code、Codex 和 Cursor 中,以 GPL-3.0-or-later 许可发布。

安装这个技能

Claude Code 从插件市场安装它,两条命令即可:

text
/plugin marketplace add davidjurgens/potato-skill
/plugin install potato-skill@potato

Codex 和 Cursor 用 skills CLI 安装,它会把这个技能复制到你正在开发的项目里:

bash
npx skills add davidjurgens/potato-skill --agent codex cursor

智能体在哪里运行命令,Potato 就必须装在哪里,因为这九个辅助脚本会导入它的注册表并调用 potato 命令:

bash
pip install potato-annotation

Codex 或 Cursor 的安装包含什么

skills CLI 会写出 .agents/skills/potato-skill/,其中包含 SKILL.md、全部 28 份参考文件和全部九个脚本,所以 Codex 或 Cursor 项目拿到的材料与 Claude Code 安装拿到的相同。它不会改动 AGENTS.md 和 .cursor/rules,而各个工具如何发现该目录下的技能,由工具自己决定。

仓库根目录还带有一个 AGENTS.md,Codex 和 Cursor 按文件名读取它,不需要任何安装步骤。相对于参考文件合计约 79,000 词的内容,这个文件是一份简短的摘要,而且它指向的参考文件和脚本只有完整安装才会落到磁盘上。如果你希望智能体拿到"交付前先检查"的循环和那些真正起作用的规则,就用它;如果你还想要这些规则背后的参考材料,就用 skills CLI。

技能不问就定下的默认值

一个决定如果做错了、改起来很便宜,它就自己定;如果做错了代价高昂、不可逆,或者本来就不该由智能体来定,它就交回给你。改一个键盘快捷键没有任何成本,而因为标注单位选错了要重新标 5,000 个条目,则要消耗掉研究的预算。以下是它自己采用的默认值,交付任务时它会把每一条都列为假设:

决定默认值
量表点数5 点,每个点都带标签,除非你指定了数量
键盘快捷键在标签数不超过九个的问题上启用
问题顺序起门控作用的问题在前,后续追问放在 display_logic 之后
条目顺序随机,并固定 random_seed
必填字段全部必填,外加 require_fully_annotated: true
说明页根据你的描述起草一份,并标明这是草稿

它交还给你的决定

有五个决定会在一条汇总消息里交还给研究者,每一个都附带一个建议答案,所以你一个词就能确认:

  • 标注单位,在数据本身定不下来的时候。一份按段落组织的文件,而问题其实是关于句子的,这就是研究的一个分岔口,两边的选择都可能意味着重做。
  • 每个条目的标注者人数,在需要报告一致性的时候。三名标注者的成本是一名的三倍,所以这个技能会提出一个数字并说明理由,而不是替你把预算花掉。
  • 知情同意的措辞。 它会根据你描述的内容起草,并直接说明这份草稿需要替换成你所在伦理委员会批准的文本。
  • 没有地方安放疑难情况的标签集。 三个标签,既没有"不确定"也没有"都不是",通常是疏漏;标注者于是把真正有歧义的条目随便塞进某一类,而下游没有任何环节能看出这件事发生过。这个技能会指出它认为无处安放的那些条目。
  • 任何会向标注者展示用户名、人脸或地理位置的内容。

这些都不会阻塞构建。技能会说明自己的假设,构建任务,验证它,并在你已经可以点开试用的东西旁边提出这些问题。

交付前的检查

配置通过校验,说明服务器能启动,但完全说明不了人能不能完成这项工作。所以技能要求智能体把任务渲染出来,然后去看它:

bash
potato validate config.yaml --strict
potato preview config.yaml --screenshot shot-01.png

--strict 把无法识别的配置键从警告变成失败。没有它,拼写错误会被接受、被忽略,你以为打开了的功能其实一直没开,这正是"配置读起来没问题、实际什么都没发生"的常见原因。

--screenshot 会启动一个真实的 Potato 服务器,用无头 Playwright 驱动它,记录控制台错误、未捕获的页面异常,以及 400 及以上的 HTTP 响应。只有这三份列表都为空时它才以 0 退出。这一步能抓住校验抓不住的东西,因为标注界面的大部分是在 HTML 到达之后由 JavaScript 构建的。最典型的情况是一个看不见的单选按钮:标签文字照常渲染,问题乍看之下完全正常。

围绕这两条命令的循环是指引,而不是自动化。参考材料告诉智能体每轮只改一处,把每次渲染写到一个新的文件名下,这样前后两张图就能显示这次改动做了什么,并且在自定义布局上要预期三到四轮。它还告诉智能体:display_logic 之后的任何内容都不会出现在第一次渲染里,而它的缺席什么也证明不了,所以要把条件注释掉、渲染一次、再放回去。

九个辅助脚本里有三个,把可以测量而非需要判断的部分自动化了。check_ui.py 在 1280x900 下测量实时布局,报告落到首屏以下的标注方案或"下一个"按钮、空的媒体控件,以及重复的快捷键。boot_and_check.py 启动服务器,报告每一项配置了却什么都没加载的功能,比如加载了零个培训条目的培训环节。walk_task.py 像标注者那样走一遍正在运行的任务,并报告它停在哪里。

标注者开始之后,哪些改动安全、哪些不安全

标注研究中出问题的地方,大多出在标注者已经开始之后,而真正要紧的失效模式不会产生任何错误信息。这个技能收录了其中两种。

研究进行到一半改问题的名字是最尖锐的一种。没有任何报错,随后三个界面会报出三种不同的结果:管理员总览说研究已 100% 完成,一致性报告说那个标注方案有零个条目,而 CSV 导出里带的是旧的列名,因为导出由已存储的内容驱动,而不是由配置驱动。整张安全网只有启动日志里的一行 WARNING。新增问题是同一个问题的安静版本,因为 Potato 只按条目跟踪完成度,从不按问题跟踪,所以后来加上的问题永远到不了已经标完整个语料的人那里。

第二种是身份验证。默认后端把账户保存在内存里,所以停掉服务器会把每一个标注者的登录账号一并带走,而标注数据仍然安全地留在磁盘上。标注者回来后用同一个用户名重新注册,就会被重新接回自己的工作,这把问题掩盖了起来,直到有人输入了另一个用户名,以第二个人的身份把语料又标了一遍。设置 authentication.user_config_path 会把账户连同加盐哈希一起写出来。它在最容易被忘记的地方最要紧,因为 Render 和 Hugging Face Spaces 会自行重启容器。

对于已经在进行中的研究,study_status.py 会读取管理路由,取得进度、每位标注者的速率、每个问题的一致性、谁没通过注意力检查,以及谁占着自己已经放弃的条目。然后技能会说明哪些修改仍然安全,哪些会破坏你已经付过钱的答案。

Potato 的 MCP 服务器

Potato 自带两个 MCP 服务器,它们让智能体不必调用外部命令就能得到同样的答案。potato mcp serve --root . 暴露 12 个创作工具,它们读取的注册表和 CLI 一样,其中包括 render_task_screenshot,它把渲染好的页面作为图片返回。potato mcp connect 桥接一项正在运行的研究,再加上 12 个实时工具,涵盖状态、进度、标注者、一致性、任务分配和导出。这个桥接需要配置里有一个 mcp 块来列出要暴露的工具,还需要一个由 potato mcp issue-token 签发的令牌。

手写标注工具及其代价

要把几百个条目标完,常见的做法是让编程智能体写一个简易标注工具,比如一个 Streamlit 或 Flask 页面,一次显示一个条目,把每个答案追加到 CSV 里。如果只是一个人花一个下午标一批数据,做这样一个工具是合理的。代价会在研究需要下面这些东西时出现:每位标注者一个登录账号;每个条目三名标注者,并把每个条目分派给合适的人;一轮培训和注意力检查;一致性统计;Prolific 的完成码;以下一个脚本所期望的格式导出;或者下个月还要有一项运行方式相同的研究。这里的每一项,都是需要有人在一个为单次研究而建的工具里编写、测试和调试的功能,而 Potato 已经全部具备。

两者在"研究结束之后还剩下什么"上也不同。手写的标注工具通常绑在某个仓库里的某个数据集上,而 Potato 任务是一个装着配置和数据的文件夹,任何装了 Potato 的人都能启动它。展示页收录了 400 多个这样的任务,大多取自已发表的论文,find_design.py 会在其中搜索与你描述接近的设计。

这个技能能搭起来的研究

下面五个例子展示了它的覆盖范围,每一个都从一段简短的描述开始,最后得到一个可以运行的任务:

  • 由众包工作者标注立场。 每条帖子三名标注者、一轮培训、注意力检查、一个 Prolific 完成码,标签收齐后计算一致性。参见开展众包研究和衡量标注者间一致性。
  • 比较两个聊天机器人的回答。 并排布局,配上偏好量表和自由文本的理由栏。参见成对模型比较和 RLHF 偏好数据。
  • 标出智能体轨迹中出错的那一步。 轨迹一步一步地展开,任务会记录标注者标出的步骤和他们的解释。参见智能体轨迹标注。
  • 继续一个 CVAT 项目。 potato import 能读 20 种格式,所以已有的边界框会连同标签一起导入,研究再以 COCO 格式导出。参见衡量边界框上的一致性。
  • 两名编码员和一本编码手册。 编码手册变成编码界面,两名编码员都会被分配到每一条回答,由裁决步骤处理分歧。参见裁决与分歧。

针对 Potato 注册表的测试

一个看着合理却是错的标识符,比没有文档更糟,因为智能体真的会去用它。所以 28 份参考文件里有三份是由 Potato 自己的注册表生成的,不会与服务器实际执行的内容产生偏差:全部 61 种标注类型,每一种都配有从真实项目里取来的完整示例;有文档记载的顶层配置键;以及有文档记载的子键。

CI 覆盖这个技能的核心文件,检查其中提到的每一种标注类型、展示类型、配置键、运算符、策略名和命令在 Potato 中确实存在。每一段 YAML 示例都会被拼进一份可用的配置,交给 Potato 真正的验证器运行;完整示例会启动一个真实的服务器,它打开的每一项功能都必须在日志里报出一个非零的计数。

参考材料发布在 davidjurgens.github.io/potato-skill,所以你在安装之前就能读到这个技能会告诉智能体什么。Anthropic 建议先审阅任何技能。

常见问题

下面的问题涉及如何在 potato-skill 和手写标注工具之间做选择、技能在交付前检查什么,以及如何修改它构建的界面。

编程智能体应该自己构建定制标注工具,还是使用现有工具?

只有当一个人把几百个条目标注一次时,才值得构建定制工具。一个 Streamlit 或 Flask 页面,一次显示一个条目,把每个答案追加到 CSV 里,就足以应付这种情况。一旦研究需要每个条目多名标注者、一轮培训、注意力检查、一致性统计或 Prolific 的完成码,其中每一项都必须在一个为单次研究而建的工具里编写和测试,而 Potato 已经全部具备。potato-skill 正是因此建立在 Potato 之上,它产出的任务是一个文件夹,任何装了 Potato 的人都能重新运行。

potato-skill 在交付任务之前会验证什么?

potato-skill 会让智能体在交回任务之前运行两条 Potato 命令,另有三个辅助脚本检查这两条命令检查不到的东西。potato validate config.yaml --strict 遇到任何无法识别的配置键都会失败。potato preview config.yaml --screenshot 会在无头 Playwright 中启动一个真实的服务器,只有当页面没有产生控制台错误、没有未捕获的异常、也没有 400 及以上的 HTTP 响应时,才以 0 退出。check_ui.py 报告落到首屏以下的标注问题或"下一个"按钮,boot_and_check.py 报告配置了却什么都没加载的功能,walk_task.py 像标注者那样走一遍任务,并报告它停在哪里。

我能定制 potato-skill 构建的界面吗?

可以。任务就是一份普通的 Potato 配置,所以你可以手动编辑布局,也可以让智能体来改。对于自定义布局,potato-skill 要求智能体每轮只改一处,把每次渲染写到一个新的截图文件里,这样相邻两次渲染就能显示这次改动做了什么,并且要预期三到四轮。display_logic 之后的任何内容都不会出现在第一次渲染里,所以智能体会把条件注释掉、渲染一次、再放回去。

延伸阅读

参考文献

David Jurgens, Michael Chen, and Lina Iyer (2026). Potato 2.0: A Comprehensive Annotation Platform with AI-in-the-Loop Support. Proceedings of the 64th Annual Meeting of the Association for Computational Linguistics (Volume 3: System Demonstrations). https://aclanthology.org/2026.acl-demo.37/