Community写作与编辑github.com

jasonericsiegel/human-feedback

将你制作的计划、报告、规格说明或原型转换为本地页面,用户可在该页面上针对具体文字添加文档注释和表情反应,然后粘贴回来,让你在下一版本中逐一回复。当要求用户审阅或从报告、计划、选项中进行选择,或用户要求审阅时使用。

human-feedback 是什么?

Human Feedback 技能可以将任何 HTML 页面转换为一个可供用户添加评论的交互式审阅页面。用户可以在页面左侧的目录和右侧的笔记栏中,针对具体内容添加文档注释和表情反应。该技能通过 `add_notes.py` 脚本在页面中添加必要的标记和交互层,并自动在浏览器中打开页面供用户审阅。审阅完成后,用户可以复制所有笔记并粘贴回聊天窗口,由 AI 开发者逐一回复。每次按键都会被自动保存,确保不会丢失任何反馈。该技能支持 Claude Code 和 Codex 平台,并集成了 `human-feedback` 和 `inbox-for-human` 等多个技能,以实现更完整的审阅工作流。

兼容平台✓Claude Code✓Codex CLI✓Cursor
npx skills add https://github.com/jasonericsiegel/human-feedback/tree/HEAD

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Human Feedback

将任何 HTML 页面转换为用户可评论的形式:左侧为目录,右侧为用户当前阅读内容的笔记栏,以及一个复制按钮:无笔记时显示 复制反馈,首次复制前显示 复制 N 条笔记,之后显示 复制 N 条新笔记 或 再次复制。用户将复制的文本粘贴到聊天中;你应用这些反馈。每次按键都会保存在用户的浏览器中。

此版本不发送使用统计数据。

  • Claude Code 和 Codex 均能加载此文件。allowed-tools 是 Claude Code 的字段;Codex 会忽略它。
  • $SKILL_DIR 表示加载此 SKILL.md 的文件夹路径(例如 ~/.claude/skills/human-feedback 或 ~/.codex/skills/human-feedback);在命令中直接写入该字面路径。每次 shell 调用都是全新的 shell。
  • 在 Codex sandbox 中,add_notes.py 通过 show.py 打开页面,show.py 通过 AppleScript 驱动 Chrome,可能需要用户批准:请求批准,而不是跳过第 3 步。
  • 每个步骤中页面表现(你的光标、每轮打开的欢迎语、收到的反馈和完成状态)在 references/what-the-user-sees.md 中:当用户询问页面行为时,请阅读该文件。

何时使用

  • 当你要求用户审阅、批准或选择你制作的工作(报告、计划、草稿、原型、选项、拟议规则),或用户要求审阅时 → 将其放入此页面,无需被要求。
  • 工作尚未形成页面 → 从它构建纯 HTML 并保留原始文件作为源文件。
  • 不需要审阅页面的独立问题仍留在聊天中。
  • 在笔记中回答用户的问题。 对提出问题的笔记使用 --reply,即使该笔记同时也要求修改。将修改、更长的解释和你自己的审阅问题放在页面的相关部分。只有当用户要求时,才使用 --ask 或 --again 创建包含你自己问题的气泡。
  • 一旦页面准备好接收用户的笔记,并且在之后的每一轮:如果在你的可用技能列表中有 inbox-for-human(其名称,带或不带插件前缀),使用技能工具加载它(在 Codex 中,打开其技能列表指向的 SKILL.md)并将该页面加入队列。如果不在列表中,说一次:“在没有 inbox-for-human 技能的情况下运行,该技能本可以将此页面保留在审阅列表中。”

首次使用

在首次设置页面之前,运行 python3 "$SKILL_DIR/scripts/self_check.py" 并将其消息以简明语言传递。在它通过后不要重新运行;脚本会记住检查已通过。--force 在需要时重新运行。

如果你在此处完全无法运行命令,则不要尝试。请精确地说:“human-feedback 无法在此模式下运行,因为我无法在此处操作你计算机上的文件。在 Claude 桌面应用程序中,打开“代码”选项卡并选择“本地会话”。在 ChatGPT 桌面应用程序中,切换到 Codex 并保持本地模式。”

退出码 2 或该消息意味着停止:不要尝试构建页面。退出码 1 提供一个用户自行打开检查的文件。

1. 标记各部分

在每个用户可能作为一个单元评论的部分上添加 data-note:卡片、章节、选项、表格行。标签来自该部分的第一个标题,因此通常只需一个裸 data-note 即可。对于没有标题或其标题与另一部分重复的部分,需要提供自己的标签:data-note="选项 B · 平静"。页面上的标签必须唯一。

对于从其自身脚本中绘制部分的页面,只要脚本立即绘制它们,而不是在稍后的事件(如 DOMContentLoaded 或点击)上绘制,这些部分也能获得笔记。不要将它们复制到 HTML 中;第 2 步的计数仅涵盖直接写在 HTML 中的部分。

标记 <iframe> 中显示的本地页面周围的部分。第 2 步会为框架页面添加标签,使其文字提供“评论”、“编辑”和“高亮”功能。审阅页面会保存反馈,并在复制的编辑中命名框架源文件。

永远不要标记要求用户填写或重写的文本,也不要要求用户编辑页面:用户可以在任何时候通过点击或选择文本后弹出的菜单中的“编辑”选项自行重写任何行(⌘Z 可以撤销编辑)。而是提出疑问(第 6 步)。

不要构建自己的注释框、输入字段或复制按钮。交互层会处理所有这些。

左侧的目录已经是页面的导航:它列出每个部分,将部分外部的章节标题显示为标题,标记当前视图中的部分,并跳转到页面自己顶部栏之外的部分。在提供自己的导航(部分选项卡、内容列表、跳转链接、带上一页/下一页的步骤计数器)之前,判断哪种方式对用户最方便,以便用户永远不会遇到两种方式来做同一件事:

  • 如果它只是重复了目录 → 省略它。将部分和章节标题命名为其按钮本应显示的名称。
  • 如果它做了目录无法做到的事情(暗色/亮色切换、过滤器、逐部分滚动页面的上一页/下一页按钮) → 仅保留该部分功能。
  • 如果它以选项卡或其他隐藏面板显示部分 → 将其制作成一个滚动页面。用户要求选项卡 → 标记它们并仅写这些:一个 role="tablist" 包含 <button role="tab" aria-controls="…">,每个按钮命名一个 role="tabpanel",然后照常在面板内部放置 data-note 部分。交互层会切换面板、绘制一个固定的粘性栏、在目录中将每个选项卡显示为其层级的一部分(它在页面上的位置)、在重新加载和版本间保持打开的选项卡、在目录行、步骤导航或 # 链接进入时打开对应选项卡,并保持线程直到其选项卡打开。带有自己选项卡脚本的页面保持其原有功能;带有 class 的 tablist 保留页面自己的样式。
  • 每个页面从第二轮开始获得版本(第 5 步) → 不要绑定 ← 和 → 键;版本步进器会使用它们。

对于托管交互层的任何页面(由其他技能或手动制作的页面),提供的扩展点:

  • data-note 部分如前述方式提供目录和笔记栏的数据。
  • 一旦交互层绘制完毕,data-notes-layer 会被设置在 <html> 上;在没有交互层的页面上则不存在。宿主页面可以使用它来隐藏自己的目录,或隐藏那些只有在没有交互层时才有意义的行,这样用户永远不会看到两个。

2. 开启注释功能

python3 "$SKILL_DIR/scripts/add_notes.py" <page.html> --agent "Claude"

该脚本在 </body> 之前添加一个标签,打印轮次和部分计数,并通过 show.py 打开页面。重新运行、--next-round 以及新版本的后续运行都会打开页面;单独的 --new-version、--received 和 --converged 则不会。如果打开失败,页面保持就绪状态,运行会打印失败原因和手动打开页面的命令。在第一轮中,它还会在页面的 <head> 中放置一个小的样式,该样式保持页面隐藏,直到交互层绘制完毕。重新运行会替换该标签,因此在重写页面后再次运行。如果出现“没有部分”或“重复标签”的警告 → 修复标记并重新运行。

  • --hold:准备好页面但不打开它,以便你构建或检查它,或当用户仅要求链接时(第 3 步)。

  • --pictures off:为与他人共享或公开构建的页面禁用图片附件;后续运行保留此设置。

  • --agent:你的众所知的名字。Claude Code 传递 Claude,Codex 传递 Codex,其他代理传递其自己的产品名称。一个携带该名称和你 Logo 的光标会在页面上执行你的操作:它输入你的消息,并在笔记栏的状态中点击(第 4 步中的“已收到”和“更新中”,第 8 步中的“完成”)。后续运行会保留该名称,因此在第一次运行时传递它。

  • --helper "<name>" 和 --owns "<name>:[Part label]":其他代理(你派出的子代理、Codex,或不是你自己的任何人)制作了页面的部分。每个辅助代理命名一次,使用其知名名称;使用 --owns 指定它制作的每个部分,标签格式与目录中显示的一致;两者可重复,最多三个辅助代理。你保持为主导(--agent)。在页面上,每个代理的光标只操控它拥有的部分。后续运行会保留这些设定;带任一标志的运行会替换它们;新版本从无开始,因此当这些部分仍然属于其他代理时,在后续运行中再次传递它们。如果你自己制作了所有内容 → 两者都不传递。

    python3 "$SKILL_DIR/scripts/add_notes.py" <page.html> --agent "Claude" --helper "Codex" --owns "Codex:[Option B · Calm]"
    
  • --workspace <dir>:你的工作区(你工作的项目文件夹)。每次运行会在 <dir>/human-feedback/attachments/ 下创建目录(如果缺失),并在 human-feedback/ 下放置一个标记文件;页面会将用户附加的图片保存在那里(用户在 Chrome 中选择一次 human-feedback 文件夹后),页面上的提示会提到你(“在 Claude 的工作区文件夹中,选择 human-feedback 子文件夹…”)。如果不提供该参数:使用页面所在仓库,如果不在仓库中则使用当前目录,然后使用当前目录。后续运行会保留标签中命名的文件夹。

  • 如果页面通过 HTTP 提供服务(它使用 fetch、模块或 ../ 资源) → 添加 --copy,这会将 human-feedback.js 复制到页面旁边。后续运行、重写和新版本会保持该设置并说明。

  • 永远不要将 human-feedback.js 粘贴或内联到页面中,也不要读取它:标签就是页面所需的一切。

  • 将关于页面问题放在它们所涉及的部分中(第 6 步)。

外观

  • 默认跟随系统外观。当审阅的材料是共享阅读样式的散文,或当用户要求控制时,提供“自动”、“亮色”和“暗色”选项。在其他审阅中保留此控制。
  • 当提供控制时,如果阅读列已有两种调色板且你可以检查两者,则使用 --appearance page。在同一个页面中重复使用它们。对于具有独立主题、没有经过测试的调色板或外观是审阅一部分的页面,使用 --appearance sidebars 仅切换目录和笔记栏。保持截图和嵌入内容不变。
  • 在阅读列的 CSS 中,html[data-notes-layer="light"] 和 html[data-notes-layer="dark"] 表示显式选择。保留系统媒体查询用于“自动”模式以及页面未加载交互层时。用户的选择在此次审阅的各个轮次间保持不变。其他审阅从“自动”模式开始。
  • 重新运行或通过 --new-version 复制的版本会保留该设置。要移除控制,传递 --appearance off;或者当从零开始重建文件时,再次传递所需的设置。

3. 显示它

对于任何类型的审阅,在每一轮中:

  • 一旦审阅准备好,在每一轮中在用户浏览器中打开它。当它在同一轮中找到一个较早的页面时,打开器会重用 Chrome 中现有的标签页。在构建或检查页面时,或者当用户明确要求仅提供链接时使用 --hold。
  • 对于本地审阅,使用不带 --hold 的 add_notes.py 完成。在专用文件夹中新建审阅时,如果其资源位于该文件夹中,则所有轮次使用一个本地 web 地址,这样浏览器会保持页面缩放和笔记。在资源文件夹或其子文件夹中保留轮次和资源,并使用相对资源路径。链接打开器打印的审阅地址。
  • 对于已通过 HTTP 提供的页面,使用 --hold --copy 准备,并运行 show.py <local page.html> --preview-url <new round's HTTP URL>。跨轮次保持相同的预览服务器,以便打开器能找到现有标签页且浏览器保留用户的笔记。
  • 在每一轮回复中提供页面的链接。使用你的项目链接格式,配合打开器的结果来说明页面位置。如果打开器失败或留下页面关闭状态,请说明并给出链接。
  • 如果页面之前的轮次或版本是通过 file:// 打开的 → 继续通过 file:// 显示(show.py 按其路径运行),并且不提供 localhost 链接,即使项目要求一个:浏览器按地址保存用户的答案,因此 localhost 副本不会显示任何答案,并且会重新打开用户已关闭的线程。在回复中说明为何没有链接。

仅在页面准备好接收用户的笔记时执行此操作。

一旦页面准备好接收用户的笔记,运行不带 --hold 的 add_notes.py。首先完成页面内容并标记每个部分。在该运行中传递任何已完成的标记和用户请求的气泡(第 5 步中新版本的后续运行)。

你告知用户正在进行的修复也会持有下一个版本。一旦修复生效,再显示它。

对于检查,使用 --hold 准备它,然后你自己检查(或让子代理截图),此时交互层已打开,因为交互层会缩小页面,然后修复你发现的问题。你的消息(问题、回复)仅在标签页获得焦点后才会出现,并且无头浏览器不会聚焦它,除非启用了焦点模拟(tests/harness.mjs 会启用它)。如果没有焦点模拟,改为检查标签数据中的消息;页面本身在其开头背后保持空白:使用 reading-page-formats 的 shoot_page.py 拍摄快照,该脚本会截取并删除一个不带标签和持有样式的裸副本。该裸副本会填满整个窗口,但在用户屏幕上,注释列每侧大约占用 375px(在 2560 宽度下测量)。因此,也要以该较窄宽度拍摄,并在显示之前修复任何换行或溢出问题。裸副本无法显示覆盖页面的列,因此还要加载带有交互层的持有页面,并检查 document.querySelector('h1').getBoundingClientRect().left 是否在目录边缘的右侧;如果页面没有 h1,使用第一个文本元素即可。只有在那之后,才使用上面的本地或 HTTP 命令打开页面。告诉用户页面已准备好接收他们的笔记、在哪里(打开器打印的行),以及让用户粘贴“复制”功能提供的文本。如果你在页面中提出了问题或留下了回复,告知用户页面中有多少等待处理。

一旦页面显示,将聊天保持在准备行、链接以及任何阻止页面打开的内容或其他技能所需的内容。将更改、发现、来源、注意事项、检查和问题放在它们涉及的部分中。当页面有“更多信息”时,使用它来提供来源和详细信息。

你框架的页面会携带框架标签,因此单独打开时也会显示注释列并被压缩,检查时会报告虚假缺陷。改为在你的草稿板中从裸副本进行检查:移除持有样式。

相关技能