跳到内容

使用 Agent-lightning 训练第一个 Agent

欢迎!本教程是您使用 Agent-lightning 框架让 AI Agent 更智能的第一步。我们将向您展示如何采用一个简单的 Agent,并通过一种称为 自动 Prompt 优化 (APO) 的过程自动提高其性能。

Agent-lightning 的主要目标是提供一种结构化的方式来 训练您的 Agent。就像您使用数据训练机器学习模型一样,您可以使用任务数据集来训练 Agent。这可能涉及使用强化学习 (RL) 来教它新的行为,或者,正如我们今天所做的那样,优化其 Prompt 以使其更准确可靠。

提示

您可以在以下位置打开示例代码 room_selector_apo.pyroom_selector.py 在阅读本教程时。

我们的示例:房间选择器 Agent

今天,我们将使用一个 Agent,它的工作是预订会议室。这是一项常见的但棘手的任务,具有多个约束。

Agent 的工作方式如下

  • 输入: 它接收具有特定要求的任务,例如“为 4 个人在上午 10:00 预订一个带有白板的房间。
  • 操作: Agent 使用大型语言模型 (LLM) 来理解请求。它还可以使用工具,即预定义的函数,它可以调用这些函数来获取更多信息,例如检查外部数据库中的房间可用性。
  • 输出: 它的最终决定是它找到的最佳房间的 ID,例如“A103”。
  • 奖励: 在 Agent 做出选择后,一个单独的“评分器”函数会根据 0 到 1 的比例评估其性能。这个分数被称为它的 奖励。完美的选项获得 1.0,而错误的选项获得 0.0。

Agent 的逻辑是合理的,但其性能在很大程度上取决于其初始 Prompt。措辞不当的 Prompt 会让 LLM 感到困惑,从而导致糟糕的决策。我们的目标是使用 Agent-lightning 自动找到最佳 Prompt。

更深入地了解 Agent 的逻辑

现代 LLM 不仅可以生成文本,还可以决定调用您提供的函数。这通常称为工具使用或函数调用。我们的 Agent 使用此功能做出明智的决策。如果您不熟悉这个概念,可以阅读更多关于它的内容 OpenAI 的文档

以下是 Agent 逻辑的草图,紧密遵循 OpenAI API

# Pseudo-code for the Room Selector agent

import openai
import json

def room_selector_agent(task, prompt):
    client = openai.OpenAI()
    messages = [{"role": "user", "content": prompt.format(**task)}]
    tools = [ ... ] # Tool definition for the LLM

    # 1. First LLM call to decide if a tool is needed.
    response = client.chat.completions.create(
        model="gpt-5-mini",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
    response_message = response.choices[0].message
    tool_calls = response_message.tool_calls

    # 2. Check if the LLM wants to use a tool.
    if tool_calls:
        messages.append(response_message) # Append assistant's reply

        # 3. Execute the tool and get the real-world data.
        for tool_call in tool_calls:
            function_name = tool_call.function.name
            if function_name == "get_rooms_and_availability":
                function_args = json.loads(tool_call.function.arguments)
                # Query the local room database
                function_response = get_rooms_and_availability(
                    date=function_args.get("date"),
                    time_str=function_args.get("time"),
                    duration_min=function_args.get("duration_min"),
                )
                messages.append({
                    "tool_call_id": tool_call.id,
                    "role": "tool",
                    "name": function_name,
                    "content": json.dumps(function_response),
                })

        # 4. Second LLM call with the tool's output to get a final choice.
        second_response = client.chat.completions.create(
            model="gpt-5-mini",
            messages=messages,
        )
        final_choice = second_response.choices[0].message.content
    else:
        final_choice = response_message.content

    # 5. Grade the final choice to get a reward.
    reward = grade_the_choice(final_choice, task["expected_choice"])
    return reward

在 Agent-lightning 中,您将此逻辑包装在带有 @rollout 装饰器的 Python 函数中,以便 Agent-lightning 的运行程序和训练器可以管理和调整 Agent。算法调整的 prompt_template 作为参数传递。

import agentlightning as agl

@agl.rollout
def room_selector(task: RoomSelectionTask, prompt_template: agl.PromptTemplate) -> float:
    # ... agent logic using the prompt_template ...

    # The final reward is determined by a grader function
    reward = room_selection_grader(client, final_message, task["expected_choice"])
    return reward

核心概念:任务、Rollout、Span 和 Prompt 模板

要了解 Agent-lightning 的工作原理,您需要了解这些关键术语。

任务

任务是提供给 Agent 的特定输入或问题陈述。它定义了 Agent 需要完成什么。

类比:任务

如果 Agent 是厨师,那么任务就是食谱请求:“烘烤一个巧克力蛋糕。”

Rollout

Rollout 是 Agent 尝试解决给定 任务 的单个完整执行。这是从接收任务到生成最终结果和接收奖励的整个故事。Rollout 捕获 Agent 执行的完整跟踪。

类比:Rollout

Rollout 是厨师烘烤巧克力蛋糕的一次完整尝试,从收集配料到最终品尝测试。

Span

Span 代表 Rollout 中的单个工作单元或操作。Span 是跟踪的基础构建块。它们具有开始和结束时间,并包含有关特定操作的详细信息,例如 LLM 调用、工具执行或奖励计算。有关更精确的定义,请参阅 OpenTelemetry 文档

类比:Span

如果 Rollout 是“烘烤蛋糕”,那么 Span 可以是“预热烤箱”、“混合面粉和糖”或“添加糖霜”。每个都是一个不同的步骤或工作单元。

下图来自 ADK 显示了一个典型的 Rollout,其中瀑布视图中的每个矩形可视化一个 Span。如可视化所示,Span 可以是顺序的、并行的或嵌套的。在其他框架中,术语可能略有不同。Agent-lightning 遵循 OpenTelemetry 使用的术语以避免混淆。

AgentOps Waterfall Visualization

Prompt 模板

Prompt 模板是 Agent 的可重用指令,通常包含可以填充来自任务的特定详细信息的占位符。它是算法学习和改进随时间的 “资源” 的关键。

类比:资源(Prompt 模板)

如果任务是食谱请求,那么 Prompt 模板是厨师遵循的主食谱卡。算法的工作是编辑此食谱卡,使说明更清晰,最终菜肴更好。

训练循环:魔法发生的地方

Agent-lightning 中的训练围绕一个清晰、管理的循环,由 训练器 编排。下图说明了这种核心交互

Loop of Tasks and Spans

循环说明

  • 算法到 Agent(通过训练器): 算法(“大脑”)创建一个改进的 Prompt 模板 并选择 任务。然后,训练器将两者发送给 Agent。
  • Agent 到算法(通过训练器): 对于收到的每个任务,Agent 使用提供的 Prompt 模板执行 Rollout,执行其逻辑并可能使用工具。在此 Rollout 期间,运行 Agent 的运行程序会捕获详细的 Span,详细说明每个步骤。Agent 还计算其在任务上的性能的奖励。这些 Span 和奖励然后通过训练器发送回算法。
  • 算法学习: 然后,算法分析这些 Span 和奖励,以了解如何改进 Agent 的行为,例如通过生成更好的 Prompt。然后,改进的 Prompt 在下一次迭代的任务中使用。

此循环继续进行,允许 Agent 持续学习并提高解决任务的能力。

注意

在下一个教程中,我们将看到这里的“通过训练器”并不准确。实际上是通过运行程序和存储。

算法

算法是驱动改进的智能部分。在本教程中,我们使用 APO(自动 Prompt 优化)。它分几个步骤工作

  1. 评估: 算法首先要求运行 Rollout 使用当前的 Prompt 模板来查看其表现如何。
  2. 评论: 然后,它查看来自这些 Rollout 的详细 Span。使用强大的 LLM(gpt-5-mini),它生成“文本梯度”,这是一种对 Prompt 的自然语言评论。例如:“Prompt 在处理房间平局的 tie-breakers 时含糊不清。”
  3. 重写: 最后,它将评论和原始 Prompt 提供给另一个 LLM(gpt-4.1-mini),并要求它应用编辑,生成一个新的改进的 Prompt 模板。

此循环重复进行,每一轮都会产生一个略好的 Prompt。要使用它,只需使用所需的超参数初始化 APO 类即可。

# In the main training script: run_apo.py
from openai import AsyncOpenAI

openai = AsyncOpenAI()
algo = agl.APO(openai)

提示

确保您已在环境变量中设置 OPENAI_API_KEY

训练器

训练器是您将与之交互的中心组件。它连接所有内容并管理整个工作流程,通过运行上述循环。您配置训练器,提供算法、并行运行程序的数量和初始 Prompt。只需调用 trainer.fit() 即可启动整个过程!

# 1. Configure the Trainer with the algorithm and initial prompt
trainer = agl.Trainer(
    algorithm=algo,
    n_runners=8, # Run 8 agents in parallel to try out the prompts
    initial_resources={
        # The initial prompt template to be tuned
        "prompt_template": prompt_template_baseline()
    },
    # This is used to convert the span data into a message format consumable by APO algorithm
    adapter=agl.TraceToMessages(),
)

# 2. Load datasets: They can be list of task objects consumable by `room_selector`.
dataset_train, dataset_val = ...

# 3. Start the training process!
trainer.fit(
    agent=room_selector,
    train_dataset=dataset_train,
    val_dataset=dataset_val
)

提示

TraceToMessages 是一个方便的适配器,可将 Span 转换为 OpenAI 聊天消息。它需要安装 openai >= 1.100.0

训练结果

APO 算法成功地提高了 Agent 的性能。我们使用以下超参数运行示例

  • val_batch_size = 10
  • gradient_batch_size = 4
  • beam_width = 2
  • branch_factor = 2
  • beam_rounds = 2

在 29 个样本的数据集上,验证准确率稳步从 0.569(基线)提高到 0.721(第 2 轮之后)。使用 8 个运行程序进行调整大约需要 10 分钟。我们运行了两次,结果如图所示。

这证明了 Agent-lightning 可以使用几行代码有效地自动增强 Agent 的能力。