Java for You AI Java 17实现Agent工具调用的白名单、预算与审计门禁

Java 17实现Agent工具调用的白名单、预算与审计门禁

服务器机柜

Agent 能调用工具以后,最危险的误区是把“模型发来函数名”当作“系统已经批准执行”。真正的执行权应该在你的应用手里。下面这段 Java 17 代码为每次候选调用检查三件事:工具是否在白名单、金额是否为合法正数、累计预算是否还够;任何一步失败都不给执行器机会。它适用于采购草稿、工单变更、云资源申请等有外部副作用的流程。

OpenAI Function Calling 文档讲的是模型如何提出工具调用;它不替你完成组织权限、金额上限和审计。最新 GPT-6 产品与智能界面方向恰好提醒我们:把“计划”和“批准”做成用户可见的两个状态,而不是一键自动化。

mermaid diagram

环境与完整代码

保存为 BudgetGate.java,执行 javac BudgetGate.java && java BudgetGate。无第三方依赖,示例未在本次任务中实际调用模型或线上工具;请在你的 Java 17 环境先编译并运行,再接入实际执行器。

import java.math.BigDecimal;
import java.util.*;

public class BudgetGate {
  record Call(String tool, String amount, String requestId) {}
  static final Set<String> ALLOW = Set.of("create_draft_purchase", "search_catalog");
  static final BigDecimal LIMIT = new BigDecimal("500.00");
  static BigDecimal spent = BigDecimal.ZERO;
  static final List<String> audit = new ArrayList<>();

  static boolean approve(Call c) {
    if (!ALLOW.contains(c.tool())) return deny(c, "工具不在白名单");
    final BigDecimal cost;
    try { cost = new BigDecimal(c.amount()); }
    catch (NumberFormatException e) { return deny(c, "金额格式错误"); }
    if (cost.signum() < 0) return deny(c, "金额不能为负");
    if (spent.add(cost).compareTo(LIMIT) > 0) return deny(c, "累计预算不足");
    spent = spent.add(cost);
    audit.add(c.requestId()+" ALLOW "+c.tool()+" "+cost);
    return true;
  }
  static boolean deny(Call c, String reason) {
    audit.add(c.requestId()+" DENY "+reason); return false;
  }
  public static void main(String[] args) {
    System.out.println(approve(new Call("create_draft_purchase", "120.00", "r-1")));
    System.out.println(approve(new Call("wire_money", "1.00", "r-2")));
    System.out.println(approve(new Call("create_draft_purchase", "400.00", "r-3")));
    audit.forEach(System.out::println);
  }
}

预期输出依次为 true、false、false:第一笔只创建草稿,第二笔工具不被允许,第三笔超过累计额度。不要把这里的内存变量直接用于生产;多实例服务必须用数据库事务或带条件写入的额度账本。

常见错误:仅限制工具名却不校验参数;把“创建草稿”和“提交付款”放在同一工具;重试时重复扣减;审计日志包含密钥或原始敏感提示词。它适合低到中风险、规则清晰的流程,不适合让模型自行决定付款、删库或人事处分。工程化改进包括租户隔离、幂等键、每工具限额和人工双人复核。5分钟练习:为 create_draft_purchase 加“单笔超过 200 元必须 REVIEW”的返回状态。

预算是产品能力,不是财务报表

最实用的预算规则通常分三层:单次调用限制爆炸半径,单个任务限制循环,租户日限额控制总体风险。调用前冻结额度,执行成功后确认,失败或取消后释放,才能避免并发任务都读到“余额充足”。若工具会产生不可逆副作用,预算通过也不等于可以执行:界面还要显示工具名、参数摘要、预计金额和确认人。审计记录至少包含请求 ID、模型版本、策略版本、决策、执行结果与操作者;但不应完整保存敏感提示词或凭据。上线后按拒绝原因统计:工具名频繁被拒,说明能力设计要拆分;预算频繁被拒,说明需要排队或重新分配额度,而不是悄悄把阈值调高。

官方文档:Function calling。你的Agent应该按调用次数、金额还是风险等级先触发人工确认?

关注「蜗牛聊AI」,一起看懂技术变化背后的真正机会。


本文首发于 java4u.cn,转载请注明出处。

本文由 java4u.cn 发布,可自由转载、引用,但需署名作者且注明文章出处(作者:白色蜗牛,出处:java4u.cn)。如转载至微信公众号,请在文末添加作者公众号二维码。 https://java4u.cn/ai/3082.html

作者: 蜗牛

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

联系我们

公众号:蜗牛互联网

在线咨询: QQ交谈

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部