从零到一:从头构建一个自主且开放的数据科学家智能体

本文信息来源:together

摘要:这篇博客文章展示了如何使用 Together 的开源模型和 Together Code Interpreter 从零开始构建一个高效的数据科学家代理。虽然实现过程相对简单,但我们的代理在多个不同的用例和基准测试中表现出色。 我们已在 GitHub 上开源了代码库 

引言

数据科学的日常工作要求我们从杂乱、不完整的信息中筛选出可执行的洞察。这通常是一个需要多个步骤的过程,从数据清洗到模型训练再到数据分析。考虑到大型语言模型能力的爆炸式提升,自然而然会让人开始思考如何利用现成的开源技术作为基础,构建能够高效处理和分析数据的智能体。

虽然人类数据科学家仍需处于这些流程的核心位置,但 AI 智能体可以帮助分担部分工作量,减轻分析任务的负担。

今天,我们将展示如何实现一个简单而高效的数据科学家智能体,它能够解决数据科学任务。该智能体的实现将是端到端的,从流程设计到实现再到测试。我们将使用 Together Cloud 上可访问的模型和工具来完成这一过程,使得这一开发过程出乎意料地易于实现。我们今天分享的这个数据科学“配方”可以扩展到其他场景中的其他智能体。

具体来说,我们将遵循 ReAct(Yao 等人,2023)模式:代理会先“思考”,然后再“行动”。代理生成的每个动作都是一段 Python 代码片段(例如,import pandas as pd; pd.read_csv(...))。这受到 smolagents 包的强烈启发,而 smolagents 又受 CodeAct(Wang 等人,2024)以及最初的 ReAct 论文的启发。

一个用于配置和启动 DeepSeek V3 在 ESOL 数据集上运行自动化分析的 CLI 界面。

开放数据科学家的操作必须被执行。虽然从概念上看这是一个“简单”的步骤,但在实践中却并非如此: 代码执行本质上是一种非常不安全的操作 ;尤其是在语言模型的背景下,你并不知道语言模型生成的代码会是什么样子。为了解决这个问题,并安全高效地运行代码,我们将使用 Together Code Interpreter(TCI)。TCI 优雅地抽象了沙盒化 Python 执行的复杂性,提供了一个简洁的 API,能够接收代码并返回结构化结果。这一架构选择对我们的智能体设计有着重要影响——它使系统天然具备模块化和可维护性。由于代码执行层与推理逻辑完全解耦,我们可以在不触碰执行基础设施的情况下修改提示词、调整 ReAct 模式,或添加新的分析能力。智能体的行为可以仅通过提示词工程进行高度调节,而 TCI 则确保无论生成的 Python 代码多么复杂,都能实现一致、可靠的执行。

在实现代理之后,我们将通过提供其性能的定量和定性结果来重点进行评估。我们还将讨论一些从零开始构建代理的最佳实践。

我们的数据科学家代理实现是一个透明的示例,用于理解如何使用开源模型和 TCI 来构建代理并评估代理流程。由于整个解决方案只需一个 API 密钥即可通过 Together Cloud 功能组合完成,这篇博客文章对于想要了解构建以推理为驱动的 AI 助手基础知识的人来说,是一个很好的参考。

为什么要从零开始构建代理?

这是个好问题!考虑到现有的众多框架,人们可能不需要深入到更底层的实现。然而,在代理模型的语境下,了解底层抽象层面的工作原理实际上是有益的。

观察语言模型与外部世界交互所需采取的步骤,有助于更好地理解代理是如何解决问题的,以及如何改进通用代理架构。尤其是在构建代理架构的过程中,会遇到许多边缘情况。事实上,另一个有趣的特性是,我们将在这里构建的 Open Data Scientist 代理是“可破解的”,并且可以适应不同的使用场景。

一名 CodeAct 数据科学家

ReAct

ReAct 框架由 Yao 等人在 2023 年提出,用于改进语言代理。ReAct 框架的理念正如其名称所示:推理(Reasoning)与行动(Action)。代理的活动通过以下循环步骤展开:代理接收到一个目标,对下一步可能的行动进行推理,然后准备执行该动作所需的输入(随后执行该动作)。每个动作都会从环境中生成一个观察结果,该结果作为下一次 ReAct 步骤的新信息来源。

为澄清起见,代理完全通过文本生成来运行。当我们说代理“对任务进行推理”时,我们的意思是它会输出自然语言,阐述其逐步的思考过程。当我们说代理“准备下一步动作”时,我们的意思是它会生成结构化文本,指定要调用的函数以及使用的参数。推理和动作准备本质上都是文本生成任务,使代理能够与外部工具和环境进行交互。

这在实践中意味着什么?在我们的“系统提示”中,我们首先要求语言模型写出其推理过程,然后再指定一个实际的动作。

为什么要让智能体进行推理?

让智能体进行推理的灵感来源于链式思维(chain-of-thought)方法,该方法表明语言模型在“将问题思考过程说出来”时会受益。这本质上是执行前的准备步骤:

  • 原因:智能体会生成其推理过程的描述
  • 行动:智能体会设计要执行的动作
  • 观察:环境将信息返回给智能体

考虑一个任务是回答“纽约的天气怎么样?”的智能体。过程可能如下展开:语言模型会推理出“我需要使用天气 API 工具来查询纽约的天气”,然后构造函数调用 weather(“NYC”)。实际上,整个过程可以在语言模型的一次生成中完成,在提示下先进行思考,然后生成所谓的工具调用。

一旦语言模型生成了文本,我们就可以提取这个动作并执行它。我们收集该动作的输出(称为观察),并将其添加到模型的上下文中。然后,我们从语言模型中采样更多的标记,此时模型已经受到额外观察信息的影响,能够为上述问题提供答案。1

CodeAct

构建 ReAct 流程有几种不同的方法。Open Data Scientist 将遵循 CodeAct 格式,并要求模型将所有操作输出为 Python 代码。这种方法有一些优点和缺点,但总体来说,它是一种非常灵活的方式来让代理设计操作:代理可以表达比简单工具调用更复杂的操作,因为在实践中,它可以在几行 Python 代码中组合多个操作。2

在每一步中,我们的 CodeAct 代理内部的语言模型将执行两种可能的操作之一:1)生成一个思考,然后生成 Python 代码作为操作;或 2)生成一个思考并输出给用户的最终答案。以下是一个示例:

一旦我们收到来自代理的响应,我们会检查内容,并通过查找以 “Thought” 和 “Action” 开头的句子来提取操作,从而识别代理打算执行的内容。这简化了我们的循环并使其非常高效。我们将 Action 发送到环境中,一旦获得结果,就将其添加回 LLM 的聊天上下文中,以便代理知道发生了什么。

Together Code Interpreter

注意:TCI 允许你在云端安全地执行代码。对于希望在本地执行代码的用户,我们还发布了一个简单(但功能非常有限)的本地代码沙箱作为替代方案。更多细节可在代码库中查看。

Together Code Interpreter 允许我们在安全的环境中运行 Python 代码,并收集我们发送的任何代码行的输出。TCI 速度快且高效。在新任务开始时,我们会分配一个代码解释器沙箱,并加载所需的文件以进行分析。TCI 会分配一个可存活 60 分钟的沙箱,可用于运行操作,就像使用 Jupyter notebook 一样。

TCI 预装了诸如 pandas、numpy、matplotlib 和 scikit-learn 等常用数据科学库,同时支持动态安装额外的软件包。例如,下面的一个示例需要安装 RDkit,这是一个用于化学信息学的库。该平台支持包括可视化在内的丰富输出类型,并在会话中跨代码执行保持持久状态。

为了简化设置,我们在代码仓库中还提供了一个简单的本地代码沙盒,方便进行测试和构建。如果你想在本地文件上运行代理,而不需要将它们上传到云端,这也非常有用。

简单而高效,并且我们让每个人都能轻松使用

为了让开源数据科学家更加易于使用,我们开发了一个命令行工具供用户试用。

Open Data Scientist 代理可以通过一条命令行调用来触发:

open-data-scientist –executor tci --write-report

下面是由我们的命令行工具生成的一个示例报告,任务是预测分子的溶解度(cheminformatics 任务):

(任务:“使用给定数据集构建一个机器学习模型来预测分子溶解度,并分析模型性能”)

在这个例子中,数据科学家代理会探索用户提供的数据,检查开发环境并安装缺失的包,然后开发一个简单的机器学习模型,接着进行结果可视化和报告撰写步骤。所有这些过程都是全自动的,并且只需一个 Together API Key 和一个终端即可实现。更多细节可在我们的代码库中找到。我们在接下来的部分提供了更多分析和评估结果。

有趣的推理模式

我们的开放数据科学家展现出有趣的自我纠正模式。请注意,“Result”框中的内容是由环境生成的,而不是由模型生成的。框中的内容会被添加到模型的上下文中,用于生成下一步的动作。

1. 例如,当尝试使用 BERT 分词器处理数据时,很快会发现数据集的标记长度超过了模型的标记限制。因此,它会实施一个替代方案。

智能体初始化一个 BERT 分词器,对文本输入进行预处理,并因序列过长而遇到错误——从而触发动态截断。

2. 同样地,当使用 Sklearn 的线性模型之一时,警告信息会告知智能体其训练的模型尚未收敛,因此智能体决定通过增加迭代次数重新训练模型以解决问题。

训练过程中出现的收敛警告突出了需要调整超参数并简化输入特征。

3. 最后,模型还会探索数据,并尝试寻找更优的策略来解决问题。

在构建模型之前,代理会检查类别不平衡情况,并查看有毒和无毒评论的示例。

评估数据科学家代理

我们从 OpenAI 的 MLE-bench(Chan 等,2024)中提取了两个文本任务,作为真实世界数据科学任务的示例。随后,我们使用了 DABStep(Data Agent Benchmark for Multi-step Reasoning,Iglesias 等,2025)基准测试。我们所有的实验均使用 DeepSeek-V3 作为后端模型运行。我们在代码库中发布了从模型获得的输出文件。

Kaggle

我们从 OpenAI MLE-bench Lite 中选择了两个任务,即 Spooky Author Identification 和 Jigsaw Toxic Comment 挑战。这些任务易于复现,并且不需要下载数 GB 的数据。我们对这两个基准测试的兴趣主要在于观察代理是否能够端到端地完成整个 Kaggle 任务。我们保持问题提示非常高层次,不提及挑战的具体内容;我们只是将代理指向目录,并指示它解决该挑战(这意味着首先要打开 readme 并理解任务)。

在面对这些任务时,智能体能够端到端地完成任务。这意味着:查看指令、加载数据、进行一些初步的预处理、训练一些 sklearn 模型并运行它们。智能体会保存一个提交文件,然后可以用该文件在排行榜上评估智能体的表现。两次提交都提供了合理的结果,但距离最高分还有差距。这通常是因为智能体采用的技术适合作为初步尝试,但不足以获得更好的结果。

有趣的是,当被要求使用更现代的技术(如句子嵌入,甚至微调 BERT 模型)时,智能体能够成功地运用这些技术,并实现评估流程来验证,例如微调是否成功。这意味着指导智能体使用哪些方法仍然非常重要。

DABstep

DABstep 是由 Adyen 和 Hugging Face 开发的一个综合性基准,用于评估 AI 智能体在真实世界数据分析任务中的能力。它包含了 450 多个源自实际业务工作负载的数据分析挑战,测试 AI 系统在结构化和非结构化数据上的表现,并要求它们在多种分析场景中执行多步推理。这个基准特别有用的一点在于它几乎不需要复杂的设置:我们可以通过 Huggingface 下载问题和数据集文件;智能体只需访问一组有限(但全面)的文件即可回答所有问题。

该基准测试专门用于评估语言模型和 AI 智能体在处理需要顺序解决问题而非一次性解决方案的复杂数据任务时的能力。

特别是,DABstep 假设智能体会阅读包含非常具体定义的文档,这些定义说明了如何解释某些术语(例如,计算“fees”需要使用特定公式,如果不阅读文档,智能体永远无法得出正确答案)。因此,我们将问题提示设计得与挑战高度相关,迫使智能体阅读所有文档,并在回答时考虑重要细节。当前的性能指标显示仍有显著的改进空间,即使是最先进的基于推理的智能体,在该基准测试中的准确率也很低。

DeepSeek V3 在简单任务的准确率上优于其他智能体,并在更困难的任务中保持了有竞争力的表现。

从结果来看,我们发现该智能体在基准测试中的简单问题上表现出色。目前,该智能体在验证排行榜的简单任务中获得了最高分(参见我们的提交文件 )。在困难问题上,它的表现可与其他非常强大的基线模型相媲美,例如 Claude4 和 GPT4.1 ReAct 智能体,并且优于 Gemini Data Science Agent!对于一个简单的智能体来说,这已经是相当不错的成绩,尤其考虑到这是最优秀的开源提交之一!

并不是所有问题都能被正确解决!在某些情况下,我们发现智能体会混淆部分指令,并将 Python 代码作为最终答案输出(你可以查看实际结果来了解发生了什么)。这可能可以通过进一步优化提示词,或调整我们提取最终答案的方式来解决。

结语

构建一个高效的数据科学家智能体比预想的更容易。借助开源模型、ReAct 框架以及 Together Code Interpreter,我们的简单但高效的实现,在 DABStep 等基准测试中取得了具有竞争力的表现。

尽管该代理在控制和用户交互方面存在一定限制,但它展示了推理型代理所需的基本模式,这些代理能够利用现成的工具处理复杂的、多步骤的数据科学任务。

你需要什么来构建优秀的智能体?

从基础开始。 优秀的提示词可以在过程中带你走得很远。比如,在 DABStep 的场景中,非常重要的一点是要告诉模型在采取任何其他步骤之前 ,先审阅实际文档并仔细阅读。只需在提示词中添加一句简单的话,就能显著提升模型的能力。

智能体可以理解你想要的解决方案,但它们不知道该采取哪条路径才能到达目标。 在解决 Kaggle 问题时,智能体总是假设使用 sklearn 的 TFIDF 向量化器就足以解决问题。这并没有错,但在 2025 年,这很可能是一个次优解。当提示它使用 sentence-transformers 或微调 BERT 时,模型会沿着更“现代”的路径去寻找问题的答案。对智能体的指令越具体,就越有助于找到正确的路径。

稳健的执行环境比你想象的更重要。 你的智能体需要一个可靠的代码解释器,能够处理依赖关系、在多个步骤之间管理状态,并能从错误中优雅地恢复。我们发现 Together Code Interpreter 尤其高效,因为它能在执行步骤之间保持上下文,并提供清晰的错误反馈。TCI 还允许我们开启多个相互独立运行的会话,使其成为并行工作流的理想工具。

为迭代而设计,而不是为完美而设计。 最好的智能体并不是第一次尝试就能把一切做对的,而是能够调试并自我纠正错误的。构建明确的错误处理模式,并教会你的智能体批判性地审视自己的输出(需要注意的是,虽然这可能无法让智能体解决所有问题,但正如我们在上面的示例中看到的,这仍然是一个相当不错的机制)。

测试,测试,测试。 在构建智能体时,对提示词或框架逻辑的任何修改都可能以意想不到的方式破坏现有功能。为每个组件编写全面的单元测试——提示词的不同变体、工具调用模式、错误恢复流程。我们是通过惨痛的教训学到这一点的:一次小小的提示词修改虽然提升了某个任务的性能,却完全破坏了智能体在文件夹中定位文件的能力。自动化测试可以在问题进入最终阶段之前捕捉到这些回归错误。

保持人在环路中而不打断流程。 理想的状态是智能体能够在定义明确的任务上独立工作,但也知道何时需要寻求澄清。你可能会发现,构建清晰的交接点很有用,让智能体在做出重大决策前展示其推理过程并请求验证。

局限性

对智能体的行为没有真正的控制,而且——从纯工程的角度来看——日志记录过少,无法使其成为一个可靠的工具或应用。数据科学过程应当允许智能体与用户之间进行交互,以便快速修正解释错误。

致谢

我们非常感谢 HF Smolagents 软件包,它为本次发布提供了灵感来源。同时,我们也非常感谢 Adyen 为我们提供了一个易于使用且对用户端几乎无需额外搭建的基准测试。

参考文献

Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K., & Cao, Y. (2023). ReAct: 在语言模型中协同推理与行动。 国际学习表征会议(ICLR)论文集 

Wang, X., Chen, Y., Yuan, L., Zhang, Y., Li, Y., Peng, H., 和 Ji, H. (2024)。可执行代码操作可引发更优的 LLM 智能体。 国际机器学习会议(ICML)论文集 

Chan, J.S., Chowdhury, N., Jaffe, O., Aung, J., Sherburn, D., Mays, E., Starace, G., Liu, K., Maksin, L., Patwardhan, T., Weng, L., 和 Mkadry, A. (2024)。MLE-bench:在机器学习工程中评估机器学习智能体。ArXiv, abs/2410.07095

Iglesias, M., Egg, A., 和 Kingma, F. (2025 年 2 月)。多步推理数据智能体基准(🕺DABstep)。Adyen https://www.adyen.com/knowledge-hub/data-agent-benchmark-for-multi-step-reasoning-dabstep

1实现这种模式有几种不同的方法。例如,在 smolagents 中,tokens 会被持续流式传输,直到遇到代码标签为止。而 Qwen-Agent 则使用更标准的工具调用方式。

2 事实上,人们也可以通过添加 Python 函数 find_weahter_in 的形式为代理添加工具。这实际上就是驱动 smolagents 背后代理的方式。

了解 RecodeX 的更多信息

立即订阅以继续阅读并访问完整档案。

继续阅读