三:Agent 自动评估体系与 A2A 协议实战:让你的 AI 智能体从“能用“走向“可靠“

AI Agent评估:指标、策略与最佳实践 AI智能体正逐渐融入到各个领域,从日常的对话助手到复杂的工作流程自动化,其应用范围不断拓展。然而,确保这些智能体能够可靠、高效地完成任务至关重要,这就使得AI智能体评估成为了人工智能发展过程中不可或缺的一环。本文将深入探讨AI智能体评估的指标、策略以及最佳实践,为读者全面解读这一关键领域。 阅读详情

Agent 自动评估体系与 A2A 协议实战:让你的 AI 智能体从"能用"走向"可靠"

前言

前两篇文章中,我们从零构建了一个具备工具调用、RAG 和记忆能力的单体 Agent,又用 Multi-Agent + MCP 协议搭建了企业级协作架构。但到了落地阶段,几乎所有团队都会遇到同一个灵魂拷问:

“Agent 的回答准确率到底是多少?怎么衡量?出了问题怎么定位?”

没有评估体系,Agent 就永远停留在 Demo 阶段。与此同时,Google 提出的 A2A(Agent-to-Agent)协议 正在补全 Agent 生态的最后一块拼图——跨系统、跨组织的 Agent 通信。

本文将从这两个方向入手,帮你把 Agent 从"能用"推向"可靠"。


一、Agent 评估:为什么它比你想的难得多?

1.1 传统测试为什么不够用?

在传统软件开发中,我们习惯于确定性的单元测试:输入 1+1,期望输出 2。但 Agent 系统有三个根本性的不同:

差异一:输出不确定性

同样的问题,Agent 可能给出措辞完全不同但含义等价的回答。"A 栋今日能耗 3856 kWh,超出均值 84%“和"A 栋办公楼当前用电 3856 度,较历史均值偏高约八成”——这两句话表达的信息一致,但传统的字符串断言会直接判定失败。

差异二:执行路径不确定性

Agent 可能通过不同的工具调用序列达到相同的结果。"查 A 栋能耗"这个需求,Agent 可能先查实时数据再查趋势,也可能反过来。两条路径都是合理的。

差异三:多步推理的链式误差

Agent 的 ReAct 循环可能包含 3~5 步推理,每一步都有出错的可能。一个看似简单的失败,根因可能在推理链的第二步。

1.2 Agent 评估的四维模型

要系统性地评估 Agent,我们需要从四个维度建立度量标准:

┌────────────────────────────────────────────────────┐
│                 Agent 评估四维模型                   │
│                                                    │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐         │
│  │ 任务完成  │  │ 工具调用  │  │ 回答质量  │         │
│  │ 准确率    │  │ 正确性    │  │          │         │
│  │          │  │          │  │          │         │
│  │ Agent 是  │  │ 调用了正  │  │ 回答是否  │         │
│  │ 否完成了  │  │ 确的工具?│  │ 准确、完  │         │
│  │ 用户意图?│  │ 参数对吗?│  │ 整、无幻  │         │
│  │          │  │ 顺序合理?│  │ 觉?      │         │
│  └──────────┘  └──────────┘  └──────────┘         │
│                                                    │
│  ┌──────────────────────────────────────────────┐  │
│  │              执行效率                          │  │
│  │                                              │  │
│  │  Token 消耗量、工具调用次数、端到端延迟        │  │
│  └──────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────┘
维度含义怎么衡量
任务完成率Agent 是否正确理解了用户意图并完成了任务端到端判定:任务成功 / 失败 / 部分成功
工具调用正确性调了哪些工具?参数对不对?顺序是否合理?对比预期工具调用序列
回答质量回答是否准确、完整、没有幻觉?LLM-as-Judge(用大模型评判大模型)
执行效率消耗了多少 Token?调了几次工具?耗时多少?数值指标统计

1.3 LLM-as-Judge:用大模型评判大模型

这是目前 Agent 评估领域最实用的方法论。核心思想是:设计一个专门的"评审 Agent",让它根据预设的评分标准对"被测 Agent"的回答打分。

为什么不用人来评?因为人工评估成本高、速度慢、标准不统一。一个包含 200 条测试用例的评估集,人工评估可能需要一整天,而 LLM-as-Judge 只需几分钟。

当然,LLM-as-Judge 也有局限——它本身也会犯错。但在实践中,LLM 评分与人类专家评分的一致性通常在 85%~92% 之间,已经足够用于持续迭代的参考。


二、构建完整的 Agent 评估框架

2.1 评估数据集设计

评估数据集是整个评估体系的基石。一个好的评估集应该覆盖:

  • 正常路径:典型的、预期内的问题
  • 边界情况:模糊的、多义的问题
  • 异常路径:恶意输入、超出能力范围的请求
  • 复合任务:需要多步推理的复杂问题
/**
 * 评估数据集定义
 * 
 * 每条测试用例包含:
 * - input: 用户问题
 * - expectedTools: 预期应该调用的工具列表(验证工具调用正确性)
 * - referenceAnswer: 参考答案(用于 LLM-as-Judge 评分对照)
 * - category: 测试分类(便于按类别统计通过率)
 * - difficulty: 难度等级(便于分层分析)
 */
public record EvalTestCase(
    String id,
    String input,
    List<ExpectedToolCall> expectedTools,
    String referenceAnswer,
    String category,
    Difficulty difficulty
) {
    public enum Difficulty { EASY, MEDIUM, HARD }

    public record ExpectedToolCall(
        String toolName,
        Map<String, Object> expectedArgs  // null 表示不校验参数
    ) {}
}
/**
 * 评估数据集加载器
 * 
 * 数据来源:
 * 1. 历史对话日志中筛选的典型案例
 * 2. 领域专家编写的边界测试
 * 3. 线上故障复现的异常场景
 */
@Component
public class EvalDatasetLoader {

    /**
     * 从 JSON 文件加载评估数据集
     */
    public List<EvalTestCase> load(String resourcePath) throws IOException {
        String json = new String(
            getClass().getResourceAsStream(resourcePath).readAllBytes(),
            StandardCharsets.UTF_8
        );
        return JsonUtils.parseList(json, EvalTestCase.class);
    }

    /**
     * 能源管理场景的内置评估集(示例)
     */
    public List<EvalTestCase> builtInDataset() {
        return List.of(
            // ===== 正常路径 =====
            new EvalTestCase(
                "TC-001",
                "A栋办公楼今天用电量是多少?",
                List.of(new ExpectedToolCall(
                    "query_realtime_energy",
                    Map.of("areaName", "A栋办公楼")
                )),
                "A栋办公楼今日实时用电量为1523.5 kWh。",
                "数据查询",
                EvalTestCase.Difficulty.EASY
            ),

            // ===== 多步推理 =====
            new EvalTestCase(
                "TC-002",
                "分析一下C栋数据中心最近一周的能耗趋势,如果偏高就通知张工",
                List.of(
                    new ExpectedToolCall("query_energy_trend",
                        Map.of("areaName", "C栋数据中心", "days", 7)),
                    new ExpectedToolCall("send_alert", null)  // null = 不校验具体参数
                ),
                "C栋数据中心近7天平均能耗8734.6 kWh,超出历史均值,已通知张工进行排查。",
                "复合任务",
                EvalTestCase.Difficulty.HARD
            ),

            // ===== 边界情况:模糊意图 =====
            new EvalTestCase(
                "TC-003",
                "最近电费好像有点高",
                List.of(),  // 预期不调用工具,而是先追问
                "请问您想了解哪个区域的用电情况?我可以帮您查询实时数据或分析趋势。",
                "模糊意图",
                EvalTestCase.Difficulty.MEDIUM
            ),

            // ===== 异常路径:超出能力范围 =====
            new EvalTestCase(
                "TC-004",
                "帮我预订一张明天去北京的机票",
                List.of(),  // 不应调用任何能源工具
                "抱歉,我目前只负责能源管理相关的事务,无法帮您预订机票。",
                "越界请求",
                EvalTestCase.Difficulty.EASY
            ),

            // ===== RAG 知识检索 =====
            new EvalTestCase(
                "TC-005",
                "根据公司规定,能耗告警的触发条件是什么?",
                List.of(),  // 应走 RAG 而非工具调用
                "根据《能源管理手册》,当某区域单日能耗超过近30天均值的150%时触发黄色告警,超过200%时触发红色告警。",
                "知识问答",
                EvalTestCase.Difficulty.MEDIUM
            )
        );
    }
}

2.2 评估执行引擎

/**
 * Agent 评估执行引擎
 * 
 * 执行流程:
 * 1. 逐条加载测试用例
 * 2. 将被测 Agent 的对话过程完整录制(包括中间的工具调用)
 * 3. 收集四个维度的评估指标
 * 4. 输出结构化评估报告
 */
@Service
public class AgentEvalEngine {

    private final EnergyAgent agent;
    private final EvalJudge judge;
    private final AgentCallRecorder recorder;

    public AgentEvalEngine(EnergyAgent agent, EvalJudge judge,
                          AgentCallRecorder recorder) {
        this.agent = agent;
        this.judge = judge;
        this.recorder = recorder;
    }

    /**
     * 执行完整评估
     */
    public EvalReport runEvaluation(List<EvalTestCase> testCases) {
        List<EvalResult> results = new ArrayList<>();

        for (EvalTestCase tc : testCases) {
            log.info("执行测试用例: {} - {}", tc.id(), tc.input());

            // 1. 开启录制(拦截所有工具调用)
            recorder.startRecording();

            // 2. 调用被测 Agent
            String actualResponse = agent.chat(tc.input());

            // 3. 停止录制,获取工具调用链
            List<RecordedToolCall> toolCalls = recorder.stopRecording();

            // 4. 四维评分
            EvalResult result = evaluate(tc, actualResponse, toolCalls);
            results.add(result);

            log.info("用例 {} 评分: taskComplete={}, toolCorrect={}, " +
                     "answerQuality={}, tokens={}",
                tc.id(),
                result.taskCompleted(),
                result.toolCallScore(),
                result.answerQualityScore(),
                result.totalTokens());
        }

        return generateReport(results, testCases);
    }

    /**
     * 单条用例的四维评分
     */
    private EvalResult evaluate(EvalTestCase tc, String actualResponse,
                               List<RecordedToolCall> toolCalls) {

        // 维度1: 任务完成率(二值判定)
        boolean taskCompleted = judge.judgeTaskCompletion(
            tc.input(), tc.referenceAnswer(), actualResponse);

        // 维度2: 工具调用正确性(0.0 ~ 1.0)
        double toolCallScore = judge.judgeToolCalls(
            tc.expectedTools(), toolCalls);

        // 维度3: 回答质量(LLM-as-Judge,0.0 ~ 1.0)
        double answerQuality = judge.judgeAnswerQuality(
            tc.input(), tc.referenceAnswer(), actualResponse);

        // 维度4: 执行效率(Token 统计)
        int totalTokens = recorder.getTotalTokens();
        int toolCallCount = toolCalls.size();
        long latencyMs = recorder.getLatencyMs();

        return new EvalResult(
            tc.id(), taskCompleted, toolCallScore,
            answerQuality, totalTokens, toolCallCount, latencyMs
        );
    }
}

2.3 LLM-as-Judge 实现

这是评估框架最核心的部分。Judge Agent 是一个独立的、专门用于评分的 Agent:

/**
 * 评审 Agent(LLM-as-Judge)
 * 
 * 设计原则:
 * 1. Judge 和被测 Agent 必须隔离——不能共享记忆和上下文
 * 2. 评分标准必须明确写入 Prompt,避免"自由心证"
 * 3. 要求输出结构化 JSON,便于程序解析
 */
@Service
public class EvalJudge {

    private final ChatLanguageModel judgeModel;

    public EvalJudge() {
        // Judge 模型建议使用更强的模型(如 GPT-4o),
        // 且 temperature 设为 0 以确保评分稳定
        this.judgeModel = OpenAiChatModel.builder()
            .apiKey(System.getenv("LLM_API_KEY"))
            .modelName("gpt-4o")
            .temperature(0.0)
            .build();
    }

    /**
     * 维度1: 任务完成度判定
     * 
     * 评判标准:
     * - 被测 Agent 是否正确理解了用户意图
     * - 最终回答是否实质性地解决了用户的问题
     * - 与参考答案的核心信息是否一致
     */
    public boolean judgeTaskCompletion(String userQuery,
                                       String referenceAnswer,
                                       String actualAnswer) {
        String prompt = String.format("""
            你是一个严格的任务完成度评审员。
            
            请判断 Agent 的回答是否正确完成了用户的任务。
            
            ## 评分标准
            - true: Agent 的回答实质性地解决了用户问题,核心信息正确
            - false: Agent 未能理解意图、给出错误信息、或拒绝回答合理请求
            
            允许:措辞差异、信息量差异(只要核心信息覆盖即可)
            不允许:事实错误、关键数据缺失、答非所问
            
            ## 用户问题
            %s
            
            ## 参考答案(仅供参考,不是唯一标准)
            %s
            
            ## Agent 实际回答
            %s
            
            只返回 true 或 false,不要返回其他内容。
            """, userQuery, referenceAnswer, actualAnswer);

        String result = judgeModel.generate(
            UserMessage.from(prompt)).content().text().trim();

        return Boolean.parseBoolean(result);
    }

    /**
     * 维度2: 工具调用正确性评分
     * 
     * 评分逻辑(规则引擎,无需 LLM):
     * - 工具名称匹配率 × 0.4
     * - 参数正确率 × 0.3
     * - 调用顺序合理性 × 0.3
     */
    public double judgeToolCalls(List<ExpectedToolCall> expected,
                                List<RecordedToolCall> actual) {
        if (expected.isEmpty() && actual.isEmpty()) return 1.0;
        if (expected.isEmpty() || actual.isEmpty()) return 0.0;

        // 工具名称匹配率
        Set<String> expectedNames = expected.stream()
            .map(ExpectedToolCall::toolName)
            .collect(Collectors.toSet());
        Set<String> actualNames = actual.stream()
            .map(RecordedToolCall::toolName)
            .collect(Collectors.toSet());

        long matched = expectedNames.stream()
            .filter(actualNames::contains).count();
        double nameScore = (double) matched / Math.max(
            expectedNames.size(), actualNames.size());

        // 参数正确率(只校验期望参数非 null 的)
        long paramTotal = 0, paramCorrect = 0;
        for (ExpectedToolCall exp : expected) {
            if (exp.expectedArgs() == null) continue;
            RecordedToolCall act = findByName(actual, exp.toolName());
            if (act == null) continue;
            for (var entry : exp.expectedArgs().entrySet()) {
                paramTotal++;
                if (entry.getValue().equals(
                        act.arguments().get(entry.getKey()))) {
                    paramCorrect++;
                }
            }
        }
        double paramScore = paramTotal == 0 ? 1.0
            : (double) paramCorrect / paramTotal;

        // 调用顺序合理性(第一个期望工具是否在第一个实际工具之前或相等)
        double orderScore = 1.0;
        if (expected.size() >= 2 && actual.size() >= 2) {
            int firstExpIdx = indexOfFirst(actual, expected.get(0).toolName());
            int lastExpIdx = indexOfFirst(actual,
                expected.get(expected.size() - 1).toolName());
            if (firstExpIdx >= 0 && lastExpIdx >= 0
                    && firstExpIdx < lastExpIdx) {
                orderScore = 1.0;
            } else {
                orderScore = 0.5;
            }
        }

        return nameScore * 0.4 + paramScore * 0.3 + orderScore * 0.3;
    }

    /**
     * 维度3: 回答质量评分(LLM-as-Judge)
     * 
     * 评分维度:
     * - 准确性 (0~1):事实是否正确
     * - 完整性 (0~1):是否覆盖了用户关心的要点
     * - 幻觉度 (0~1):是否包含捏造的信息(1=无幻觉)
     * - 专业性 (0~1):措辞是否专业得体
     */
    public double judgeAnswerQuality(String userQuery,
                                     String referenceAnswer,
                                     String actualAnswer) {
        String prompt = String.format("""
            你是一个专业的回答质量评审员。请从以下四个维度对 Agent 的回答打分。
            每个维度 0~1 分,最终返回四个维分的加权平均。
            
            ## 评分维度与权重
            1. 准确性 (权重0.35): 事实和数据是否正确?有没有编造数据?
            2. 完整性 (权重0.25): 是否回答了用户关心的所有要点?
            3. 无幻觉 (权重0.25): 是否包含无法验证的或捏造的信息?
            4. 专业性 (权重0.15): 措辞是否专业、简洁、得体?
            
            ## 用户问题
            %s
            
            ## 参考答案
            %s
            
            ## Agent 实际回答
            %s
            
            严格按以下 JSON 格式返回,不要返回其他内容:
            {
              "accuracy": 0.0~1.0,
              "completeness": 0.0~1.0,
              "noHallucination": 0.0~1.0,
              "professionalism": 0.0~1.0,
              "weightedScore": 加权总分,
              "reason": "一句话说明扣分原因"
            }
            """, userQuery, referenceAnswer, actualAnswer);

        String result = judgeModel.generate(
            UserMessage.from(prompt)).content().text().trim();

        // 解析 JSON 获取加权分数
        JsonNode node = JsonUtils.parse(result);
        return node.get("weightedScore").asDouble();
    }
}

2.4 工具调用录制器

为了评估工具调用的正确性,我们需要在不侵入 Agent 代码的前提下"录制"所有的工具调用过程。这可以通过 AOP 拦截 实现:

/**
 * Agent 工具调用录制器
 * 
 * 实现原理:
 * 使用 Spring AOP 拦截所有 @Tool 标注的方法调用,
 * 记录调用时间、参数、返回值,存储到 ThreadLocal 中。
 * 
 * 优势:对业务代码零侵入,Agent 完全不知道自己在被"监控"。
 */
@Component
public class AgentCallRecorder {

    private final ThreadLocal<List<RecordedToolCall>> callLog =
        ThreadLocal.withInitial(ArrayList::new);
    private final ThreadLocal<Long> startTime = new ThreadLocal<>();
    private final ThreadLocal<Integer> totalTokens =
        ThreadLocal.withInitial(() -> 0);

    /**
     * 开始录制
     */
    public void startRecording() {
        callLog.get().clear();
        startTime.set(System.currentTimeMillis());
        totalTokens.set(0);
    }

    /**
     * 停止录制,返回工具调用链
     */
    public List<RecordedToolCall> stopRecording() {
        return List.copyOf(callLog.get());
    }

    public long getLatencyMs() {
        return System.currentTimeMillis() - startTime.get();
    }

    public int getTotalTokens() {
        return totalTokens.get();
    }

    /**
     * AOP 切面:拦截所有 @Tool 方法调用
     */
    @Around("@annotation(dev.langchain4j.agent.tool.Tool)")
    public Object recordToolCall(ProceedingJoinPoint pjp) throws Throwable {
        long callTime = System.currentTimeMillis();
        String toolName = pjp.getSignature().getName();
        Map<String, Object> arguments = extractArguments(pjp);

        Object result;
        try {
            result = pjp.proceed();
        } catch (Throwable t) {
            callLog.get().add(new RecordedToolCall(
                toolName, arguments, null, t.getMessage(),
                callTime, System.currentTimeMillis()
            ));
            throw t;
        }

        callLog.get().add(new RecordedToolCall(
            toolName, arguments, result, null,
            callTime, System.currentTimeMillis()
        ));

        return result;
    }

    private Map<String, Object> extractArguments(ProceedingJoinPoint pjp) {
        String[] paramNames = ((MethodSignature) pjp.getSignature())
            .getParameterNames();
        Object[] args = pjp.getArgs();
        Map<String, Object> map = new LinkedHashMap<>();
        for (int i = 0; i < paramNames.length; i++) {
            map.put(paramNames[i], args[i]);
        }
        return map;
    }
}

/**
 * 录制的单次工具调用
 */
public record RecordedToolCall(
    String toolName,
    Map<String, Object> arguments,
    Object result,
    String error,
    long startTime,
    long endTime
) {}

2.5 评估报告生成

/**
 * 评估报告
 */
public record EvalReport(
    int totalCases,
    double taskCompletionRate,       // 任务完成率
    double avgToolCallScore,         // 平均工具调用正确率
    double avgAnswerQuality,         // 平均回答质量
    double avgTokens,                // 平均 Token 消耗
    double avgLatencyMs,             // 平均延迟
    Map<String, CategoryScore> byCategory,  // 按类别统计
    List<EvalResult> failedCases     // 失败用例(便于定向优化)
) {
    public record CategoryScore(
        int count,
        double completionRate,
        double avgQuality
    ) {}
}

/**
 * 报告生成逻辑
 */
private EvalReport generateReport(List<EvalResult> results,
                                  List<EvalTestCase> cases) {
    int total = results.size();

    long completed = results.stream()
        .filter(EvalResult::taskCompleted).count();
    double completionRate = (double) completed / total;

    double avgTool = results.stream()
        .mapToDouble(EvalResult::toolCallScore).average().orElse(0);
    double avgQuality = results.stream()
        .mapToDouble(EvalResult::answerQualityScore).average().orElse(0);
    double avgTokens = results.stream()
        .mapToInt(EvalResult::totalTokens).average().orElse(0);
    double avgLatency = results.stream()
        .mapToLong(EvalResult::latencyMs).average().orElse(0);

    // 按类别分组统计
    Map<String, EvalReport.CategoryScore> byCategory = cases.stream()
        .collect(Collectors.groupingBy(EvalTestCase::category))
        .entrySet().stream()
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            e -> {
                List<EvalResult> catResults = e.getValue().stream()
                    .map(c -> findById(results, c.id()))
                    .toList();
                long catCompleted = catResults.stream()
                    .filter(EvalResult::taskCompleted).count();
                return new EvalReport.CategoryScore(
                    catResults.size(),
                    (double) catCompleted / catResults.size(),
                    catResults.stream()
                        .mapToDouble(EvalResult::answerQualityScore)
                        .average().orElse(0)
                );
            }
        ));

    // 失败用例
    List<EvalResult> failed = results.stream()
        .filter(r -> !r.taskCompleted()).toList();

    return new EvalReport(total, completionRate, avgTool, avgQuality,
        avgTokens, avgLatency, byCategory, failed);
}

2.6 评估报告示例

运行评估后,输出类似以下结构的报告:

╔══════════════════════════════════════════════════════════╗
║              Agent 评估报告  2026-08-27                  ║
╠══════════════════════════════════════════════════════════╣
║  总用例数:     50                                        ║
║  任务完成率:   88.0% (44/50)                             ║
║  工具调用正确率: 82.3%                                   ║
║  回答质量均分:  0.81                                     ║
║  平均 Token:   2,340                                    ║
║  平均延迟:     4.2s                                     ║
╠══════════════════════════════════════════════════════════╣
║  按类别统计:                                             ║
║  ┌──────────────┬──────┬──────────┬──────────┐          ║
║  │ 类别         │ 数量 │ 完成率    │ 质量均分 │          ║
║  ├──────────────┼──────┼──────────┼──────────┤          ║
║  │ 数据查询     │ 15   │ 100.0%   │ 0.91     │          ║
║  │ 复合任务     │ 12   │ 75.0%    │ 0.73     │          ║
║  │ 模糊意图     │ 10   │ 80.0%    │ 0.78     │          ║
║  │ 知识问答     │ 8    │ 87.5%    │ 0.85     │          ║
║  │ 越界请求     │ 5    │ 100.0%   │ 0.92     │          ║
║  └──────────────┴──────┴──────────┴──────────┘          ║
╠══════════════════════════════════════════════════════════╣
║  失败用例 (Top 3):                                       ║
║  1. TC-023: "对比A栋和B栋上个月的能耗差异并..."           ║
║     → 工具调用遗漏:未调用 query_history                 ║
║  2. TC-041: "如果能耗正常就不用通知了"                    ║
║     → 条件推理错误:即使正常也发了通知                    ║
║  3. TC-037: "帮我看看B栋3楼的空调是不是太费电了"          ║
║     → 粒度不足:只查了B栋整体,未细化到3楼               ║
╚══════════════════════════════════════════════════════════╝

这份报告的价值在于:它直接告诉你 Agent 的薄弱环节在哪里,下一步该优化什么。 比如上例中,"复合任务"完成率只有 75%,说明 Orchestrator 的路由逻辑需要加强;TC-041 说明 Agent 的条件推理能力不足,需要在 System Prompt 中增加对条件语句的处理规则。


三、A2A 协议:Agent 间通信的"HTTP"

3.1 A2A 解决了什么问题?

MCP 协议解决了 Agent 与工具之间的集成问题,但还有一个更大的问题没有解决:不同系统、不同组织构建的 Agent 之间如何互相通信、互相协作?

想象这样的场景:

  • 你公司的 能源管理 Agent 需要向物业公司的 设备维修 Agent 发起维修工单
  • 供应链部门的 库存 Agent 需要向采购部门的 采购 Agent 提出备品需求
  • 客户的 私人助理 Agent 需要与你公司的 客服 Agent 协商预约时间

这些 Agent 可能基于不同的框架构建(LangChain4j、Spring AI、AutoGen……),部署在不同的服务器上,由不同的团队维护。如果没有统一的通信协议,每对 Agent 之间都需要单独开发对接方案——这是 N² 级别的复杂度。

A2A(Agent-to-Agent Protocol)就是为此而生的。它是 Google 于 2025 年提出的开放协议,到 2026 年已获得 50+ 家企业和组织的支持。

3.2 A2A vs MCP:互补而非竞争

很多人会问:“已经有了 MCP,为什么还需要 A2A?”

答案是:它们解决的问题不在同一层。

┌────────────────────────────────────────────────────┐
│                                                    │
│   Agent A ──── A2A 协议 ────→ Agent B              │
│     │                            │                 │
│     │                            │                 │
│   MCP 协议                    MCP 协议             │
│     │                            │                 │
│   工具集 A                    工具集 B             │
│                                                    │
└────────────────────────────────────────────────────┘

MCP = Agent 与工具之间的"USB 接口"
A2A = Agent 与 Agent 之间的"HTTP 协议"
维度MCPA2A
连接对象Agent ↔ 工具/数据源Agent ↔ Agent
关系主从(Agent 调用工具)对等(Agent 互相请求)
通信模式请求-响应任务(可异步、可流式)
类比USB 接口HTTP 协议

3.3 A2A 的核心概念

A2A 协议定义了四个核心概念:

Agent Card(名片)

每个 Agent 发布一个 JSON 文件描述自己的身份信息,类似于 OpenAPI 的 swagger.json。其他 Agent 通过读取 Agent Card 来了解"对方能做什么"。

Task(任务)

A2A 通信的基本单元。一个 Agent 向另一个 Agent 发起任务,任务有明确的生命周期状态:

submitted → working → input-required → completed
                           ↑                  │
                           └──── 需要更多 ────┘
                                 信息
                  ↘
                   failed / canceled

Message(消息)

任务中的通信载体。一条消息包含多个 Part(内容片段),每个 Part 可以是文本、文件、或结构化数据。

Artifact(产物)

任务执行完成后产出的结果,如生成的报告文件、分析数据等。

3.4 实现一个 A2A Agent Server

下面我们把能源管理 Agent 包装成一个标准的 A2A Server,让外部 Agent 可以通过 A2A 协议调用它。

依赖配置
<dependencies>
    <!-- A2A Java SDK -->
    <dependency>
        <groupId>io.github.a2ap</groupId>
        <artifactId>a2a-java-sdk</artifactId>
        <version>0.5.0</version>
    </dependency>
</dependencies>
发布 Agent Card
/**
 * Agent Card 端点
 * 
 * 作用:向外界声明"我是谁、我能做什么"
 * 路径:/.well-known/agent.json(A2A 协议约定的标准路径)
 * 
 * 其他 Agent 在调用我们之前,会先请求这个地址获取 Agent Card,
 * 从而了解我们的能力和通信方式。
 */
@RestController
public class AgentCardController {

    @GetMapping("/.well-known/agent.json")
    public AgentCard getAgentCard() {
        return AgentCard.builder()
            .name("Energy Management Agent")
            .description("智慧能源管理智能体,提供能耗查询、趋势分析、预警通知等能力")
            .url("https://energy.example.com/a2a")  // A2A 通信端点
            .version("1.0.0")
            .protocolVersion("0.2.1")

            // 声明支持的能力
            .capabilities(AgentCapabilities.builder()
                .streaming(true)          // 支持流式响应
                .pushNotifications(true)  // 支持异步推送通知
                .build())

            // 声明支持的内容类型
            .defaultInputModes(List.of("text/plain", "application/json"))
            .defaultOutputModes(List.of("text/plain", "application/json"))

            // 技能列表(其他 Agent 据此决定是否调用我们)
            .skills(List.of(
                AgentSkill.builder()
                    .id("query-energy")
                    .name("能耗数据查询")
                    .description("查询指定区域的实时能耗、历史趋势、对比分析")
                    .tags(List.of("energy", "data", "analytics"))
                    .build(),
                AgentSkill.builder()
                    .id("energy-alert")
                    .name("能耗预警通知")
                    .description("根据能耗异常情况发送预警通知给相关负责人")
                    .tags(List.of("energy", "alert", "notification"))
                    .build(),
                AgentSkill.builder()
                    .id("energy-report")
                    .name("能耗报告生成")
                    .description("基于能耗数据生成专业的分析报告")
                    .tags(List.of("energy", "report", "document"))
                    .build()
            ))
            .build();
    }
}
处理 A2A 任务请求
/**
 * A2A 任务处理端点
 * 
 * 处理外部 Agent 发来的任务请求
 */
@RestController
@RequestMapping("/a2a")
public class A2ATaskHandler {

    private final EnergyAgent energyAgent;
    private final TaskRepository taskRepository;

    public A2ATaskHandler(EnergyAgent energyAgent,
                         TaskRepository taskRepository) {
        this.energyAgent = energyAgent;
        this.taskRepository = taskRepository;
    }

    /**
     * 接收并处理 A2A 任务
     * 
     * 完整流程:
     * 1. 解析外部 Agent 的任务请求
     * 2. 将任务转化为内部 Agent 调用
     * 3. 返回任务状态和结果
     */
    @PostMapping("/tasks/send")
    public ResponseEntity<TaskResponse> handleTask(
            @RequestBody TaskRequest request) {

        // 1. 创建任务记录
        Task task = Task.builder()
            .id(request.taskId())
            .status(TaskStatus.WORKING)
            .build();
        taskRepository.save(task);

        // 2. 提取用户消息(从 A2A Message 的 Part 中提取)
        String userMessage = extractMessageFromParts(request.message());

        // 3. 调用内部 Agent
        String response = energyAgent.chat(userMessage);

        // 4. 构建 A2A 响应
        TaskResponse response = TaskResponse.builder()
            .taskId(task.getId())
            .status(TaskStatus.COMPLETED)

            // 将回答封装为 A2A Artifact
            .artifacts(List.of(
                Artifact.builder()
                    .name("analysis-result")
                    .parts(List.of(
                        Part.textPart(response)
                    ))
                    .build()
            ))
            .build();

        taskRepository.updateStatus(task.getId(), TaskStatus.COMPLETED);

        return ResponseEntity.ok(response);
    }

    /**
     * 任务状态查询(外部 Agent 可轮询此接口获取进度)
     */
    @GetMapping("/tasks/{taskId}")
    public ResponseEntity<TaskStatus> getTaskStatus(
            @PathVariable String taskId) {
        Task task = taskRepository.findById(taskId)
            .orElseThrow(() -> new TaskNotFoundException(taskId));
        return ResponseEntity.ok(task.getStatus());
    }

    /**
     * 流式任务处理(SSE)
     * 
     * 适用于耗时较长的任务,外部 Agent 可以实时获取中间进展
     */
    @PostMapping(value = "/tasks/sendSubscribe",
                 produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter handleTaskStream(@RequestBody TaskRequest request) {
        SseEmitter emitter = new SseEmitter();

        CompletableFuture.runAsync(() -> {
            try {
                // 发送"开始工作"事件
                emitter.send(SseEmitter.event()
                    .name("task-status")
                    .data(new TaskStatusEvent(request.taskId(), "working")));

                String userMessage = extractMessageFromParts(request.message());

                // 调用流式 Agent
                TokenStream stream = streamingAgent.chat(userMessage);

                stream.onNext(token -> {
                    try {
                        emitter.send(SseEmitter.event()
                            .name("task-artifact")
                            .data(new ArtifactChunk(token)));
                    } catch (IOException e) {
                        emitter.completeWithError(e);
                    }
                });

                stream.onComplete(response -> {
                    try {
                        emitter.send(SseEmitter.event()
                            .name("task-status")
                            .data(new TaskStatusEvent(
                                request.taskId(), "completed")));
                        emitter.complete();
                    } catch (IOException e) {
                        emitter.completeWithError(e);
                    }
                });

            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });

        return emitter;
    }

    private String extractMessageFromParts(List<Part> parts) {
        return parts.stream()
            .filter(Part::isText)
            .map(Part::getText)
            .collect(Collectors.joining("\n"));
    }
}

3.5 作为 A2A Client 调用外部 Agent

现在让我们反过来——我们的 Agent 作为客户端,去调用物业公司的"设备维修 Agent":

/**
 * A2A Client:调用外部 Agent 的服务
 */
@Service
public class A2AClientService {

    private final A2AClient a2aClient;

    public A2AClientService() {
        this.a2aClient = A2AClient.builder()
            .build();
    }

    /**
     * 调用外部 Agent 之前,先读取对方的 Agent Card
     * 了解它有哪些能力
     */
    public AgentCard discoverAgent(String agentUrl) {
        return a2aClient.getAgentCard(agentUrl);
    }

    /**
     * 向物业维修 Agent 提交维修工单
     * 
     * @param deviceName 设备名称
     * @param issue      问题描述
     * @param urgency    紧急程度
     * @return 工单编号
     */
    public String submitRepairTask(String deviceName,
                                   String issue,
                                   String urgency) {
        // 1. 构建 A2A 任务请求
        TaskRequest request = TaskRequest.builder()
            .taskId(UUID.randomUUID().toString())
            .message(Message.builder()
                .role("user")
                .parts(List.of(
                    Part.textPart(String.format("""
                        请为以下设备创建维修工单:
                        
                        设备名称:%s
                        问题描述:%s
                        紧急程度:%s
                        提交方:能源管理系统
                        """, deviceName, issue, urgency))
                ))
                .build())
            .build();

        // 2. 发送到物业维修 Agent 的 A2A 端点
        TaskResponse response = a2aClient.sendTask(
            "https://property-repair.example.com/a2a",
            request
        );

        // 3. 提取结果
        if (response.status() == TaskStatus.COMPLETED) {
            return response.artifacts().get(0).parts().get(0).getText();
        } else {
            throw new RuntimeException(
                "维修工单创建失败: " + response.status());
        }
    }
}

3.6 将 A2A Client 集成到 Agent 的工具集中

最强大的做法是:把"调用外部 Agent"也封装成一个工具,让 Agent 自主决定什么时候需要请求外援。

@Component
public class ExternalAgentTools {

    private final A2AClientService a2aClient;

    public ExternalAgentTools(A2AClientService a2aClient) {
        this.a2aClient = a2aClient;
    }

    @Tool("向物业维修系统提交设备维修工单。" +
          "当发现设备能耗异常、可能存在硬件故障时使用此工具。" +
          "返回维修工单编号。")
    public String submitRepairOrder(String deviceName,
                                    String issueDescription,
                                    String urgency) {
        return a2aClient.submitRepairTask(
            deviceName, issueDescription, urgency);
    }

    @Tool("查询物业维修系统的工单处理进度。" +
          "当用户询问'维修进展如何'、'工单处理到哪了'时使用此工具。")
    public String queryRepairProgress(String orderId) {
        return a2aClient.queryTaskStatus(
            "https://property-repair.example.com/a2a", orderId);
    }
}

这样,你的 Agent 不仅能管理能耗数据,还能 自主地 发现设备故障 → 调用外部维修 Agent → 跟踪维修进度——形成了一个完整的业务闭环。


四、评估 + A2A 的完整集成测试

4.1 CI/CD 集成:每次代码变更自动评估

/**
 * Agent 评估的集成测试
 * 
 * 在 CI/CD 流水线中运行,确保每次代码变更不会导致 Agent 能力退化
 */
@SpringBootTest
public class AgentEvalIntegrationTest {

    @Autowired
    private AgentEvalEngine evalEngine;

    @Autowired
    private EvalDatasetLoader datasetLoader;

    /**
     * 核心回归测试:确保关键能力不退化
     * 
     * 阈值设定依据:
     * - 任务完成率 >= 85%(允许少量边界情况失败)
     * - 工具调用正确率 >= 80%
     * - 回答质量均分 >= 0.75
     */
    @Test
    public void regressionTest() {
        List<EvalTestCase> dataset = datasetLoader.builtInDataset();
        EvalReport report = evalEngine.runEvaluation(dataset);

        // 输出报告(CI 日志可查)
        System.out.println(formatReport(report));

        // 关键指标断言
        assertThat(report.taskCompletionRate())
            .as("任务完成率不应低于 85%%")
            .isGreaterThanOrEqualTo(0.85);

        assertThat(report.avgToolCallScore())
            .as("工具调用正确率不应低于 80%%")
            .isGreaterThanOrEqualTo(0.80);

        assertThat(report.avgAnswerQuality())
            .as("回答质量均分不应低于 0.75")
            .isGreaterThanOrEqualTo(0.75);

        // 特定类别的断言
        assertThat(report.byCategory().get("数据查询").completionRate())
            .as("数据查询类任务应 100%% 完成")
            .isEqualTo(1.0);
    }

    /**
     * 性能回归测试:确保响应时间不退化
     */
    @Test
    public void performanceTest() {
        List<EvalTestCase> dataset = datasetLoader.builtInDataset();
        EvalReport report = evalEngine.runEvaluation(dataset);

        assertThat(report.avgLatencyMs())
            .as("平均响应时间不应超过 10 秒")
            .isLessThanOrEqualTo(10000);

        assertThat(report.avgTokens())
            .as("平均 Token 消耗不应超过 5000")
            .isLessThanOrEqualTo(5000);
    }
}

4.2 评估驱动的持续优化闭环

评估不是一次性的动作,而是一个持续迭代的闭环:

代码变更 → CI 自动评估 → 评估报告 → 发现退化?
                                       │
                         ┌───── Yes ───┤
                         │             │
                         ▼             No → 合并代码
                   分析失败用例
                         │
                         ▼
              定位根因(Prompt? 工具? RAG?)
                         │
                         ▼
                    修复 & 重新评估
                         │
                         ▼
                  通过率达标?──→ 合并代码

五、三篇文章的完整知识图谱

让我们回顾一下整个系列的脉络:

┌─────────────────────────────────────────────────────────────┐
│                  AI Agent 技术全景图                         │
│                                                             │
│  第一篇:单体 Agent                                          │
│  ┌───────────────────────────────────────────────────┐      │
│  │ Tool Calling + RAG + Memory                       │      │
│  │ → 掌握 Agent 的基本构建能力                        │      │
│  └───────────────────────────┬───────────────────────┘      │
│                              │                              │
│  第二篇:Multi-Agent + MCP   │                              │
│  ┌───────────────────────────▼───────────────────────┐      │
│  │ 多 Agent 协作 + 工具标准化                         │      │
│  │ → 掌握企业级的架构设计和协议集成                    │      │
│  └───────────────────────────┬───────────────────────┘      │
│                              │                              │
│  第三篇:评估 + A2A(本篇)   │                              │
│  ┌───────────────────────────▼───────────────────────┐      │
│  │ 自动评估体系 + Agent 间通信                        │      │
│  │ → 掌握从"能用"到"可靠"的工程化能力                 │      │
│  └───────────────────────────────────────────────────┘      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

六、总结

本文覆盖了两个关键主题:

Agent 自动评估体系:

  • 四维评估模型(任务完成率、工具正确性、回答质量、执行效率)
  • LLM-as-Judge 方法论的完整实现
  • AOP 工具调用录制器,零侵入
  • CI/CD 集成,评估驱动持续优化

A2A 协议实战:

  • Agent Card 发布(让别人找到你)
  • 任务处理(同步 + 流式)
  • 作为 Client 调用外部 Agent
  • 将 A2A 集成到工具集,形成跨组织协作闭环

A2A + MCP + Multi-Agent + 评估体系——这四者的组合,构成了 2026 年企业级 AI Agent 系统的完整技术版图。


一文读懂A2A(Agent-to-Agent)开放协议:AI领域的TCP/IP协议 A2A(Agent-to-Agent Protocol)是由谷歌于2025年推出的开放协议标准,旨在实现不同智能体之间的直接互通与协作。它通过标准化接口支持智能体间的动态服务发现、任务分配、数据交换和实时协作,打破“智能体孤岛”的局限。A2A的核心特性包括动态能力发现、任务生命周期管理、多模态协作和安全通信。它解决了传统AI系统中的生态碎片化、复杂任务瓶颈和实时协作缺失等问题,提升了开发效率和协作成本。A2A采用分布式三层架构,通过HTTP/SSE/JSON-RPC等协议实现智能体间的通信。应用场景涵盖企业 阅读详情

相关推荐

从零开始构建AI Agent评估体系:12种LangSmith评估方法详解

通过探索使用 LangSmith 进行 AI Agent 评估的十二种不同技术,我们构建了一个全面的评估框架。每种技术都解决了 AI 系统评估的特定方面,从基本的输出正确性到复杂的行为分析。技术分类与应用指南基于标准答案的评估方法包括精确匹配(适用于确定性答案,如事实、日期或计算)、非结构化问答(适用于开放式问题,其中语义正确性比字面匹配更重要)、结构化数据比较(适用于 JSON 提取和数据转换任务)、动态标准答案(适用于基于实时变化数据的系统)。

张伟的专栏 1490

构建AI智能体:四十七、Agent2Agent多智能体系统:基础通信与任务协作实现

摘要:Agent2Agent(A2A)是一个促进多智能体间通信与协作的框架,通过标准化协议实现复杂问题求解。智能体具备自主性、社交能力等特征,分为反应型、慎思型等类型。框架提供四种协作模式和多种冲突解决机制,采用消息传递方式进行通信,包含传输层、任务分配器等组件。演示案例展示了任务管理器与工作者智能体之间的任务分配与执行流程,包括问候交互、任务创建、结果反馈等环节。该框架适用于分布式系统管理、多模态AI协作等场景,为构建智能自治系统提供基础支持。示例代码实现了智能体注册、消息传递和任务处理的核心功能。

minhuan的专栏 1865

企业级 AI Agent 系统整合架构:MCP 与 A2A 的设计与落地案例

如果将 MCP 视为 AI 智能体的“工具箱”,那么 Agent2Agent (A2A) 协议就是促进 AI 智能体之间“相互协作”的沟通语言。这两种协议的结合正在重新塑造 AI 智能体的合作方式,从独立作业转变为团队合作。

dmx123789的博客 975

AI Agent,让企业从自动化走向自进化

要理解AI Agent的价值,先得弄清楚它到底是什么。AI Agent(人工智能体)是指一种能感知环境、自主规划行动并执行任务以达成特定目标的软件实体。换句话说,它既有“大脑”,也有“手脚”;既能思考问题,也能执行任务。2025年,将被写入AI产业史的关键节点。AI不再停留在实验室或PPT上,而是真正走进企业,成为推动组织进化的新引擎。未来的竞争,不是算法之争,也不是算力之争,而是Agent生态的竞争。谁能让AI真正参与业务、融入决策、释放执行力,谁就能在新一轮智能化浪潮中掌握主动权。

python123456_的博客 1410

AI Agent评测实战:从INTERN X SECRET AGENT基准到自动化评估体系

在人工智能领域,智能体(Agent)已成为连接大语言模型与现实应用的关键技术。其核心原理在于通过任务规划、工具调用和环境交互,使AI系统能够自主完成复杂工作流。这一技术价值在于将静态的知识模型转化为动态的问题解决系统,广泛应用于自动化办公、智能客服、代码生成等场景。面对市面上众多的AI模型和Agent框架,开发者常面临选型难题,缺乏客观评估标准。本文以INTERN X SECRET AGENT评测基准为例,深入探讨如何构建多维度、可实操的评估体系,涵盖工具调用准确率、任务完成率等关键指标,帮助开发者建立科学

weixin_34006468的博客 753

企业AI Agent的多维度性能评估体系设计

本文旨在探讨企业AI Agent的多维度性能评估体系设计。随着人工智能技术的不断进步,AI Agent在企业中的应用越来越广泛。然而,如何有效评估AI Agent的性能,成为了一个亟待解决的问题。本文将从背景介绍、核心概念与联系、性能评估方法、数学模型和公式、系统分析与架构设计、项目实战等方面,系统性地阐述企业AI Agent的多维度性能评估体系设计。在企业的日常运营中,AI Agent的应用场景多种多样。例如,在客服系统中,AI Agent需要快速响应客户的问题,提供准确的解决方案;

AI天才研究院 953

2026 AI Agent 学习路线图:从小白到实战,系统掌握智能体开发

2026 最全 AI Agent 学习路线图:从 ReAct 原理到手写 Agent,四阶段(入门→进阶→实战→专家)系统学习路径,涵盖 LangGraph/CrewAI/AutoGen 框架对比、MCP 工具开发、Multi-Agent 协作,附完整可运行代码和 7 个避坑指南。

m0_73614031的博客 2万+

4.1 Agent 也需要体检!如何为你的 AI 智能体建立科学的评估体系

摘要: 本文探讨如何为AI智能体建立科学的评估体系,强调客观度量的重要性。评估体系涵盖四大支柱:质量(准确性、相关性等)、成本(Token消耗、API费用)、延迟(响应速度)和行为(工具使用、决策路径)。评估方法包括人工评估(黄金标准但昂贵)、基于指标的评估(客观但适用场景有限)和基于模型的评估(LLM作为裁判,兼具规模与理解能力)。构建高质量评估数据集是关键,需覆盖典型和边缘案例。科学的评估体系能指导优化,确保AI应用的高效与可靠。

yonggeit的博客 2941

猫头虎AI赠书第13期赠书活动:《深入浅出AI智能体 基于DeepSeek的AI Agent开发实战 智能体开发AI编程agent设计模式 》

猫头虎AI赠书第13期赠书活动:《深入浅出AI智能体 基于DeepSeek的AI Agent开发实战 智能体开发AI编程agent设计模式 》《深入浅出AI智能体:基于DeepSeek的AI Agent开发实战》 🔥 关键词:DeepSeek、AI Agent、智能体开发、Agent设计模式、AI编程、RAG、LangChain、LangGraph、MCP、A2A

猫头虎技术团队:授渔优于赠鱼,兴趣引领智慧,探索之乐尤显珍贵。商务合作+:Libin9iOak ,万粉变现+:优快云WF,猫头虎承诺每年免费为100名C站创作者做账号流量诊断服务!全网搜:猫头虎技术团队,点击文章底部名片或直接私信我一切皆可谈,快找虎哥! 8431

PX4|Gazebo模型加载失败排查指南:从环境变量到资源路径的全面解析

本文针对PX4与Gazebo联合仿真中常见的'Unable to get model name'错误,提供了从环境变量配置、资源路径排查到网络访问问题的全面解决方案。详细解析了GZ_SIM_RESOURCE_PATH等关键变量的作用与设置方法,并给出了离线模型库部署等一劳永逸的修复指南,帮助开发者彻底解决无人机模型加载失败问题。

weixin_29243063的博客 1228

若依开源框架(分离版)在人大金仓数据库下使用

对于甲方业务特殊要求,使用国产化数据库人大金仓,作为项目主要存储。这里以若依开源框架整合人大金仓为例,演示如何在真实项目中引入人大金仓。

🐱喵测实验室 5942

大模型应用中Agent2Agent(A2A)的应用场景,以及A2A与MCP的区别和适用场景

在人工智能技术飞速发展的当下,单一AI模型的能力已难以满足复杂多变的实际需求。越来越多的场景需要多个AI智能体(Agent)协同工作,彼此分工、互补、协作完成任务。无论是企业自动化、智能办公,还是智能家居、自动驾驶,智能体之间的高效通信与协作已成为AI系统演进的关键。然而,智能体间的通信长期缺乏统一标准,导致“信息孤岛”现象严重,系统集成复杂、扩展性差。

微学AI的博客 3224

保姆级教程:用VESTA软件5分钟搞定纳米颗粒Wulff Construction建模(以Au金为例)

本文提供了一份详细的VESTA软件教程,指导用户如何在5分钟内完成纳米颗粒Wulff Construction建模,特别以金(Au)为例。从环境搭建、基础晶体结构创建到Wulff Construction设置和可视化优化,涵盖了全流程操作步骤和常见问题解决方案,适合科研新手快速上手。

weixin_29311017的博客 436

Agent-to-Agent (A2A) 协议全面解析:定义、原理、应用与未来

Agent-to-Agent(A2A)协议是由Google在2025年4月正式推出的开放标准通信协议,旨在解决不同AI智能体之间的互操作性问题。该协议为异构AI系统提供了一套统一的交互规范,使来自不同平台、不同供应商的智能体能够像人类团队一样进行有效协作。A2A协议的诞生标志着AI技术发展进入了一个新阶段——从单一智能体的能力提升转向多智能体系统的协同增效。在A2A协议出现之前,AI领域面临着严重的"巴别塔困境":每个智能体都有自己独特的通信方式和数据格式,导致跨系统协作极为困难。

分享python,大模型,人工智能,机器学习相关的内容 4242

Langfuse落地教程:从Docker部署到项目接入,掌控LLM调用链路

大模型应用开发中,调用链路的透明度直接决定调试效率与成本控制。可观测性技术通过记录每次请求的输入、输出、模型参数与Token消耗,帮助开发者快速定位问题。Langfuse作为开源LLM可观测性平台,将Trace、Prompt版本管理、评分等能力集成于一体,支持Docker Compose自托管部署,并提供Python/JS SDK与REST API。借助部署后的控制台,团队能够直观追踪RAG检索、Agent工具调用等复杂流程中的每一步耗时与资源占用,实现从黑盒调用到全链路可视化的转变。无论是本地调试、线上排

weixin_29698641的博客 308

cesium自定义指南针

项目需要一个指南针,用鼠标按住旋转指针,会让3d地图旋转,点击中心点重置方位。当然可以使用插件cesium-navigation-es6,但是样式不好修改,所以我自定义了一个指南针。

weixin_47017648的博客 750

如何科学评估一个智能体(Agent)的效果?——从指标设计、实战案例到自动化评估体系构建

Benchmark特点任务类型GitHubAgentBench多维度(知识、工具、规划)8 类任务linkWebArena基于真实网站操作Web 导航、表单填写linkGAIA强调推理与多步验证科学、常识问题linkToolBench专注工具调用能力API 使用、组合link📌建议:不要盲目追求 SOTA 分数,优先选择与你业务场景匹配的 benchmark。# 1. 任务完成度(基于规则+LLM)# 2. 准确性(使用 LLM Judge)# 3. 效率。

吾为热爱计科,致力于知识分享的践行者,此博客是我在这条道路上留下的足迹。 888

【IC前端虚拟项目】spyglass lint环境组织与lint清理

和上个虚拟项目的lint清理环节一样,关于spyglass的lint清理功能与流程还是大家通过各种资料去学习下就好啦。和之前不同的事,这次的虚拟项目里我把流程封装为Makefile,更加的贴近了实际项目交付流程。而后就可以根据提示进行lint的清理工作了。

moon9999的博客 1886

AI架构师成长必学:A2A+MCP构建智能体协作生态,值得反复研读与收藏

AI架构师成长必学:A2A+MCP构建智能体协作生态,值得反复研读与收藏

m0_48891301的博客 1434

反应堆设计:基于MATLAB的反应堆仿真和分析,包括反应堆稳态分析、反应堆动态分析和反应堆安全分析 介绍

反应堆设计是利用计算机技术对核反应堆进行设计和模拟,以获得安全、高效、经济的核能发电系统。它是核能领域的重要组成部分,在电力生产、核医学、科学研究等领域有着广泛的应用。

走向CTO的路上... 1112

使用 Fargate 在 AWS ECS 上运行 Spring Boot 应用程序

本文介绍了使用AWS Fargate支持的ECS部署SpringBoot应用的完整流程。主要内容包括:1)将SpringBoot应用打包为Docker镜像并推送至ECR;2)创建任务定义配置CPU、内存和网络等参数;3)设置ECS服务管理任务运行;4)配置负载均衡器分配流量;5)设计VPC网络和安全组规则确保安全访问;6)使用SSM参数存储管理敏感信息。整个过程实现了无服务器化部署,既保持了应用控制权,又免除了基础设施管理负担,是扩展Web服务的可靠方案。

介绍AWS Azure GCP devops Terraform 等技术 511

AI智能体三域评估与安全能力向量:构建可靠Agent的培养体系

在AI智能体(AI Agent)的工程化实践中,如何确保其行为的可靠性、安全性和稳定性成为关键挑战。传统方法往往侧重于功能实现,而缺乏系统化的评估体系。本文从智能体的核心概念切入,探讨了通过能力域、稳定域和安全域的三维评估框架,构建量化评估体系的技术原理。该框架不仅关注任务完成度,更强调异常处理、一致性及安全合规性,其技术价值在于为智能体提供了贯穿全生命周期的“培养”机制。通过引入安全能力向量这一量化工具,开发者可以精准定位智能体短板,实现基于数据的迭代优化。这一体系适用于自动化数据分析、智能客服、流程自动

weixin_30099989的博客 284

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ADK Agent2Agent协议:如何让AI智能体像团队一样高效协作?

你是否遇到过这样的困境?构建的AI智能体功能单一,无法处理复杂任务;多个智能体之间各自为战,缺乏有效沟通;想要集成第三方服务却面临复杂的API对接问题。这正是传统单一智能体架构的痛点所在。Agent Development Kit (ADK) 的 Agent2Agent (A2A) 协议正是为解决这些问题而生,它让AI智能体能够像真正的团队一样协作,构建强大的分布式智能体系统。 ## 单一智能体

gitblog_00444的博客 779

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

LLM 应用评估体系详解:从多轮对话到 RAG 与 AI Agent 的落地评估

大语言模型应用评估方法指南 本文系统梳理了大语言模型(LLM)应用的评估体系。传统NLP任务评估依赖准确率、BLEU等指标,但现代LLM应用需要更全面的评估方案。文章重点分析了三类场景的评估指标: 多轮对话:需跟踪相关性、完整性、知识留存、可靠性等指标 RAG应用:评估检索质量、答案准确性和上下文相关性 智能体系统:关注任务完成度、决策逻辑等维度 评估方式呈现新趋势: 从单一模型测试转向系统级评估 LLM-as-a-judge成为主流评分方法 涌现DeepEval等专业评估框架 企业应结合具体场景选择合适的

2401_85725028的博客 1164

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

谷歌正式定义生产级AI Agent:5级分类、5步循环、A2A交互与Agent Ops运维

Google这两天发布了最新的Agent白皮书。早在今年2月份,Google发布了第一版的Agent白皮书。这份新白皮书和2月份发布的相比,不同之处在于,它被定位为一份正式指南 ,其核心目标是帮助开发人员、架构师和产品负责人从概念验证 (proofs-of-concept)阶段过渡到构建生产级的Agent系统。相较于之前更侧重于定义概念的白皮书,这份新指南的重点是解决构建生产级系统时遇到的重大挑战,特别是围绕安全性、质量和可靠性的挑战。今天先来大致了解一下这份新的Agent白皮书里有哪些内容。

2401_85375298的博客 857

『Agent』一篇文章入门Agent基础知识、MCP协议和A2A协议

背景:假设每个AI智能体是一个小国家,如今,各国大使馆虽然集中设在同一栋大楼内,却各自为政,在沟通、经商乃至情报交换方面时常面临障碍。模型通过Prompt Engineering提供的工具结构化描述和few-shot的example来确定使用的工具。A2A协议建立了“客户端”智能体和“远程”智能体之间的通信,大模型的下半场,Agent的大爆发类似寒武纪生命大爆发。Agent的决策流程:Perception(感知)记忆、经验、世界知识、一些对过往的反思和总结。,以尝试提供正确的信息或采取正确的行动。

julac的博客 1444
上一篇: 二:Multi-Agent 协作架构与 MCP 协议实战:Java 企业级 AI 智能体进阶指南
下一篇: 四:Agent 长期记忆与用户画像——让智能体真正“认识“你的用户
yychen_java
博客等级 码龄8年 1451粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值