🎮 Fine-Tuning Agents with DSPy: 从零开始优化游戏智能体

在这个教程中,我们将学习如何使用 DSPy 优化一个语言模型驱动的智能体(Agent),让它在复杂的游戏任务中表现更出色。通过优化提示和微调模型权重,我们将从一个基础表现的智能体出发,最终构建一个高效的游戏玩家。


🛠️ 安装依赖并下载数据

首先,安装最新版本的 DSPy 和所需的依赖项:

pip install -U --pre dspy
pip install -U alfworld==0.3.5 multiprocess
alfworld-download

推荐设置 MLflow 来追踪优化进程并可视化结果:

pip install mlflow>=2.20
mlflow ui --port 5000

在代码中连接 MLflow:

import mlflow
mlflow.set_tracking_uri("http://localhost:5000")
mlflow.set_experiment("DSPy")
mlflow.dspy.autolog()

🤖 设置语言模型

我们将使用两个模型:

  • GPT-4o:用于提示优化和生成高质量示例。
  • GPT-4o-mini:一个更小的模型,经过微调后将成为最终的智能体。
import dspy

gpt4o_mini = dspy.LM('gpt-4o-mini-2024-07-18')
gpt4o = dspy.LM('openai/gpt-4o')
dspy.configure(experimental=True)

加载 AlfWorld 数据集(一个家庭模拟任务数据集):

from dspy.datasets.alfworld import AlfWorld

alfworld = AlfWorld()
trainset, devset = alfworld.trainset[:200], alfworld.devset[-200:]
len(trainset), len(devset)

🧑‍💻 定义智能体程序

智能体的核心是一个简单的 DSPy 模块,名为 Agent。它包含一个子模块 self.react,用于根据任务、轨迹和可能的动作生成下一步行动。

class Agent(dspy.Module):
    def __init__(self, max_iters=50, verbose=False):
        self.max_iters = max_iters
        self.verbose = verbose
        self.react = dspy.Predict("task, trajectory, possible_actions: list[str] -> action")

    def forward(self, idx):
        with alfworld.POOL.session() as env:
            trajectory = []
            task, info = env.init(idx)
            if self.verbose:
                print(f"Task: {task}")

            for _ in range(self.max_iters):
                trajectory_ = "\n".join(trajectory)
                possible_actions = info["admissible_commands"][0] + ["think: ${...thoughts...}"]
                prediction = self.react(task=task, trajectory=trajectory_, possible_actions=possible_actions)
                trajectory.append(f"> {prediction.action}")

                if prediction.action.startswith("think:"):
                    trajectory.append("OK.")
                    continue

                obs, reward, done, info = env.step(prediction.action)
                obs, reward, done = obs[0], reward[0], done[0]
                trajectory.append(obs)

                if self.verbose:
                    print("\n".join(trajectory[-2:]))

                if done:
                    break

        assert reward == int(info["won"][0]), (reward, info["won"][0])
        return dspy.Prediction(trajecotry=trajectory, success=reward)

🧪 零样本评估(Zero-Shot Evaluation)

在未优化的情况下,直接测试智能体的表现:

agent_4o = Agent()
agent_4o.set_lm(gpt4o)
agent_4o.verbose = True

example = trainset[0]
agent_4o(**example.inputs())

通过评估整个开发集的表现,查看平均成功率:

metric = lambda x, y, trace=None: y.success
evaluate = dspy.Evaluate(devset=devset, metric=metric, display_progress=True, num_threads=16)

agent_4o.verbose = False
evaluate(agent_4o)

结果显示:

  • GPT-4o:约 57.5% 的成功率。
  • GPT-4o-mini:仅 15% 的成功率。

提示优化(Prompt Optimization)

我们将使用 MIPROv2 优化器对 GPT-4o 的提示进行轻量级优化:

optimizer = dspy.MIPROv2(metric=metric, auto="light", num_threads=16, prompt_model=gpt4o)

config = dict(max_bootstrapped_demos=1, max_labeled_demos=0, minibatch_size=40)
optimized_4o = optimizer.compile(agent_4o, trainset=trainset, **config, requires_permission_to_run=False)

🔧 微调 GPT-4o-mini

接下来,我们将使用优化后的 GPT-4o 作为教师模型,微调 GPT-4o-mini:

student_4o_mini = optimized_4o.deepcopy()
student_4o_mini.set_lm(gpt4o_mini)

optimizer = dspy.BootstrapFinetune(metric=metric, num_threads=16)
finetuned_4o_mini = optimizer.compile(student_4o_mini, teacher=optimized_4o, trainset=trainset)

📊 评估微调后的智能体

微调后,GPT-4o-mini 的成功率显著提升:

evaluate(finetuned_4o_mini)

结果显示成功率达到 71.5%,如果使用更多训练数据(如 500 个任务),成功率甚至可以提升到 82%


💾 保存和加载优化后的智能体

将优化后的智能体保存到文件中:

finetuned_4o_mini.save('finetuned_4o_mini_001.pkl')

稍后可以通过以下方式加载并使用:

loaded = Agent()
loaded.load('finetuned_4o_mini_001.pkl')

🚀 总结

通过 DSPy 的提示优化和微调技术,我们成功将一个基础的 GPT-4o-mini 智能体从 15% 的成功率提升到超过 70%。这种方法不仅高效,还能充分利用小数据集的潜力,为复杂任务提供强大的解决方案。

准备好让你的智能体更智能了吗?快试试 DSPy 吧!🎉

发表评论

人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 知差(chai)网 🐾 DeepracticeX 社区 🐾 老薛主机 🐾 智柴论坛 🐾