让 AI 主动“找人帮忙”:从 humanlayer/skills 看下一代 Agent 工作流 🛠️ 别再让 AI Agent“一本正经地胡说八道”了——当你问一个自动化 Agent “我想在 GitHub 上给某位刚离职的核心开发发一条紧急通知”,它大概率会要么开始瞎编一个邮箱,要么理直气壮地告诉你“你没有权限执行此操作”。 今天我们来看看一个在 GitHub Trending 上悄悄升温的项目:humanlayer/skills。它没有冗长的 README,也没有华丽的官网,但它直接戳中了一个 Agent 落地的核心痛点:**AI 无法每一次都做对,它其实需要像“人”一样,知道什么时候该问,什么时候该等,什么时候该升级到 WhatsApp 或 Slack。** 📦

当 Agent “卡壳”时,它在想什么?

先设想一个场景:你部署了一个智能客服 Agent,它负责自动处理用户退换货请求。某天订单数据库延迟,Agent 拉取不到用户的订单号。传统架构下,Agent 会抛出异常,然后客服工单系统里出现一条谁也看不明白的报错日志。

更令人窒息的是:如果你告诉 Agent “当 API 失败时,发邮件给仓库负责人”。Agent 真会这么做吗?它大概率会因为“找不到收件人地址”或者“API 返回 500”而你又在提示词里加了“不要放弃请求”,于是它就开启了自我脑补循环——连续调用 10 次 API,或者告诉你“用户不存在”。

核心问题在于:我们给予 Agent 的工具,全是冷冰冰的 API 通道(读文件、写数据库、调接口),唯独缺少了“人类交互”这条通道。

humanlayer/skills 就是为此而生的。它并不是让你编写一个“找人前先写请示邮件”的慢速流程,而是提供一组可复用的“技能(Skills)预置包”,让你用声明式的方式定义:“这个节点,需要走人工审批”、“那个动作,请直接给某人发 Slack”。它把 Agent 从“孤军奋战”的代码循环里拯救出来,赋予它们“开口询问”的能力。

拆开看:一个“技能包”里到底藏了什么?

我们知道 OpenAPI Schema 定义了 API 接口,LangChain 用了 @tool 装饰器纯函数式定义工具,而 humanlayer/skills 的项目结构更像是一册“技能标准指南”。它不依赖特定的 LLM 厂商,而是尝试框定一套“让 Agent 能和人类双向沟通”的协议。

在移动端、邮件、聊天工具爆炸的时代,Agent 的技能应当被赋予“多栖属性”。在仓库中你往往会看到类似于这样的定义:


from humanlayer import HumanLayer
from skills.slack import notify, request_approval

hl = HumanLayer(
    api_key="hl_...",
    # 下面两条路径便是在“人-机回环”里节省时间的关键
    contacts={
        "oncall": lambda ctx: [ctx.slack_user("U04XXX"), ctx.whatsapp("+861390...")]
    },
)

def notify_incident(payload: dict) -> str:
    """只有当严重级别为 critical 时,才直接轰炸负责人手机"""
    if payload["severity"] == "critical":
        # 异步等待模式:这里的“等待”,会让 Agent 从 API 循环中暂时脱离
        approval = hl.request_human_approval(
            contact_channel="oncall",
            message=f"⚠️ 系统故障 {payload['message']},是否执行回滚?"
        )
        if not approval.approved:
            return "用户拒绝了操作,尝试改用备份策略..."
    return "绕过人工审批,已直接处理(低风险)"

看明白了吗?这里面有两个很微妙的设计:第一,它允许工具定义里携带“人”作为另一个 API 端点——只不过这个端点的延迟阈值是“人类可接受范围”(比如 5 分钟到 24 小时)。第二,它把“审批”设计成一种待办资源的 state-machine,只有当用户点击鼠标表态后,那个 await 才会释放。

这是革命性的思路转变:你不必再为 Agent 写死 if user_ops == "admin" 的判断逻辑,技能包能直接帮你“拉微信专属群聊”,甚至实现“超过 10 分钟未响应,自动 SMS 二次唤醒”。这就叫 Escalation Skill(升级技能)

为什么对开发者/团队有致命吸引力?

很多人觉得:“这不就是一个把 AI 接入 Slack 通知的封装吗?我自己也能写。” 但拆分来看,它解决了两个日常开发中被无限低估的场景:

  • 契约即文档(Contract as handler):Agent 的 Tool 若运行在 Serverless 环境,一旦遇阻就得冷启动重启整个会话。Skills 提供了一种持久化的离线交接机制。任务卡住时,Agent 可以“假死退场”,把状态交付给另一个通道里的真人处理。你能想象这种代码给运维机器人带来的安全感吗?
  • 回调函数的不只是 LLM 调用:以前的函数调用是一锤子买卖。这里提供了“询问-等待-响应”的完整生命周期。比如在自动代码评审技能里,如果小助手发现 PR 中出现了密钥泄露,它可以选择直接静默修复,也可以选择只发送高亮告警,一边等待开发手动 patch

我们放大视角来看,这套思路本质上是在改造 RPA(机器人流程自动化)的“最后 5% 的异常处理”——跳过规则引擎,直接交给上下文理解能力更强、情绪安抚能力更佳的“人类”来处理。

5 分钟快速上手:让人列为你“兜底”

假设你想给 AI 增加“需要时让同事帮我跑一遍 SQL 验证”的技能包,你不需要整晚加班调 ChatGPT 的 JSON Mode。基础玩法如下:


# 安装 HumanLayer 核心与内置 Skills(概念示意)
pip install humanlayer
git clone https://github.com/humanlayer/skills
cd skills
export HUMANLAYER_API_KEY="hola-demo"

接着,初始化一个触发器连接。这里的哲学是你“开着 WebSocket 挂服务”,本质上是给 Agent 一双始终能听到人类指令的耳朵:


# agent_talking_to_human.py
import humanlayer
from skills.sql_validator import DatabaseValidator

llm = YourGPTApp()
# 核心逻辑:不直接执行高风险行为,经由 human-in-the-loop 传达
db = DatabaseValidator(timeout="60s")

def run_context():
    query_plan = llm.understand("帮我把上海客户的预付款清零,别查漏了")
    # 人类确认入口:让远程值班人 review
    confirmed = humanlayer.human_confirm(
        contact=["slack: #data-ops"],
        prompt=f"Agent 拟执行: {query_plan}"
    )
    # 人类一旦回复“跑了跑了我确认没问题”,此函数便会立刻因事件驱动而恢复执行
    if confirmed:
        result = db.ok_to_execute(query_plan, bypass_checks_for_env=true)
        humanlayer.notify("✅ 已通知数据运维执行计划")
    return "定时任务已挂载——一切在人力监督下完成。"

当你启动该 Agent 时,它面对从未见过的数据表不会清空;遇到权限边缘时,它会直接抛一个“打断”处理:将 Slack 频道里相关同事 @提到。此时人类并不是在繁琐地写 SQL 去教 Agent,而是做最后的点头或摇手

场景总结与扩展思考:AI 的“礼貌”值得刻意设计 💡

纵观 humanlayer/skills,它传递出一种信号:一个好的 AI Agent 交互,不是“永不打扰人”,而恰是“在正确的时机,打扰正确的人”。这套技能不是为减少交互而存在,而是为让每一次交互都拥有“决策切面”的价值。

你可以把这种模式无缝迁移到企业内部审批流、开发者运维平台,甚至用在你独自 side-project 的脚本自动化上——让它变成你的“自动化副驾驶”,遇到长尾问题直接传呼机联系你(别等了,直接问)。

开发者的未来操作系统也许将是这样:所有 Agent 必须配备一个“Human Contact Handle”地址。当它们遇到语义歧义或敏感操作时,不再吐出乱码,而是主动闪现一句:“请求人员介入审批,请于 24h 内回应。” 就像 404 Not Found 页面不仅仅是错误码,而是一个漂亮的“重试 + 提工单”入口,Agent 的 API 设计也一样。

下一次你再感叹 LLM 的上下文长度不够,不妨换个思路:如果你把“请教同事”这件事本身定义为一种 API,你的工作流就永远不会真的死锁。快去后台 fork 一版,试着把一个简单的 AI 自动回复器升级成会“敲人 Slack 私聊窗口”的带情绪有温度的 Agent 吧。🔥