尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

谁来评判评判者?在 Elasticsearch Workflows 中用 TaoToken 搭建 LLM-as-a-Judge 评测链路

发布时间:2026/9/27 20:07:24

资讯中心
01
ARTICLE

谁来评判评判者?在 Elasticsearch Workflows 中用 TaoToken 搭建 LLM-as-a-Judge 评测链路

谁来评判评判者?在 Elasticsearch Workflows 中用 TaoToken 搭建 LLM-as-a-Judge 评测链路
1. 为什么 RAG 评测总在「凭感觉」这一步卡住做 RAG 应用的人大多经历过这个场景检索策略调了一版prompt 改了两句回答模型从 A 换成 B然后你盯着几条样例反复看觉得「好像好了一点」但到底好在哪、差在哪说不清楚。问题不在于你不够细心而在于人工评审这件事本身不可扩展——改一次检索参数就要重看几十上百条答案不同人打分标准还不一致。LLM-as-a-Judge 就是来解决这个问题的用一个更强的模型当裁判对回答模型在正确性、忠实性、上下文相关性三个维度上自动打分。它适合谁适合已经在跑 RAG、需要频繁迭代检索或 prompt、又不想每次都靠肉眼判断的工程团队。这篇要做的是把这条评测链路完整放进 Elasticsearch Workflows 里同时用 TaoToken 统一 Key/API 通道来调用 Claude 作为裁判模型让知识库、评测用例、执行过程和评分结果都留在同一个系统中。我试过把评测脚本散落在 notebook 和本地文件里跑几次就找不到哪版对应哪版了。Workflows 的好处是 YAML 可版本控制、可重复执行、可通过 API 触发评测这件事终于有了「可复现」的底座。下面从接入通道开始一步步把闭环跑通。2. TaoToken 前置统一 Key 与 API 通道在 Workflows 里调用 Claude本质上是让 workflow 的ai.promptstep 能访问到一个可用的模型通道。TaoToken 在这里扮演的角色是统一入口你不需要在多个地方分别维护不同模型的 Key而是通过一个 API 通道拿到模型能力再把它接到 Elasticsearch 的 connector 上。先拿到访问凭证。打开控制台创建 API Key控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Key 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewriteAPI 基础地址是https://taotoken.net/api注意这个地址不加 UTM 参数直接用于程序调用。拿到 Key 之后建议先在模型对话页面确认通道可用再往 Workflows 里接模型对话验证https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite这里有个关键点Elasticsearch 的 AI Connector 需要配置一个兼容的 API endpoint 和 Key。TaoToken 提供的是统一通道所以你在 Kibana 里配置 connector 时把 base URL 指向https://taotoken.net/api把上一步创建的 Key 填进去即可。裁判模型选 Claude Sonnet 系列能力更强回答模型选 Claude Haiku 系列快、便宜两个 connector 可以共用同一个 Key。注意不要把 Key 硬编码进 workflow YAML。YAML 会进版本库Key 应该留在 Kibana connector 配置里workflow 只通过connector-id引用。如果你打算长期跑编码类或 Agent 类任务可以顺带了解 Coding Plan它更适合高频调用的场景Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入文档在这里配置 connector 遇到字段疑问可以对照接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite3. 可复制配置索引、connector 与 Workflow 骨架3.1 两个索引知识库与评判列表整个评测需要两个索引。hotpot-knowledge-base存上下文段落供检索使用hotpot-judgement-list存问题与标准答案作为评测用例。知识库的passage字段复制到semantic_content映射为semantic_text这样检索时直接用自然语言 queryElasticsearch 会自动处理 embedding。INDEX_NAME hotpot-knowledge-base if es_client.indices.exists(indexINDEX_NAME): es_client.indices.delete(indexINDEX_NAME) es_client.indices.create( indexINDEX_NAME, mappings{ properties: { title: {type: keyword}, passage: { type: text, copy_to: semantic_content, }, semantic_content: { type: semantic_text, inference_id: .jina-embeddings-v5-text-small, }, } }, ) print(fCreated index: {INDEX_NAME})评判列表索引则简单得多每个 document 一个question和一个answer标准答案。裁判模型会把回答模型的输出和这个标准答案做比对。3.2 connector 与 settings.json / config.toml 关键字段在 Kibana 里创建两个 AI Connector分别指向回答模型和裁判模型。如果你用配置文件管理连接信息关键字段大致是这样{ elasticsearch: { url: https://your-cluster.es.cloud:9243, api_key: ELASTICSEARCH_API_KEY }, kibana: { url: https://your-cluster.kb.cloud:9243 }, connectors: { answer_model: { connector_id: Anthropic-Claude-Haiku-4-5, base_url: https://taotoken.net/api, api_key: TAOTOKEN_API_KEY }, judge_model: { connector_id: Anthropic-Claude-Sonnet-4-6, base_url: https://taotoken.net/api, api_key: TAOTOKEN_API_KEY } } }如果用 TOML 管理结构等价[elasticsearch] url https://your-cluster.es.cloud:9243 api_key ELASTICSEARCH_API_KEY [connectors.answer_model] connector_id Anthropic-Claude-Haiku-4-5 base_url https://taotoken.net/api api_key TAOTOKEN_API_KEY [connectors.judge_model] connector_id Anthropic-Claude-Sonnet-4-6 base_url https://taotoken.net/api api_key TAOTOKEN_API_KEYconnector_id是 workflow 里ai.promptstep 引用的名字base_url指向 TaoToken 的统一通道api_key用上一步创建的 Key。两个 connector 共用同一个 Key 完全没问题。3.3 Workflow YAML 骨架Workflow 用 YAML 定义通过 Workflows API 上传Elastic 9.4。核心结构是先加载评测用例再用foreach逐条迭代每次迭代里跑「检索 → 回答 → 裁判 → 落库」四步。name: agent_accuracy_eval description: Batch evaluation. Loads the judgement list, iterates each case with a foreach, runs stage 1 (RAG answer with Haiku) and stage 2 (LLM judge with Sonnet), and indexes every score into the eval results index. enabled: true consts: kbIndex: hotpot-knowledge-base judgeIndex: hotpot-judgement-list resultsIndex: eval-results triggers: - type: manual steps: - name: load_cases type: elasticsearch.search with: index: {{ consts.judgeIndex }} query: match_all: {} size: 35 - name: eval_loop type: foreach foreach: {{ steps.load_cases.output.hits.hits }} steps: - name: retrieve type: elasticsearch.search with: index: {{ consts.kbIndex }} query: semantic: field: semantic_content query: {{ foreach.item._source.question }} size: 4 - name: agent_answer type: ai.prompt with: connector-id: Anthropic-Claude-Haiku-4-5 prompt: You are a Wikipedia QA assistant. Answer the question using ONLY the passages provided. Keep the answer short (one line). If the passages do not contain the answer, reply unknown. Question: {{ foreach.item._source.question }} Passages: 1. {{ steps.retrieve.output.hits.hits[0]._source.passage }} 2. {{ steps.retrieve.output.hits.hits[1]._source.passage }} 3. {{ steps.retrieve.output.hits.hits[2]._source.passage }} 4. {{ steps.retrieve.output.hits.hits[3]._source.passage }} - name: judge type: ai.prompt with: connector-id: Anthropic-Claude-Sonnet-4-6 prompt: You are a STRICT evaluator. Score the candidate answer against the ground truth on three axes. Each score MUST be exactly one of these three values: 0.0, 0.5, or 1.0. correctness: 1.0 contains ground truth exactly or unambiguous synonym; 0.5 partially correct; 0.0 wrong. faithfulness: 1.0 every claim supported by passages; 0.5 mostly supported; 0.0 unsupported claim. context_relevance: 1.0 passages enough to answer; 0.5 partial coverage; 0.0 not covered. Be harsh. If in doubt, pick the lower one. Question: {{ foreach.item._source.question }} Ground truth: {{ foreach.item._source.answer }} Candidate: {{ steps.agent_answer.output.content }} Passages: 1. {{ steps.retrieve.output.hits.hits[0]._source.passage }} 2. {{ steps.retrieve.output.hits.hits[1]._source.passage }} 3. {{ steps.retrieve.output.hits.hits[2]._source.passage }} 4. {{ steps.retrieve.output.hits.hits[3]._source.passage }} schema: type: object properties: correctness: type: number minimum: 0 maximum: 1 faithfulness: type: number minimum: 0 maximum: 1 context_relevance: type: number minimum: 0 maximum: 1 required: - correctness - faithfulness - context_relevance - name: save type: elasticsearch.index with: index: {{ consts.resultsIndex }} document: qid: {{ foreach.item._source.qid }} question: {{ foreach.item._source.question }} ground_truth: {{ foreach.item._source.answer }} candidate: {{ steps.agent_answer.output.content }} correctness: {{ steps.judge.output.content.correctness }} faithfulness: {{ steps.judge.output.content.faithfulness }} context_relevance: {{ steps.judge.output.content.context_relevance }}几个关键设计点值得展开。consts把索引名抽成常量换数据集时只改这里。judgestep 里的schema强制模型返回固定字段的 JSONminimum/maximum把评分锁在 0–1 之间这样savestep 可以直接引用{{ steps.judge.output.content.correctness }}不需要任何正则或 markdown 解析。裁判 prompt 里明确要求「Be harsh拿不准就取低分」这是为了避免模型给分过于宽松导致评测失去区分度。4. 验证请求上传、运行、看结果Workflow 定义好之后用三个 REST 端点跑起来。创建 workflowcurl -X POST https://your-kibana:9243/api/workflows \ -H Authorization: ApiKey $KIBANA_API_KEY \ -H kbn-xsrf: true \ -H Content-Type: application/json \ -d workflow.json启动一次执行curl -X POST https://your-kibana:9243/api/workflows/agent_accuracy_eval/run \ -H Authorization: ApiKey $KIBANA_API_KEY \ -H kbn-xsrf: true轮询执行状态直到完成curl -X GET https://your-kibana:9243/api/workflows/executions/{execution_id} \ -H Authorization: ApiKey $KIBANA_API_KEY35 个用例大概需要几分钟因为每次迭代要跑一次语义检索、两次 LLM 调用回答 裁判和一次索引写入。执行完成后直接查eval-results索引算平均分curl -X POST https://your-cluster:9243/eval-results/_search \ -H Authorization: ApiKey $ELASTICSEARCH_API_KEY \ -H Content-Type: application/json \ -d { size: 0, aggs: { avg_correctness: {avg: {field: correctness}}, avg_faithfulness: {avg: {field: faithfulness}}, avg_context_relevance: {avg: {field: context_relevance}} } }一次实测下来用 Claude Haiku 作为回答模型35 个 HotpotQA 用例的结果大致是correctness 0.74、faithfulness 0.90、context_relevance 0.86。这组数字本身比单个分数更有信息量——faithfulness 高说明模型没有编造内容correctness 偏低说明它在较难的多跳问题上没找到正确答案。问题出在检索或推理而不是幻觉。这就是评测链路的价值它告诉你该往哪个方向优化而不是让你猜。5. 本篇常见错排查connector 调用返回 401 或 403。大概率是 Key 没配对或者base_url写错了。检查 Kibana connector 里的 base URL 是否指向https://taotoken.net/apiKey 是否和创建时一致。可以先去模型对话页面确认通道本身可用排除 Key 失效的可能。judge step 报 schema 校验失败。裁判模型返回了 0–1 之外的数字或者字段名对不上。检查 prompt 里是否明确写了「exactly one of 0.0, 0.5, 1.0」以及schema的required字段是否和 prompt 里要求的字段完全一致。字段名大小写也要对齐。foreach 迭代到一半中断。常见原因是某次retrieve返回的 hits 少于 4 条导致hits.hits[3]越界。可以在 prompt 里做防御或者把size调小、在检索后加一个判断。多跳数据集里偶尔会有段落数不足的情况。评分全是 1.0没有区分度。裁判 prompt 太宽松了。加上「Be harsh. If in doubt between two scores, pick the lower one.」这类约束并把评分档位明确成 0.0/0.5/1.0 三档而不是让模型自由给分。执行很慢。每次迭代两次 LLM 调用是主要耗时。如果只是验证链路可以先把size从 35 降到 5跑通后再放大。另外确认回答模型用的是 Haiku 这类快模型别用大模型当回答模型。6. 把评测链路接进你的迭代流程跑通之后这条链路真正的用法是每次改检索策略、换 prompt、换回答模型就重新跑一遍同一个 workflow把新的评分和旧结果对比。YAML 进版本库评分进eval-results索引Kibana 仪表盘可以跟踪质量随时间的变化。如果你要长期跑这类评测或者把它接进 CICoding Plan 会比按次调用更划算Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入过程中如果 connector 字段或 workflow 语法卡住对照接入文档排查接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite需要新建 Key 或管理已有 KeyAPI Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite想先手动验证裁判模型对某条答案的打分是否符合预期可以在模型对话里直接试模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite最后一个实操建议先把裁判 prompt 在模型对话里手动调到你满意再固化进 workflow。裁判标准一旦稳定整条评测链路才有可比性——否则每次跑出来的分数波动你分不清是系统变了还是裁判心情变了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。