精选

为 NVIDIA Nemotron 3 Ultra 创建 LangChain 深度智能体线束配置文件以提高性能

代理式系统通常需要在准确性和成本之间做出权衡。性能最高的专有前沿模型和线束可提供最高的准确性,但成本高昂。微调是解决这一问题的一种方法。较小或更高效的开放模型从较低的准确度开始训练,以提高特定智能体的性能。但是,微调需要专业知识和硬件来训练和托管自定义模型。

虽然针对特定用例调整提示词是一种常见做法,但将此过程规范化为智能体工具并验证其是否能显著改善结果是较新的做法。以下两项进展使这一切成为可能:

  • 专为给定线束构建的评估基准,可用于验证更改是否提高了性能。
  • 按模型自定义切入点 (例如 LangChain 的智能体工具配置文件) 是首个此类示例,使团队能够根据特定的智能体工作流调整模型。

在本教程中,您将为 NVIDIA Nemotron 3 Ultra 创建与专有前沿模型智能相匹配的 LangChain Deep Agents 线束配置文件。所有调整均使用 NVIDIA 云提供商提供的现有 NVIDIA Nemotron 3 Ultra 端点对智能体线束进行。 匹配专有前沿模型智能

视频 1. 使用手动和自动评估,为 Nemotron 3 Ultra 创建和验证 LangChain Deep Agents 线束配置文件

预备知识

  • 已安装 Python 和 LangChain Deep Agents 的主机。
  • NVIDIA Nemotron 3 Ultra 的 API 密钥。对于测试,build.nvidia.com 提供免费 API 访问权限。对于生产,可以考虑使用 NVIDIA 云提供商的端点,例如 Baseten、Crusoe、Fireworks、Nebius 或 Together AI。
  • 推荐:用于收集智能体追踪的 LangSmith 账户

运行评估以创建线束配置文件

LangChain Deep Agents 是一款热门的开源智能体工具。为调整智能体线束以用于特定模型,LangChain 提供了两种重要工具:

  • 开源评估基准测试。
  • 智能体束配置文件为开发者提供一流的扩展点,以便根据模型更改智能体束行为。

为 NVIDIA Nemotron 3 Ultra 调整 Deep 智能体的程序如下:

  • 使用 Deep 智能体 和 NVIDIA Nemotron 3 Ultra (无线束配置文件) 运行评估基准测试,从而建立基准。
  • 分析故障。
  • 对线束配置文件提出更改建议,以解决故障问题。
  • 重新运行基准测试,以验证更改如何在不引入回归的情况下改进评估。

智能体线束配置文件可用的更改类型包括:

  • 提示:更改 Deep 智能体的基本系统提示,应用提示后缀或更改工具描述。例如,添加 Nemotron Ultra 指令时,首选澄清问题或首选工具结果,而不是模型召回。
  • 排除项:要删除的工具或中间件。
  • 新增功能:开发者可通过额外的中间件或子智能体扩展工具,例如检查截断的模型响应或错误工具名称的中间件。

线束工程的目标是使智能体对模型的调用更接近模型在训练数据中看到的内容。

  1. 运行评估

NVIDIA Nemotron 3 Ultra 无法对内置 read_file 工具进行测试。

Failing test: tests/evals/test_file_operations.py::test_read_file_truncation_recovery_with_pagination[nvidiahub:ultra-tme]

Failure:
  success check failed: Expected final text to contain 'opal-fox-91', got: 'x'
  Trajectory:
  step 1:
    - read_file {'file_path': '/big.txt'}
  step 2:
    text: x

read_file 工具是 LangChain Deep Agent 工具的关键组成部分,用于编码、数据分析和智能体任务 (如查看技能) 。任务要求输入/big.txt 中的最后一个非空行。第一次 read_file 调用返回文件的第一页,其中仅包含 x 个值。正确答案 opal-fox-91 将显示在文件的稍后部分。该模型需要继续通过偏移/ 限制分页来读取,但答案是在第一页。

  1. 提出修复建议
class ReadFileContinuationNoticeMiddleware(AgentMiddleware):
      """Tell the model when a read_file result probably continues."""
      name = "ReadFileContinuationNoticeMiddleware"
      def wrap_tool_call(self, request, handler):
          return self._annotate(request, handler(request))
      @staticmethod
      def _annotate(request, result):
          if not isinstance(result, ToolMessage):
              return result
          if request.tool_call.get("name") != "read_file":
              return result
          content = str(result.text)
          args = request.tool_call.get("args", {}) or {}
          offset = int(args.get("offset", 0))
          limit = int(args.get("limit", 100))
          n_lines = sum(
              1
              for row in content.split("\n")
              if "\t" in row and row.split("\t", 1)[0].strip().isdigit()
          )
          if n_lines < limit:
              return result
          notice = (
              f"\n\n[read_file returned {limit} lines starting at offset {offset}, "
              f"the per-read limit. The file likely continues past this window. "
              f"To read further, call read_file again with offset={offset + limit}. "
              f"Do not assume you have seen the end of the file.]"
          )
          return result.model_copy(update={"content": content + notice})

将中间件添加到线束配置文件中:

profile = HarnessProfile(
      extra_middleware=[
          ReadFileContinuationNoticeMiddleware(),
      ]
  )
  register_harness_profile("nvidia:nemotron-ultra", profile)
  1. 验证修复

使用新配置文件重新运行失败测试:

uv run pytest \
  tests/evals/test_file_operations.py \
  --model nvidia:nemotron-utlra \
  --harness-profile nemotron-ultra

测试通过后,重新运行整个评估基准测试,以确保配置文件更改不会引入回归。基准测试和测试都是随机的,因此多次运行基准和提议的更改非常重要。

配置文件 读取文件测试 评估基准 
基准 0 / 3 平均分 94/ 127
读取文件中间件 3 / 3 平均分 96/ 127
表 1:结果显示,文件中间件解决了所有三次失败的 read_file 测试,并将整体评估基准得分从 94 提高到 96/ 127

在最终完成更改之前,请务必考虑过拟合。在本示例中,文件分页中间件是一种机械修复。它教会模型如何进行适当的工具调用。相比之下,假设智能体未能完成评估任务,因为它会将“事件警报”与“事件分类”相混淆在线束中添加“alert”或“triage”的定义更有可能导致过拟合。

自动创建线束配置文件

前三个步骤中的手动过程是一个循环。运行基准测试,读取故障,更改配置文件,然后再次运行。像这样的循环正是代理擅长在无人值守的情况下运行的东西。Geoffrey Huntley 称之为“ralph 循环”:模型反复读取当前状态,进行一次更改,并使用文件系统 (而非对话) 作为内存。虽然该模式是为编码智能体而创造的,但它适用广泛。

线束工程是指向不同目标的相同循环。将代码库替换为配置文件,将测试套件替换为评估基准测试,形状相同。提出更改,根据目标信号进行检查,保留或丢弃更改,然后重复。评估基准测试使其能够安全地自动化 – 它为循环提供了一个真值验证器,因此只有在显著帮助的情况下,才会保留提议的更改。

LangSmith 引擎 是 LangChain 用于线束改进的此循环的托管版本。它会检测生产跟踪中的故障,根据源代码诊断其根本原因,起草修复方案,并添加评估器以阻止回归返回。每项提议的更改在发布之前都会经过人工审查。

本节的其余部分将介绍类似算法的简化版本,其中包含 NemoClaw 社区资源库 中提供的基于 LangChain Deep Agents 构建的可运行参考实现。它有意设置为小型,它会根据评估基准而不是实时流量调整单个线束配置文件,但它端到端运行类似的自校正循环,因此您可以遵循机制并自行尝试。

改进循环

外部循环是有意地简单化的,但有一些决定是将可靠的改进循环与过拟合机器分开的:

  • 先验证再相信。 模型调用是随机的,而由 LLM 判断的基准测试也是随机的。只有在连续多次通过相同测试后,修复程序才会被接受,该测试会过滤掉因运气而通过的更改。
  • 快照和回滚。 在每次尝试之前保存配置文件,如果尝试不起作用,则恢复配置文件,因此糟糕的提案永远不会使配置文件比开始时更糟糕。
  • 从上次尝试中学习。 当尝试失败时,循环会准确地传递下一次尝试的内容以及失败原因,因此模型会优化其方法,而不是再次提出相同的修复方案。
  • 重新检查整个套件。 修复完成后,整个基准测试会被重新运行 — 不仅仅是已修复的测试 — 以捕获回归,并对新解锁的路径进行表面测试。

循环继续进行一轮循环,直到剖面完全通过,整个回合没有任何改进,或者迭代预算耗尽。

代理式提议者

有趣的部分是“提议更改”步骤,其中模型会收到故障描述,获得探索解决方案的工具,并提出配置文件修改建议。

每个提案都以简短且有边界的智能体会话的形式运行。智能体将获得配置文件的可写副本,以及对失败测试、观察到的智能体轨迹、SDK 和基准测试代码的只读访问权限。借助读取、编辑、grep、glob 等普通文件工具,它可以在依赖中间件 hook 或工具默认行为之前确认其行为方式,而无需根据代码片段进行猜测。然后,它会进行最小的更改,以解决诊断出的故障,并编写关于更改内容及其原因的简短说明。

两个约束条件可确保智能体接地。其写入权限仅限于配置文件,因此它可以读取整个代码库的上下文,但只能修改正在调整的一个文件。而且,与特定的黑客行为相比,它更喜欢一般的修复方法,以便推断故障暴露的更广泛的行为,而不是对某个测试的确切输入进行特殊的分类。这种区别体现了教授模型持久技能与记住单个答案之间的区别。

为进一步防止过拟合,您可以指定将评估套件的这一部分作为验证集保留。进行更改的代理循环永远不会看到这些测试,但测试中的分数用于验证配置文件的改进。

以下缩略输出显示了针对 Deep 智能体利用和 Nemotron 3 Ultra 运行的参考实现,以解决先前确定的 read_file 分页失败问题:

$ hep langchain ralph \
    --model "openai:nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B" \
    --profile examples/deepagents/profiles/nvidia_nemotron_3_ultra.py \
    --evals-dir external/deepagents/libs/evals \
    --category file_operations \
    --ralph-model "anthropic:...:bedrock-claude-opus-4-8" \
    --ralph-max-turns 100 \
    --max-iters 100 \
    --max-iters-per-failure 5 \
    --verify-runs 3

[ralph] baseline: 20 passed, 1 failed  (correctness: 0.95)

  FAILED test_read_file_truncation_recovery_with_pagination
  Expected final text to contain 'opal-fox-91', got: 'x'
    step 1: read_file {'file_path': '/big.txt'}
    step 2: text: x

[ralph] round 1 — fixing pagination failure (attempt 1/100)
[ralph:proposer] Root cause: read_file pages by lines (100),
  and the result gives no signal the file continues past the
  page — so the model treated the first page's last line as
  EOF and answered after one call.

  Fix (profile levers, not test-specific values):
    1. Middleware: when a page returns full (lines == limit),
       append a hint to keep paging (offset=<last line>)
       until a short page signals EOF.
    2. Prompt: page to EOF before answering end-of-file
       questions.

[ralph]   verify 1/3 ✓   2/3 ✓   3/3 ✓
[ralph]   FIXED

[ralph] === re-running full suite ===
  results: 21 passed, 0 failed  (correctness: 1.00)

result: 20 → 21 passed, 1 → 0 failed

该智能体诊断出故障的根本原因,获得了通过连续三次检查的修复,并在无回归的完整套件重新运行中幸存下来。

调整 Ultra 以适应其他线束

此自动化循环中没有任何内容是 LangChain Deep Agents 特有的。要使 Ultra 适应使用此框架的其他智能体框架,请展示三件事:运行评估并报告每次测试通过/ 失败的结果和轨迹的方法、可通过编程方式编辑和验证的配置文件或配置文件,以及用于提出编辑建议的前沿质量模型。给定这些,相同的循环 (提议、验证、保留或回滚、重新运行) 将保持不变。

了解详情

标签