mcpField
I
inngest-agent-evals

inngest-agent-evals

github.com/inngest测试与质量29573 次安装4 周前更新
代码仓库

关于 inngest-agent-evals

inngest-agent-evals 是用于在生产环境评估 AI Agent 和工作流的技能,借助 Inngest 的持久评分与追踪能力。它指导设置评分、延迟评估、会话分组和实验,以分析质量并比较不同方案。

主要功能

  1. 01直接评分与延迟评分
  2. 02按会话对运行分组
  3. 03提示词、模型和工具实验
  4. 04关联追踪的评估工作流
  5. 05规划结果与质量信号

适用场景

  1. 01在执行期间为 Agent 输出评分
  2. 02在运行结束后记录用户反馈
  3. 03比较提示词或模型方案
  4. 04按对话或工单调查相关运行

MCP 相关

该技能介绍 Inngest 中的生产评估工作流,未说明 MCP 功能。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/inngest/inngest-skills --skill inngest-agent-evals

安装后在 Claude Code 中输入/inngest-agent-evals确认已加载。

详细介绍

Inngest Agent 评估

当用户希望在生产环境中评估 AI Agent 或 AI 工作流、添加评分、比较提示词/模型/工具、分组相关运行,或排查 Agent 结果好坏的原因时,使用此技能。

Agent 评估并非独立的软件包,而是基于 Inngest 函数、持久化步骤、评分、延迟评分、会话、跟踪、实验和 Insights 构建的生产评估工作流。

权威参考资料

需要准确的 API 细节时,先查阅公开文档:

决策流程

从结果出发,而不是从实现机制出发:

  1. 确定产品或质量信号:有帮助的点击、工单解决、转化、护栏通过、检索质量、模型置信度、延迟、成本、人工审核或 LLM 作为裁判的结果。
  2. 确定信号何时出现:
    • 运行期间:使用 step.score() 或 inngest.score() 直接评分。
    • 运行之后:使用 createScorer() 和 defer() 进行延迟评分,或显式调用 inngest.score({ runId })。
  3. 确定用户将如何检查相关工作:
    • 对 conversation_id、ticket_id、agent_run_id 或 import_id 等重复出现且基数较高的标识符,使用 meta.sessions。
    • 对临时历史分析、低基数筛选、SQL 聚合和广泛调查,使用 Insights。
  4. 确定是否需要比较不同变体:
    • 使用 group.experiment() 比较提示词、模型、提供方、工具、工作流或发布方案。
    • 当评分应归属于选定变体时,将 experimentRef 传递给延迟评分或后续评分。
  5. 保留可追溯性:
    • 将模型调用、工具调用、等待、数据库写入和评分工作放在持久化步骤中,以便通过跟踪说明评分的由来。

设置要求

  • 使用 TypeScript SDK v4,并安装最新 SDK:npm install inngest@latest。
  • 评分和延迟评分属于 beta API;发布面向用户的示例前,请对照文档确认当前导入方式。
  • step.score() 需要在 Inngest 客户端上使用 inngest/experimental 中的 scoreMiddleware()。
  • 从 inngest/experimental 导入 createScorer(),并将评分器与其他函数一同注册到 serve 处理程序中。
  • 通过 TypeScript SDK 发送会话需要 v4.7.0 或更高版本。
  • 步骤实验需要 v4.8.0 或更高版本才能使用 group.experiment() 和 inngest 中的 experiment 辅助函数。

客户端结构:

import { Inngest } from "inngest";
import { scoreMiddleware } from "inngest/experimental";

export const inngest = new Inngest({
  id: "support-agent",
  middleware: [scoreMiddleware()],
});

会话

当事件属于用户流程、对话、工单、导入或有人会反复检查的 Agent 任务时,添加会话。

await inngest.send({
  name: "support/ticket.created",
  data: {
    ticketId: "tk_123",
    message: "I can't sign in.",
  },
  meta: {
    sessions: {
      ticket_id: "tk_123",
    },
  },
});

规则:

  • 使用稳定、非机密且基数较高的 ID。
  • 键名保持通用,例如 conversation_id;实际 ID 放在值中。
  • 如果下游运行应加入同一会话,则通过 step.invoke() 和 step.sendEvent() 显式传递会话。
  • 不要将会话用于 environment: prod 之类的标签;这类筛选应使用 Insights。

直接评分

当函数运行期间已知分数时,使用直接评分。

适合直接评分的情况:

  • 防护措施通过/未通过
  • JSON 有效性
  • 检索置信度
  • 工具是否成功
  • 模型置信度
  • 内联 LLM-as-judge 结果
export const answerTicket = inngest.createFunction(
  {
    id: "answer-ticket",
    triggers: [{ event: "support/ticket.created" }],
  },
  async ({ event, step }) => {
    const answer = await step.run("generate-answer", () =>
      generateAnswer(event.data.ticketId)
    );

    const passed = await step.run("check-answer", () => validateAnswer(answer));

    await step.score("score-answer-quality", {
      name: "answer-quality",
      value: passed,
    });

    return { answer, passed };
  }
);

使用稳定的评分名称。更改评分名称会创建单独的指标。 评分值必须是有限数字或布尔值。

延迟评分

当有用的信号在父工作流完成后才到达时,例如用户反馈、转化、工单重开、留存,或耗时较长的 LLM-as-judge 运行,请使用延迟评分。

import { createScorer } from "inngest/experimental";
import { z } from "zod";

export const feedbackScorer = createScorer(
  inngest,
  {
    id: "support-feedback-scorer",
    schema: z.object({ ticketId: z.string() }),
  },
  async ({ event, step }) => {
    const feedback = await step.waitForEvent("wait-for-feedback", {
      event: "support/feedback.received",
      timeout: "7d",
      if: `async.data.ticketId == '${event.data.ticketId}'`,
    });

    return {
      name: "user-feedback",
      value: feedback?.data.helpful ? 1 : 0,
    };
  }
);

从产生信号的函数中触发:

async ({ event, step, defer }) => {
  const answer = await step.run("generate-answer", () =>
    generateAnswer(event.data.ticketId)
  );

  defer("score-feedback", {
    function: feedbackScorer,
    data: { ticketId: event.data.ticketId },
  });

  return { answer };
}

注意事项:

  • 使用 serve({ functions: [...] }) 注册评分器。
  • defer() 是发起后即返回的调用;不要对它使用 await。
  • 延迟评分器会自动关联到父级运行。
  • 如果信号超时,请根据产品语义返回默认分数或 null。

实验

在真实流量中比较提示词、模型、提供商、工具、工作流重写或运营设置时,使用 group.experiment()。

import { experiment } from "inngest";

const { result, variant, experimentRef } = await group.experiment(
  "answer-style",
  {
    variants: {
      concise: () => step.run("answer-concise", () => answerConcise(event.data)),
      detailed: () =>
        step.run("answer-detailed", () => answerDetailed(event.data)),
    },
    select: experiment.bucket(event.data.accountId, {
      weights: { concise: 50, detailed: 50 },
    }),
  }
);

选择策略:

  • 使用 experiment.weighted() 进行运行级流量拆分。
  • 如果用户、账户或租户通常应保持相同体验,请使用 experiment.bucket(stableId, { weights })。
  • 如果分配来自数据库、标记服务或发布表,请使用 experiment.custom()。
  • 在测试期间或选定胜出方案后,使用 experiment.fixed() 强制采用某个变体。

规则:

  • 每个变体回调都必须至少调用一个 step.* 工具。
  • 保持实验 ID 和变体名称稳定,因为它们会出现在跟踪记录中。
  • 重试和重放时会记忆所选变体。
  • 如果之后由单独的进程为所选变体评分,请持久化 experimentRef 和父级运行 ID。

为变体进行延迟评分时,传入引用:

defer("score-answer-feedback", {
  function: feedbackScorer,
  data: { ticketId: event.data.ticketId },
  experiment: experimentRef,
});

明确地在后续运行中评分时:

await inngest.score.experiment({
  name: "clickthrough",
  value: 1,
  experiment: experimentRef,
  runId: originalRunId,
});

现有项目迁移

向现有应用添加 Agent Evals 时:

  1. 查找现有的 Agent/工作流输出,以及用户会基于这些输出采取操作的位置。
  2. 找出领域中已有的持久标识符:对话 ID、工单 ID、账户 ID、导入 ID、运行 ID 或推荐 ID。
  3. 在围绕关联关系构建仪表板之前,先在事件产生方添加 meta.sessions。
  4. 在结果已知时,添加一个直接评分。
  5. 只有在信号事件已存在或能够清晰发出后,才添加延迟评分器。
  6. 一次只针对一个独立决策添加 group.experiment()。
  7. 在评分证明新路径有效之前,保持旧的提示词/模型/工具行为稳定。

如果代码仓库中有许多候选工作流,请先使用 inngest-brownfield-audit。如果工作涉及 AgentKit 或持久化 Agent 工作流,请将 inngest-agents 与此技能搭配使用。

反模式

  • 尚未确定结果指标,就开始进行提示词实验。
  • 使用不稳定的名称、字符串、对象、NaN 或 Infinity 进行评分。
  • 忘记 scoreMiddleware(),之后却误以为缺少 step.score()。
  • 在外部队列中运行评分器,而评分器需要持久化等待。
  • 仅在内存中保留实验分配结果。
  • 在后续运行中为实验变体评分,却没有原始 runId。
  • 将会话用于低基数标签或敏感个人数据。
  • 将模型/工具工作放在步骤之外,导致跟踪记录无法解释分数。

验证

  • 对 Inngest 客户端、函数、评分器架构和服务处理程序进行类型检查。
  • 确认评分器已注册到服务端点。
  • 测试生产者发出的事件包含预期的 meta.sessions。
  • 测试直接评分使用稳定的名称,且值为有限数字或布尔值。
  • 测试延迟评分器的超时行为。
  • 对于实验,测试每个变体回调都包含步骤工作,并确认后续评分在需要时会收到 experimentRef 和原始运行 ID。
  • 如果可能,运行 Inngest 开发服务器,并在仪表板中或通过可用的 CLI/API 工具检查跟踪记录、会话、评分和实验变体选择。

评论

支持 Markdown