Agent如何传递不同类型的ID给MCP Server

1 概述

在Agent中,ID可以分两大类:一类是大模型推理出的业务ID(例如聊天记录中的ordier_id),另一类是Agent自身决定注入的上下文ID(例如user_id、tenant_id)。上下文ID 往往和系统的认证、权限相关,不能由大模型推理决定,必须由Agent完全把关

Agent作为mcp client,发送的数据包如下:

复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "cancelOrder",
    "arguments": {  
      // 1. 这里放的是【大模型推理】出的业务ID
      "orderId": "20260811-ABC"
    },
    "_meta": {      
      // 2. 这里放的是【Agent自定决策】的上下文ID(Spring AI 自动放这里)
      "userId": "U-999",
      "tenantId": "TENANT-BJ",
      "traceId": "a1b2c3d4"
    }
  }
}

arguments字段:只包含大模型从用户聊天记录中提取的 orderId。

_meta字段:包含 Agent(例如你写的 Java 代码)决策后强行注入的 userId、tenantId 等。

2 Mcp Client 端(Agent应用)如何把 ID 塞进 _meta

在 Spring AI 中,你通过配置 AsyncMcpToolCallback 的 toolContextToMcpMetaConverter,告诉框架:"请把 Java 上下文里的 ID 自动转为 _meta 字段"。

复制代码
import org.springframework.ai.mcp.AsyncMcpToolCallback;
import org.springframework.ai.tool.ToolContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

@Configuration
public class AgentClientConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder
            // 关键配置:定义如何将 ToolContext 转为 MCP 的 _meta
            .mcpToolCallbacks(List.of(AsyncMcpToolCallback.builder()
                .toolContextToMcpMetaConverter((Function<ToolContext, Map<String, Object>>) context -> {
                    // Agent 决策:从安全上下文或本地生成 ID
                    String userId = SecurityContextHolder.getContext().getAuthentication().getName(); // U-999
                    String tenantId = TenantContextHolder.getCurrentTenant(); // TENANT-BJ
                    String traceId = UUID.randomUUID().toString(); // a1b2c3d4
                    
                    // 返回的 Map 将自动成为 JSON 中的 _meta 对象
                    return Map.of(
                        "userId", userId,
                        "tenantId", tenantId,
                        "traceId", traceId
                    );
                })
                .build()))
            .build();
    }
}

业务调用代码(Service 层):

复制代码
@Service
public class OrderAgentService {
    private final ChatClient chatClient;

    public String handleUserRequest(String userInput) {
        // 用户输入:"帮我把订单 20260811-ABC 取消掉"
        // LLM推理出的ID会自动注入arguments字段
        // 上下文类型ID由上面的Converter自动注入_meta字段
        return chatClient.prompt(userInput)
            .call()
            .content();
    }
}

3 Mcp Server端如何拿到 _meta 里的 ID

在 MCP Server 端,Spring AI 会自动将收到的 JSON 解析并注入到 @Tool 方法的参数中。你需要让工具方法接收一个 ToolContext 参数,这个参数里就包含了 _meta 的所有内容。

Server 端工具定义代码:

复制代码
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.ToolContext;
import org.springframework.stereotype.Component;

@Component
public class OrderTools {

    @Tool(description = "根据订单ID取消订单")
    public String cancelOrder(
            // 1. 这里的 orderId 从 JSON 的 arguments 中获取(大模型推理)
            String orderId,
            
            // 2. 这里的 ToolContext 由框架自动注入,包含 _meta 的所有键值对
            ToolContext toolContext) {
        
        // 从 ToolContext 中提取 Agent 决策的 ID
        // 注意:这里拿到的 key 必须和 Client 端 Converter 里写的 key 一致
        String realUserId = (String) toolContext.getContext().get("userId");   // U-999
        String tenantId = (String) toolContext.getContext().get("tenantId");   // TENANT-BJ
        String traceId = (String) toolContext.getContext().get("traceId");     // a1b2c3d4

        // 安全校验:打印日志,确认 userId 绝对不是来自大模型
        System.out.println("安全校验:真实用户ID = " + realUserId);
        System.out.println("大模型提供的订单号 = " + orderId);

        // 执行业务,使用 realUserId 操作数据库,杜绝越权
        return orderService.cancel(realUserId, tenantId, orderId);
    }
}

4 总结:ID的流转路径

环节 动作 数据变化
用户输入 说了一句话 "取消 20260811-ABC"
大模型推理 提取业务参数 输出 arguments: {orderId: "20260811-ABC"}
Client Converter Agent 决策,注入上下文 自动生成 _meta: {userId: "U-999", ...}
网络传输 (JSON) 组装完整请求 params 里同时包含 arguments 和 _meta
Mcp Server 接收 框架解析 JSON 将 arguments 映射给 orderId 参数,将 _meta 映射给 ToolContext 参数
工具方法执行 获取并验证 业务代码从 ToolContext 拿 userId,抛弃大模型可能给出的任何用户标识
相关推荐
weixin_3988316618 分钟前
佛山AI推广GEO哪家做的专业
人工智能·python
luj_176827 分钟前
断舍离中的项目管理智慧
c语言·开发语言·c++·经验分享·算法
taller_200028 分钟前
【006】何时用 Python?何时用 Excel 公式?一文讲清
python·excel·公式·pie·py
老王爱玩车32 分钟前
关于函数递归的优缺点分析
开发语言·数据结构·学习·算法
2601_9623815841 分钟前
物联网场景下的 Python 边缘计算轻量化方案解析与实战落地
python·物联网·边缘计算·数据处理·轻量化方案
Dovis(誓平步青云)42 分钟前
同一条路线在手机和平板上怎样换一种排版
android·开发语言·数据库·智能手机·音视频
OPEN-F1 小时前
C++进阶教程:文件流与字符串流
开发语言·c++·算法
whcyhhh1 小时前
头歌实践教学平台:大数据存储2023(十三1)
大数据·数据库·python
2601_966949651 小时前
9:25-9:30 如何获取 A 股开盘基准价?QuantDash Python SDK 实战初始化量化策略状态
开发语言·人工智能·python·量化·quantdash·量化数据源