Human in the loop:Claude Code 人在回路插件,让只有你能做的任务始终在眼前
Claude 把只有你能做的事派成任务,放进“我的任务”面板,并在输入框下方计数,直到你处理。
权限
- 拦截工具调用能看到 Claude 发起的每一次工具调用(tool.call / tool.check),并可以阻止或修改它。
- 读取你的提示词可以看到你输入的内容和对话记录(prompt.* / session.append / session.messages)。
- 修改界面在 Claude Code 界面中绘制内容:横条、面板、状态文字、弹出通知(ui.render / $.ui.*)。
- 添加命令/工具注册新的斜杠命令或工具,供你或 Claude 调用($.command.register / $.tool.register)。
- 存储数据在插件的私有存储中跨会话保存数据($.store.*)。
- 实测版本
- v2.1.310
- 最近实测
- 需要
- Claude Code ≥ 2.1.287
- 显示位置
- 面板、状态栏、弹出通知、对话记录
这个插件能做什么?
Human in the loop 是 Tzafrir Rehan(tzafrir)开发的社区插件,是一款 Claude Code 人在回路插件,针对这样的情形:Claude 需要只有你能做的事,比如把密钥放进 .env、在预发布环境批准、在你自己的机器上运行命令,或者做一个决定。通常它会在回复中间提一句,这个请求很快就被刷上去了。有了这个插件,Claude 会把请求派成任务。
插件注册了三个工具:assign_task、list_tasks 和 withdraw_task,并在系统提示词中加入几行文字,告诉 Claude 凡是只有你能做的事(包括对它工作的审阅)都用 assign_task。任务包含标题、一句话理由、可选的“完成条件”,以及类型:do(你做完后标记完成)、answer(Claude 需要你的文字)或 choose(从 2 到 4 个选项中选一个)。未完成的任务等在“我的任务”面板中,并在输入框下方的状态栏计数,例如 ☐ 1 task for you · /my-tasks。你可以回复“完成”、选项、回答,或带理由的拒绝。
任务不会阻塞 Claude。它会继续做别的事,你的回应在你给出时作为一条消息送达。代码中的限制:最多 5 个未完成任务,同一个请求重复提出只算一个任务,并且只有主代理可以派任务。
演示
录屏中,我们在小型演示项目里启动加载了该插件的 Claude Code,让 Claude 用 assign_task 给我们派一个任务:把 STRIPE_KEY 放进 .env。Claude 调用工具后,对话记录里出现黄色的 ☐ Assigned you a task: Put your STRIPE_KEY in the .env file 一行,下面是工具结果,说明这是 #1 号任务,未完成任务为 5 个中的 1 个。输入框下方的状态栏显示 ☐ 1 task for you · /my-tasks,页脚右侧还有一条提示:human-in-the-loop: Claude assigned you a task: Put your STRIPE_KEY in the .env file. See /my-tasks。在这段较窄的录屏中面板没有自己展开,提示正是为此而设,所以视频里没有出现面板,也没有演示回答任务。
安装
使用安装区块中的任意一种方式;它们都直接从作者自己的插件市场安装。安装后请开启新会话,或运行 /reload-plugins。/my-tasks 会打开面板。
$ install human-in-the-loop
需要 Claude Code ≥ 2.1.287
从作者自己的 marketplace 安装: tzafrir/human-in-the-loop
1.在 Claude Code 中一行安装
/plugin install human-in-the-loop --marketplace tzafrir/human-in-the-loop粘贴到正在运行的会话中(v2.1.275+)。Claude Code 会先询问是否添加该插件市场。
2.从终端安装
claude plugin marketplace add tzafrir/human-in-the-loop claude plugin install human-in-the-loop@human-in-the-loop然后在所有已打开的会话中运行 /reload-plugins。
3.免安装试用
git clone https://github.com/tzafrir/human-in-the-loop claude --plugin-dir ./human-in-the-loop仅在当前会话中加载该插件,不会写入你的设置。
工作原理
hooks/register.tsx 是唯一的 hooks 模块。assign_task 的处理函数会检查参数,拒绝重复请求和第六个未完成任务,保存任务并打开面板。以下来自 hooks/register.tsx:
on('tool.call', { tool: ASSIGN }, async ($, e) => {
if (e.agentId !== undefined) {
return { deny: 'Only the main agent assigns tasks to the user. Say what you need from the user in your result instead.' }
}
const ask = parseAsk(e as unknown as Record<string, unknown>)
if ('error' in ask) {
return { deny: ask.error }
}
// ...
return { result: assignedOf(task, active.length + 1) }
})任务保存在 $.state 中,并在项目文件夹下为每个会话使用一个 $.store 键,由一个 60 秒的心跳写入,这样已结束或长时间无响应的会话,其任务可以由下一个会话接手。Claude 空闲时,你的回应通过 $.prompt.submit 发送;Claude 工作时,则通过 $.session.append 作为一行追加。prompt.compose 钩子加入引导文字,prompt.context 钩子在会话开始和压缩之后列出未完成的任务。
自定义
没有任何选项。你通过面板中的按钮和按键来操作:d 表示完成,1 到 4 选择选项,r 回答,x 拒绝,“Save for later”和“Send now”控制发送时机。长回答通过你自己的提示框输入:“Long answer…”会以 ↳ Answer to #3: 开头。若要修改限制,MAX_OPEN 和 MAX_TITLE 常量在 hooks/tasks.ts 中,BATCH_MS 在 hooks/register.tsx 中。
权限与安全
在运行任何东西之前,我们读过了插件加载的每一个文件:.claude-plugin/plugin.json、hooks/hooks.json、hooks/register.tsx、pane.ts、project.ts、tasks.ts、text.ts、类型声明和测试。没有 package.json、安装脚本、打包或压缩过的代码,除 PNG 和 GIF 图片之外也没有二进制文件。有 LICENSE 文件(MIT)。
- 网络、进程、文件、环境变量: 都没有。在 hooks 中搜索未发现
fetch、child_process、$.process、$.http、eval或动态import()。唯一的存储是$.store和$.state,数据模型见docs/privacy.md。没有遥测;作者的隐私政策称没有任何数据离开你的机器。 - 守护进程: 没有;
$.clock.every心跳只在会话运行期间存在。 - 对模型的影响: 这是值得注意的部分。插件加入三个工具、系统提示词末尾的三行文字(
STEERING)、一个列出未完成任务的humanInTheLoop上下文块,以及附在你下一条提示上的任务更新摘要。它还让这三个工具始终可见,而不是延迟加载。文字平实,与 README 一致;我们在代码和清单中没有发现隐藏字符或零宽字符(只有表情符号测试字符串中有)。 - 拦截类钩子:
tool.call钩子只响应插件自己的三个工具;prompt.submit会读取你的提示,以识别长回答(↳ Answer to #N:)并附上尚未发送的回应。看起来像密钥的回答会被拦下并给出提示,而不会发送。其他所有工具调用原样通过。validate提示这些钩子没有.catch。 - 它提交的提示: 以你的口吻写成的任务回应,以及一句固定的话:
I answered a task while you were finishing your reply; my answer is above. - 要求: Claude Code 中必须启用 function hooks(README 称其为抢先体验功能)。不需要外部二进制或账号。
claude plugin validate 通过,没有错误和警告;作者的测试在 Claude Code 2.1.310 上全部通过:192 个通过,0 个失败。
- 拦截工具调用
- 能看到 Claude 发起的每一次工具调用(tool.call / tool.check),并可以阻止或修改它。
- 读取你的提示词
- 可以看到你输入的内容和对话记录(prompt.* / session.append / session.messages)。
- 修改界面
- 在 Claude Code 界面中绘制内容:横条、面板、状态文字、弹出通知(ui.render / $.ui.*)。
- 添加命令/工具
- 注册新的斜杠命令或工具,供你或 Claude 调用($.command.register / $.tool.register)。
- 存储数据
- 在插件的私有存储中跨会话保存数据($.store.*)。
兼容性与故障排除
已在 macOS 上使用 Claude Code 2.1.310 检查(validate、测试和录屏)。如果没有任何反应:
- 已启用 function hooks,并且插件已在
/plugin中加载。 - 安装后你开启了新会话或运行了
/reload-plugins。 - 只有系统提示词带有引导文字时,Claude 才会派任务;在
-p(print)或 bare 模式下不会加入。 - 终端较窄时,面板不会自行打开。运行
/my-tasks,然后点击面板或按ctrl+x tab使用按键。 - 手机应用不绘制回答输入框,因此在那里只有“完成”、选项和立即拒绝。
常见问题
- 任务和 AskUserQuestion 有什么不同?
- AskUserQuestion 会阻塞 Claude,直到你回答。任务不会:Claude 在任务等待期间继续工作,你什么时候回应,回应就在什么时候作为一条消息送达 Claude。工具说明会告诉 Claude,会话中某个时刻才需要的事用任务。
- Claude 什么时候收到我的回答?
- Claude 空闲时立刻收到。Claude 正在工作时,回答会先保存,在这一轮结束时发送;如果还有未处理的任务,则等到没有任务打开时与其他回答一起发送。“Send now”按钮会立即发送,你输入的下一条提示也会带上它。
- 任务在 /clear、新会话或压缩之后还在吗?
- 在。未完成的任务保存在插件自己的存储里,以项目文件夹为键,该文件夹的下一个会话会接手它们。会话开始时和压缩之后,Claude 会再次被告知这些任务。
- 如果我的回答里有密钥怎么办?
- 看起来像密钥、令牌或私钥的回答会被拦下并给出警告,除非你按“Send anyway”,否则不会发送。工具说明也要求 Claude 让你把密钥放到它该在的地方,然后按 Done,而不是粘贴出来。
- 它会通过网络发送东西吗?
- 不会。我们在代码中没有发现网络、进程或文件系统调用。它用 $.store 保存任务,只把你的回应以你自己的话作为提示发送给 Claude。
# 相关插件
精选
精选Next Steps
每轮结束后,在 Claude Code 输入框上方显示 2 到 3 条可能的下一条提示词,按 1、2 或 3 即可填入草稿。
- 输入框上方
- 调用模型(消耗你的额度)
- 读取你的提示词
- 修改界面
已在 v2.1.291 实测