以编程方式使用文档

某些代理任务有明确的"完成"定义,但工作模型本身无法在第一次尝试时可靠地达到:符合音节模式的俳句、通过所有测试的重构、涵盖所有必需要求的报告。 RubricMiddleware 允许你声明 *什么样的结果才算完成* 作为评分标准,并让代理 **自我评估并迭代** 直到评分标准满足(或达到配置的最大迭代次数上限)。

LLM-as-a-judge 是一种模式,其中一个语言模型根据定义的标准评估另一个模型的输出。在 LangSmith 评估中,LLM即评判者评估器以离线批处理方式对应用程序输出进行评分。 RubricMiddleware 在运行时应用相同的模式:深度代理生成输出后,专门的评判器模型会根据你的评分标准审查对话记录,并驱动修订,直到每个标准都通过(或达到配置的迭代上限)。

当深度代理完成推理时,LLM即评判者评判子代理会审查输出并返回裁决。如果返回 needs_revision,则会逐标准反馈注入对话,代理再次运行。循环在 satisfied, max_iterations_reached, failed, or grader_error.

graph LR
    Start[User invokes<br/>with rubric] --> Agent[Deep agent]
    Agent --> Grader{Grader<br/>verdict}

    Grader --> |satisfied| Done[Finish execution]
    Grader --> |failed| Done
    Grader --> |grader_error| Done
    Grader --> |needs_revision| Cap{Iterations < <br/> max_iterations?}

    Cap --> |yes| Inject[Re-prompt deep agent with per-criterion feedback]
    Cap --> |no| Done

    Inject --> Agent

    classDef trigger fill:#F6FFDB,stroke:#6E8900,stroke-width:2px,color:#2E3900
    classDef process fill:#E5F4FF,stroke:#006DDD,stroke-width:2px,color:#030710
    classDef decision fill:#FDF3FF,stroke:#7E65AE,stroke-width:2px,color:#504B5F
    classDef alert fill:#F8E8E6,stroke:#B27D75,stroke-width:2px,color:#634643

    class Start trigger
    class Agent,Inject process
    class Grader,Cap decision
    class Done,MaxOut alert

配置中间件

添加 RubricMiddlewaremiddleware 调用时的 create_deep_agent:

参数必填默认值描述
modelNoneLLM即评判者评判子代理使用的聊天模型。接受 "provider:model-id" 字符串或 BaseChatModel 实例。通常比深度代理的工作模型更小或更便宜的模型。
system_prompt内置评判器提示自定义评分指令。回退到默认系统提示,向评判器教授裁决格式及其可用的工具。
toolsNoNone评判器在做出裁决前可调用的工具,用于收集证据(运行测试、计算令牌数、读取文件)。如果没有工具,评判器仅根据对话记录进行推理。
max_iterationsNo3每次评分标准尝试的评判器迭代硬上限。最大输入值为 20。当达到上限而未获得 satisfied 裁决时,代理以 max_iterations_reached.
on_evaluationNoNone 状态终止。可选的回调函数,在每次 RubricEvaluation 评分迭代后触发,无论你是否使用 invoke(), stream() or stream_events()。可用于日志记录、自定义指标、评估数据集或 UI 更新。

调用时传递评分标准

在调用状态时传递 rubric 字符串以启动自我评估循环。使用 invoke() 进行单个阻塞调用,或 stream_events(..., version="v3") 配合 CustomTransformer 以在 stream.custom 上接收实时评分事件:

invoke()

stream_events()

评分标准评分会在 stream.custom:

事件触发时机Payload 字段
rubric_evaluation_start在评判器运行之前。<ul><li>type:事件名称</li><li>grading_run_id:在一次评分尝试内的所有事件中共享</li><li>iteration:当前评分运行的从零开始的索引</li></ul>
rubric_evaluation_end在评分器返回后或评分器异常后。<ul><li>type:事件名称</li><li>grading_run_id:在一次评分尝试内的所有事件中共享</li><li>iteration:当前评分遍次的从零开始的索引</li><li>result:此次遍次的最终裁决</li><li>explanation:来自评分器的摘要</li><li>criteria:每个标准的裁决</li></ul>

评分裁决

当深度智能体完成推理并产生输出后,LLM 即评分器子智能体会根据评分标准审查该输出,并产生以下裁决之一:

状态含义是否循环回退?
satisfied评分标准中的每个标准都通过。
needs_revision至少一个标准未通过;评分器反馈被注入,智能体再次运行。
max_iterations_reached评分器仍希望进行修改,但 max_iterations 已达到。
failed评分器判定评分标准格式错误或无法根据记录进行评估。
grader_errorLLM 即评分器子智能体本身抛出了异常(提供商超时、凭据缺失、结构化响应格式错误等)。

观察迭代进度

on_evaluation 是一个回调函数,在每次评分迭代后触发,并附带评分器的裁决,无论你是否调用 invoke() or stream_events()。如果你没有从 stream.custom 中读取评分事件(配合 CustomTransformer) or 使用 LangSmith 追踪运行情况),它是检查评分过程中发生情况的主要方式。

中间件在每次 RubricEvaluation 评分遍次 后使用字典调用你的函数。 RubricEvaluation

字段类型描述
grading_run_idstr在一次评分标准尝试中每次评估的共享标识符。当调用者提供不同的 rubric时,或当同一个 rubric 在得到最终裁决后再次被调用时,会开始新的运行。
iterationint在该运行中当前评分遍次的从零开始的索引。
resultstr此次遍次的评分器裁决: satisfied, needs_revision, failed, or grader_error.
explanationstr来自评分器的自由格式摘要。基础设施故障时,包括异常类型和消息。
criterialist每个标准的裁决。每个条目为 {name, passed: true} or {name, passed: false, gap} ,其中 gap 是针对未通过标准的可操作反馈。

评分遍次事件

事件描述
**成功评分**每次遍次触发一次,包括中间 needs_revision 裁决和最终 satisfied or failed verdict. <br /><br /> 当评分器返回时 needs_revisionmax_iterations 已达到时,回调仍会收到 result: "needs_revision" (评判者的裁决)。运行的最终状态是 max_iterations_reached 基于私有状态 _rubric_status,而非评估记录。请检查 _rubric_status 之后 invoke 完成后,或读取 _rubric_evaluations_rubric_iterations,以在达到上限时进行分支。
**评判者异常**触发时返回 result: "grader_error",一个从异常派生的解释,以及一个空的 criteria 列表。
**回调中的错误**异常会被记录并抑制。评分循环继续。请勿使用 on_evaluation 来强制控制流(例如,抛出异常以停止代理)。

在多次调用中保持评分标准

单个 agent.invoke() or agent.stream_events() 调用运行评分标准循环直到完成,并以最终裁决结束: satisfied, failed, or max_iterations_reached.

要将评分标准延续到后续调用,请附加一个 检查点器 并传递相同的 thread_id 与调用一起。在这些情况下,相同的 rubric 会持续存在于未来的 invoke() or stream_events() 调用中,直到你传入新的为止。

中断(KeyboardInterrupt, asyncio.CancelledError)会从 agent.invoke()agent.stream_events() 中未捕获地传播出去。在已检查点的线程上,下次使用相同评分标准调用会恢复正在进行的评分运行。

示例:生成经过验证的 Python 代码

以下示例构建了一个深度代理,用于编写 find_duplicates 函数。它定义 RubricMiddleware 一次,将其附加到代理,然后在调用时传递一个 rubric 字符串。

该示例不是让评判者抽象地推理正确性,而是为它提供了一个 run_test_suite 工具来直接验证行为。评判者在做出裁决前会调用此工具获取额外信息,当未提供工具时会回退到从对话记录中推理。

Define RubricMiddleware

此中间件在基础代理之上添加了一个 LLM 即评判者的评分循环。配置评判者模型、可选的自定义提示、用于收集证据的工具以及最大迭代次数上限。

Pass it to a deep agent

代理的 system_prompt 告诉它如何完成工作,而评分标准告诉评判者如何评判工作。

Invoke with a human message and rubric

在调用时,在 messages 中提供用户请求,在 rubric 中提供换行分隔的检查清单,评判者必须标记为已满足。当输入状态中未提供 rubric 时,中间件不会运行。

代理产生输出后,评判者接管并检查每个标准的输出:例如,当输入包含不可哈希类型时 test_unhashable 会因 TypeError 而失败。如果有问题,评判者会提供反馈,然后代理修改其实现并将其返回给评判者。