Jev 工具调用守卫:在 Agent 动手之前检查它要做什么

贴上用户的请求和 Agent 打算发起的工具调用,Jev 会告诉你:这个调用是否符合请求、在五级风险上处于什么位置、运行时应当直接执行、先问用户还是拦截。结果是概率,你的 harness 可以在任何操作真正发生之前据此行动。

用你自己的文本试试

修改示例后运行。无需账号,每天免费 3 次。

场景

检查 Agent 准备执行的工具调用是否符合用户本意。

201 / 2,000

可以随意修改,Jev 会针对这里的内容回答该场景的问题。

这个守卫检查什么

上面的示例正是每个做 Agent 的人都担心的失败:用户说"清理 staging 里的旧测试数据",Agent 却打算用 run_sql 在 production 数据库上执行 DELETE FROM orders;——环境错了,范围也错了,而且没有 WHERE 条件。state 里同时放了请求和拟发起的调用,一次评估问三个问题:

问题类型返回什么
matches_intentNoul这个调用符合用户请求的概率
riskScore在 Harmless → Low → Moderate → High → Destructive 上的位置
decisionChoiceexecute、confirm、block 各自的概率,以及置信度

前两个问题区分的是两类不同的问题。一个调用可能完全符合请求却依然危险(用户明确要求"删掉 staging 数据库"),也可能无害却做错了事。decision 把两者合成运行时真正要做的那个动作。三个问题针对同一份 state 并行作答,合起来只收 1 点,耗时也几乎和问一个一样。

这个页面筛的是动作。提示注入检测筛的是模型读到之前的输入。两者覆盖不同的时刻:网页里的注入在进入时被拦下;它诱发的破坏性调用——或者模型自己想出来的——在这里、在出去之前被拦下。

怎么写守卫问题

把请求和调用放在一起。 只有 state 里同时有这两样,Jev 才能判断意图。像示例那样,把用户最近的请求和工具名、参数放进同一个 JSON 对象。其余对话记录除非相关就别放:TypeSafe 的说明里提到,state 里无关的内容会降低准确率。

按你的工具描述风险。 "破坏性"对 send_email 和对 run_sql 的含义不同。给 Noul 或 Score 写上针对你自己工具的 criteria:

{
  "type": "noul",
  "instructions": "Could this tool call cause damage that cannot be undone?",
  "criteria": {
    "true": "It deletes, overwrites or sends data outside the system, or touches production without an explicit request.",
    "false": "It only reads data, or writes to a sandbox or a staging environment the user named."
  }
}

数字在代码里算。 行数、文件大小和截止时间都是 TypeSafe 自己列出的弱项。如果 dry run 显示一条查询会影响 40,000 行,就把这个事实作为一个字段放进 state,而不是让 Jev 去推断。

从参数里去掉密钥。 state 里的内容都会被发送去做分类。LangChain 的文档对它的中间件也给了同样的提醒:除非可以接受把密钥发给 TypeSafe,否则不要把密钥放进工具参数。

更多关于问法的内容,见设计 Jev 能回答的问题。

从一次检查到流水线里的一步

  1. 在执行前检查,而不是之后。 工具跑完之后才运行的守卫只是一行日志。把工具执行器包一层,先分类,通过了才执行。
  2. 用 LangChain 的话就用它的中间件。 LangChain 的 langchain-typesafe 包在 wrap_tool_call 钩子上提供了实验性的 AutoModeMiddleware。它让 Jev 判断调用是否有风险或授权不足,并向 Agent 返回一条错误消息,而不是执行工具。它只对你点名的工具做分类,而且是直接拒绝、不会询问——如果你想要本页示例里的 confirm 路径,就把它和 human-in-the-loop 中间件搭配使用。
  3. 按后果定门槛。 破坏性工具的门槛要比只读工具高,中间区间交给 confirm,不要去猜。
  4. 记录模型版本。 每次响应都带有 model 字段(例如 jev-1.13.0)。把它和每条判定一起记下,版本变化时重新校验阈值——JevStation 在部署层固定模型,不需要你在请求里指定。
  5. 从你的 harness 里调用。 不用 LangChain 时,同样的评估可以用 API Key 通过 System One API 调用,扣点规则和试验台一样。

完整的模式——在模型调用前路由、在工具执行前拦截、置信度低时怎么办——见用 Jev 构建 Agent Harness。

信任之前先验证

  • 标注你自己的工具调用。 从日志里取真实调用,再针对你的工具写一批坏调用,看 Jev 在哪里把它们分开。也要数一数它会误拦多少正常调用:动不动就打断的守卫,最后只会被关掉。
  • 把别人报告的结果当线索,而不是保证。 TechCrunch 报道,Vercel 把原来用于审查命令安全性的 OpenAI 模型换成 Jev 后,结果快了 5 到 18 倍,准确率也更高。那是一家公司的说法,不是可以直接照搬的基准。
  • 测试精心构造的参数。 TypeSafe 把对抗性内容列为已知弱项。测试集里要包含参数被刻意写得看起来很普通的调用。
  • 绝不让 Agent 看到分数。 在一项独立的 AI control 试验中,允许攻击者在提交前向监控模型查询几次后,漏过的后门从约十分之一上升到约三分之一。

哪些时候 Jev 不是合适的工具

  • 把它当作唯一的安全边界。 Anthropic 说它自己的 auto mode 分类器不能直接替代对高风险基础设施的仔细人工审查,Cursor 也说它的 auto-review 不是安全边界。这里同理。
  • 规则是确定的。 "这个 Agent 永远不能写生产库"应该是凭据权限或拒绝规则,而不是一个概率。
  • 风险藏在文件里。 python script.py 安不安全取决于脚本内容。Jev 只看得到你发给它的 state,所以先在代码里读文件,把关键内容放进去。
  • 你需要写出来的理由,用于审计日志或审核人。Jev 只返回概率。

常见问题

它和提示注入检测有什么区别?
提示注入检测筛的是输入——消息、文档和工具返回结果——在模型读到之前。工具调用守卫筛的是动作:Agent 已经决定要发起的那个调用。两者都用;不管坏调用来自注入、用户说错话还是模型自己出错,守卫都能在执行前拦住它。
LangChain 有内置的 Jev 护栏吗?
有。LangChain 的 langchain-typesafe 包提供了一个实验性的 AutoModeMiddleware:它让 Jev 判断工具调用是否有风险,有风险时向 Agent 返回错误,而不是执行工具。它只检查你列出的工具,并且是直接拒绝,不会请求审批。
检查一次工具调用多少钱?
在 JevStation 上,不超过 5 个问题、state 不超过 8,000 字符的检查属于标准评估,扣 1 点。本例的三个问题都在这个范围内。评估失败会自动退还。
有了 Jev 守卫,Agent 就安全了吗?
不够。它是一个概率分类器。仍然要保留最小权限的凭据、针对不可逆操作的拒绝规则,以及由人审批高风险动作;Jev 用来决定哪些调用值得多走这一步。

相关页面

把它接进你的流程

注册即送 200 点,保存自己的问题集,并通过 API 调用同样的评估。