做 AI Agent:光会写还不够,还得知道它写得“好不好”
这篇就用大白话讲讲:怎么把 Microsoft Foundry 上现成的一堆评估器,拿来给你自己的 Harness 框架用。
为什么需要评估器?
先说个大白话的问题:你写了个 AI 天气助手,问它"东京天气怎么样",它回了一段话。问题来了:它回得到底好不好?
它是不是真的去调了查天气的工具,还是自己瞎编的?它说话有没有逻辑,前言不搭后语没有?它给的答案跟人家问的是不是一回事?
你总不能每次都自己一句一句看吧?这就是"评估器"(Evaluator)要干的活——让机器帮你打分,告诉你这次回答合不合格。
自己写评估器 vs 使用现成方案
那评估器自己写?太累了,很多人一上来就想:我自己写几个评估逻辑不就行了?刚开始确实能写。比如"检查回答里有没有提到城市名"、"检查长度是不是太长",这种简单的规则自己撸两行代码就搞定了。但是!一旦你想评估更"虚"的东西,麻烦就来了:
- "这回答靠不靠谱"——这得有个聪明的模型来当裁判
- "它工具用得对不对"——这背后有一整套判断逻辑
- "逻辑连不连贯"——这更是没法用 if-else 写出来
这些"软指标",自己从零写,又难又不准,还容易写错。
好消息:Foundry 上全给你备好了。
Microsoft Foundry 现成评估器一览
打开 Microsoft Foundry,进到「评估」→「计算器目录」,你会发现微软已经把一大堆现成的评估器摆在那儿了,拿来就能用:
- Tool-Call-Accuracy(工具调用准确度):看 Agent 该调工具的时候有没有调对
- Tool-Call-Success(工具调用成功):看所有该调的工具是不是都成功调了
- Tool-Input-Accuracy(工具入参准确度):看传给工具的参数对不对(0 或 1 打分)
- Tool-Output-Utilization(工具输出利用率):看 Agent 有没有"用上"工具返回的结果,别白调了
- Tool-Selection(工具选择):看在一堆工具里有没有挑对那个该用的
- Coherence(连贯性):看回答逻辑顺不顺、读着别扭不别扭
- Fluency(流畅度):看话说得自然不自然,像不像人话
- Groundedness(事实依据):看回答是不是有根有据,没瞎编
- Similarity / Retrieval(相似度 / 检索):看答案跟标准答案有多接近、检索找得准不准
- Task-Completion / Task-Adherence(任务完成 / 任务遵从):看 Agent 有没有把活干完、有没有照着要求来
这些大部分都是 Microsoft 官方发布的(类型写着 builtin),版本号都迭代十几次了,比你自己写的稳得多。
而且你还能在目录里看到自己团队建的评估器——比如截图里那个 HarnessEval,类型是 custom,就是自己人传上去的。官方的 + 自定义的,混着用,都行。
Harness 集成三步走
重点来了:Harness 里怎么薅这个羊毛?
做 Harness(这套 AI Agent 操作系统框架)的时候,评估这块完全不用自己硬写。思路就一句话:
本地负责跑流程,把"打分"这件脏活累活,外包给 Foundry 上的现成评估器。
具体分三步走,特别简单:
第一步:本地能写的,本地写
那种简单粗暴的检查——"有没有调工具""长度超没超""中文问就得中文答"——这些规则明确的,留在本地用普通代码写,又快又省钱,不用麻烦 Foundry。
第二步:要"动脑子"判断的,交给 Foundry
像连贯性(Coherence)、工具输出利用率(Tool-Output-Utilization)这种需要"理解语义"才能打分的,直接连到 Foundry,调用上面那些现成评估器。
你只要在代码里指定好要用哪几个(比如 tool_output_utilization 和 coherence),剩下的打分逻辑微软都帮你写好了,你一行判断逻辑都不用碰。
第三步:把结果收回来,统一看
跑完之后,Foundry 会把每一项的分数 + 为什么给这个分(Reason)都返回给你。你在 Harness 里统一收一下,红的(不合格)绿的(合格)一目了然。
代码实战:一看就懂
光说不练假把式,下面这段 C# 代码就是上面那套思路的完整落地。它做了两件事:先建一个天气 Agent 跑起来,再把它丢给 Foundry 上的评估器打分。
using AIConfig;using Azure.AI.OpenAI;using Azure.AI.Projects;using Azure.Identity;using Microsoft.Agents.AI;using Microsoft.Agents.AI.Foundry;using Microsoft.Extensions.AI;using Microsoft.Extensions.AI.Evaluation;using System.ClientModel;using System.ComponentModel;// 初始化 Azure OpenAI 配置与凭据。var aiConfig = new AzureOpenAIConfig("gpt-5.4-mini");var credential = new ApiKeyCredential(aiConfig.Key);var agent = new AzureOpenAIClient(new Uri(aiConfig.Endpoint), credential).GetChatClient(aiConfig.DeploymentName).AsIChatClient().AsAIAgent(instructions: "你是一个天气服务预报员",tools: [AIFunctionFactory.Create(GetWeather, name: "GetWeather")],name: "天气服务预报员");// 构造一条用户问题,供代理回答与后续评估使用。var ask = "东京的天气怎么样?";// 运行代理并获取响应。var response = await agent.RunAsync(new[] { new ChatMessage(ChatRole.User, ask) });Console.WriteLine($"代理响应: {response.Text}");Console.WriteLine("-----------------------------");var foundryConfig = new FoundryAgentConfig("azure-foundry");var foundryCredential = new ClientSecretCredential(tenantId: foundryConfig.TenantId,clientId: foundryConfig.ClientId,clientSecret: foundryConfig.ClientSecret);var aiProjectClient = new AIProjectClient(new Uri(foundryConfig.Endpoint), foundryCredential);var foundry = new FoundryEvals(aiProjectClient, "gpt-5.4-mini", "tool_output_utilization", "coherence");var evaluationResult = await agent.EvaluateAsync(new[]{"西雅图天气怎么样?","计划周末去波特兰旅行吧。","派克市场附近有哪些餐厅?"},foundry, "FoundryEvalDemo");// 输出整体评估是否通过,并用颜色区分结果。Console.Write($"是否通过Foundry评估: ");Console.ForegroundColor = evaluationResult.Passed == 0 ? ConsoleColor.Red : ConsoleColor.Green;Console.WriteLine(Convert.ToBoolean(evaluationResult.Passed));Console.WriteLine();// 输出每一项本地评估指标的详细结果。foreach (var itemResult in evaluationResult.Items){foreach (var checkResult in itemResult.Metrics){Console.WriteLine($"Name: {checkResult.Value.Name}, Reason: {checkResult.Value.Reason}");if (checkResult.Value.Metadata != null && checkResult.Value.Metadata.Count > 0){// 某些评估项会附带额外元数据,这里一并输出方便排查。Console.WriteLine("相关内容:");foreach (var kv in checkResult.Value.Metadata){Console.WriteLine($" {kv.Key}: {kv.Value}");}}}}[Description("获取指定位置的天气。")]static string GetWeather([Description("要获取天气的位置。")] string location){// 模拟本地工具被代理调用后的输出与返回值。Console.WriteLine($"调用了 GetWeather 工具,位置: {location}");return $"{location} 的天气多云,最高气温 15°C。";}
代码拆解分析
① 先建一个天气 Agent
var agent = new AzureOpenAIClient(...).GetChatClient(...).AsAIAgent(instructions: "你是一个天气服务预报员",tools: [AIFunctionFactory.Create(GetWeather, name: "GetWeather")],name: "天气服务预报员");
就是搭了个"天气预报员"机器人,还给它配了一把工具 GetWeather(查天气用的)。
② 让它先答个题热个身
var response = await agent.RunAsync(...); // 问它"东京天气怎么样?"
③ 连上 Foundry,指定要用哪几个评估器
var foundry = new FoundryEvals(aiProjectClient, "gpt-5.4-mini","tool_output_utilization", "coherence");
这一行就是薅羊毛的关键——它没自己写任何打分逻辑,直接点名要 Foundry 上的两个现成评估器:
- tool_output_utilization(工具输出利用率)
- coherence(连贯性)
④ 一口气喂三个问题进去打分
var evaluationResult = await agent.EvaluateAsync(new[] { "西雅图天气怎么样?", "计划周末去波特兰旅行吧。", "派克市场附近有哪些餐厅?" },foundry, "FoundryEvalDemo");
⑤ 把结果收回来,红绿灯一目了然
Console.ForegroundColor = evaluationResult.Passed == 0 ? ConsoleColor.Red : ConsoleColor.Green;// ...再遍历每一项,打印 分数 + Reason(为什么给这个分)
你看,从头到尾你没写过一句"怎么判断连贯性"的逻辑——那些烧脑的判断,全是 Foundry 上现成评估器在背后默默帮你干的。这就是这篇文章想说的那句话:简单的活本地干,烧脑的活 Foundry 干。
最后跑完后可以到 Foundry 的评估器上看到评估的结果:
成本效益分析
为啥这么干划算?给你算笔账
自己写评估器:
- 又难又费时间
- 评"软指标"基本写不准
- 微软更新了你还得跟着改
直接用 Foundry 的:
- 现成的,拿来就用
- 官方维护,自动迭代(你看那些版本号都十几代了)
- 能跟自己的 custom 评估器混搭
- 本地简单的 + 云端复杂的,组合拳打出来,又省钱又准
一句话总结:简单的活本地干,烧脑的活 Foundry 干。能薅的羊毛,干嘛不薅?
最后唠一句:做 Agent 这件事,"造出来"只是第一步,"评得准"才是能不能上生产环境的关键。与其埋头自己造一堆评估轮子,不如打开 Foundry 看看——大概率你想要的那个评估器,微软早就给你做好放那儿了。
站在巨人的肩膀上,比自己长高快多了。

