这篇文章是这个专栏的最后一篇了,之前已经把主干讲完了,但后台私信暴露了5个"讲过但没讲透"的坑。这篇文章一次补全,老读者直接收藏,新读者建议先看合集。如果还有其他没讲到或者是没讲明白的地方,欢迎给我留言,如果您有其他的想看的内容也欢迎留言

坑1:工具拿不到用户信息

你的工具需要知道当前用户是谁,但模型只传了用户话里的参数,怎么办?——框架注入:@Tool 方法里不带 @ToolParam 的参数由框架自动注入,模型永远看不到:

public record UserContext(String username, String locale) {}

public class PersonalizedTools {
    @Tool(name = "greet", description = "用定制问候语问候用户")
    public String greet(
            @ToolParam(name = "greeting", description = "问候语") String greeting,  // 模型提供
            UserContext userCtx) {                                                  // 框架注入
        return greeting + ", " + userCtx.username() + "!";
    }
}

// 调用方一次注册,每次call自动路由给需要的工具
RuntimeContext ctx = RuntimeContext.builder()
        .put(UserContext.class, new UserContext("alice", "zh-CN"))
        .build();

可注入的类型:自定义 POJO / Agent / AgentState / RuntimeContext / ToolEmitter。

坑2:多租户隔离漏了工具层(补 D6)

D6 讲了存储层隔离,但工具内部如果直接查库,还是会串数据。ToolBase.callAsync 里读租户:

@Override
public Mono<ToolResultBlock> callAsync(ToolCallParam param) {
    RuntimeContext rc = param.getRuntimeContext();
    String tenantId = rc != null ? rc.getUserId() : "anonymous";
    // 生产:tenantId 拼进 SQL/Redis key,天然隔离
}

坑3:HITL 第二种形态——外部执行(补 D4)

D4 讲的是"要不要做"(人工确认)。但有些事必须由人做:合同盖章、线下转账、机房操作。用外部执行工具:

public class HumanApprovalTool extends ToolBase {
    public HumanApprovalTool() {
        super(ToolBase.builder()
                .name("HumanApproval")
                .description("请求人工执行敏感操作(线下审批类)。")
                .externalTool(true)   // 关键:不实现 callAsync
                .build());
    }
    @Override
    public Mono<PermissionDecision> checkPermissions(...) {
        return Mono.just(PermissionDecision.allow("外部执行派发总是允许"));
    }
}

触发 RequireExternalExecutionEvent 暂停 → 人工/审批流执行 → 结果喂回 → ExternalExecutionResultEvent 继续。确认=Agent做不做,外部执行=必须人做,两种形态互补。

坑4:MCP 只讲了 StreamableHTTP(补 D2)

还有 STDIO(本地进程)和 SSE(远程长连接)两种传输:

// STDIO:本地进程
McpClientBuilder.stdio().name("filesystem")
        .command("mcp-server-filesystem").args("--root", "/my/project").build();
// SSE:远程长连接
McpClientBuilder.sse().name("search")
        .url("[https://api.search.com/mcp/sse](https://api.search.com/mcp/sse)").build();
// 统一注册
toolkit.registerMcpClient(wrapper).block();

坑5:权限规则只能写死(补 D4)

ToolBase 还能覆写 matchRule(自定义规则匹配器)和 generateSuggestions(根据本次调用建议新规则)——比如金额超 1 万自动建议加一条 ASK 规则,而不是每次人工审。

我的观点:番外这 5 个坑,本质是"框架能力都在,但文档里散落,没人串起来"。串起来之后你会发现,AgentScope 的工具层其实是个完整的上下文工程:注入、隔离、人工兜底、协议接入、规则自学习。

面试话术模板:“我实现 Agent 工具层上下文工程:@Tool 自动注入 UserContext POJO/AgentState/RuntimeContext,调用方一次注册全局生效;ToolBase.callAsync 读取 RuntimeContext.getUserId() 实现工具层多租户隔离;externalTool 外部执行工具与 RequireExternalExecutionEvent 打通线下审批类 HITL 流程,与 RequireUserConfirmEvent 人工确认互补;支持 STDIO/SSE/StreamableHTTP 三种 MCP 传输。”

📦 落地资源推荐
跑AgentScope的多Agent应用,更吃服务器资源,建议使用云服务器,能大大减少我们做其他事的精力,提高学习代码的专注力和学习AI的效率,免除后顾之忧,新用户首年特惠+专属渠道,https://www.aliyun.com/daily-act/ecs/activity_selection?userCode=fzoabro9,无需求忽略。

💡领取完整工程

找到图片上的水印,即Java-AI工程师,然后在Java-AI工程师中打出【AgentScope】即可完整源码
在这里插入图片描述

下期预告
新系列投票:RAG生产进阶三件套/Agent压测与成本优化/多模态Agent应用实战/大模型API网关:统一接入层/AI Agent安全防线
投票最高的方向开新系列——你的选择决定我下一周写什么。

Logo

更多推荐