用开源模型和代码解释器构建数据科学家智能体

这篇博客展示了如何用 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 模式或添加新的分析能力,而无需触及执行基础设施。智能体的行为变得可以通过提示工程(Prompt Engineering)高度调优,而 TCI 确保无论生成的 Python 代码多复杂,都能一致、可靠地执行。
实现智能体后,我们将专注于评估,提供关于其性能的定量和定性结果。我们将讨论一些关于如何从头开始构建智能体的最佳实践。
我们的数据科学家智能体实现作为一个透明示例,帮助理解如何使用开源模型和 TCI 构建智能体并评估智能体流水线。由于整个解决方案只需一个 API 密钥就能使用 Together Cloud 功能组合而成,这篇博客是那些希望理解构建推理驱动 AI 助手基础知识的良好参考。
为什么从头构建智能体?
这是个好问题!考虑到现有的框架数量,可能不需要深入底层实现。然而,在智能体模型的背景下,了解事物在较低抽象层次上的工作原理实际上是有益的。
观察语言模型必须采取的步骤来与外部世界交互,有助于更好地理解智能体如何解决问题以及如何改进通用智能体架构。更重要的是,考虑到在构建智能体架构过程中会遇到多少边缘情况。确实,另一个有趣的特点是,我们将要构建的开放数据科学家智能体是“可黑客化”的,并且可以适应不同的用例。
一个 CodeAct 数据科学家
ReAct
ReAct 框架由 Yao 等人于 2023 年提出,旨在改进语言智能体。ReAct 框架背后的思想体现在其名称中:推理(Reasoning)和行动(Action)。智能体的活动使用以下循环步骤展开:智能体被赋予一个目标,推理下一步可能是什么,然后准备动作的输入(随后执行)。每个动作都会从环境中生成一个观察结果,用作下一个 ReAct 步骤的新信息来源。
澄清一下,智能体完全通过文本生成来操作。当我们说智能体“推理任务”时,意味着它输出自然语言,阐述其逐步思考过程。当我们说智能体“准备下一个动作”时,意味着它生成结构化文本,指定调用哪个函数以及使用什么参数。推理和动作准备本质上都是文本生成任务,使智能体能够与外部工具和环境交互。
这在实践中意味着什么?在我们的“系统提示”中,我们要求语言模型先写下其推理,然后指定一个实际动作。
为什么让智能体推理?
让智能体推理受到思维链(Chain-of-Thought)方法的启发,这些方法显示语言模型从“大声思考问题”中受益。这本质上是在行动之前的准备步骤:
- 推理:智能体发展其推理的描述
- 行动:智能体设计要执行的动作
- 观察:环境返回信息给智能体
考虑一个任务为回答“纽约市的天气如何?”的智能体。这可能如下展开:语言模型会推理“我需要使用天气 API 工具来查找纽约市的天气”,然后构建函数调用 weather("NYC")。实际上,整个过程可以在语言模型的单次生成中发生,它被提示先思考,然后产生所谓的工具调用(Tool Call)。
一旦语言模型生成文本,我们就可以提取这个动作并执行它。我们收集动作的输出(称为观察)并将其添加到模型的上下文中。然后我们从语言模型中采样更多 token,现在它受到额外观察上下文的影响,将能够回答上述问题。
CodeAct
有几种不同的方式可以构建 ReAct 流水线。开放数据科学家将遵循 CodeAct 格式,并要求模型将所有动作输出为 Python 代码。这种方法有一些优点和缺点,但通常是智能体设计动作的一种非常灵活的方式:智能体可以表达比简单工具调用(Tool Calling)可能更复杂的操作,因为它实际上可以在几行 Python 代码中组合多个操作。
在每个步骤中,我们 CodeAct 智能体中的语言模型将执行两种可能的动作:1)生成一个思考(Thought)然后以 Python 代码作为动作,或 2)生成一个思考然后为用户输出最终答案。这是一个例子:

一旦我们从智能体收到响应,我们将检查内容并通过查找以“Thought”和“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 –executor tci --write-report
下面是由我们的命令行工具生成的报告示例,提供了一个预测分子溶解度的化学信息学任务:


(任务:“使用给定数据集构建一个机器学习模型来预测分子溶解度,并分析模型性能”)
在这个例子中,数据科学家智能体探索用户提供的数据,检查开发环境并安装缺失的包,然后开发一个简单的机器学习模型,接着是结果可视化和报告编写步骤。所有这些都完全自动化,只需一个 Together API 密钥和一个终端即可实现。更多细节可以在我们的代码库中找到。我们将在下一节提供更多分析和评估结果。
有趣的推理模式
我们的开放数据科学家智能体展现出一些有意思的自我纠错模式。需要说明的是,下方“结果”框中的内容是由执行环境生成的,而非模型直接输出。这些内容会被添加到模型的上下文(Context Window)中,用于生成下一个动作。
- 例如,当尝试使用 BERT 分词器处理数据时,智能体很快发现数据集的序列长度超过了模型的限制。于是,它转而执行了备选方案。

智能体初始化 BERT 分词器,预处理文本输入,但因序列过长遇到错误——这促使它动态地进行截断处理。
- 类似地,在使用 Sklearn 的某个线性模型时,警告信息提示智能体,它训练的模型尚未收敛。于是,智能体决定增加迭代次数重新训练模型来解决问题。

训练过程中的收敛警告凸显了调整超参数和简化输入特征的必要性。
- 最后,模型还会主动探索数据,尝试寻找更好的问题解决策略。

在构建模型之前,智能体会检查类别是否均衡,并查看有毒和无毒评论的示例。
评估数据科学家智能体
我们从 OpenAI 的 MLE-bench 中选取了两个文本任务作为真实世界数据科学任务的示例,然后使用 DABStep 基准进行测试。所有实验均以 DeepSeek-V3 作为后端模型运行。我们将模型生成的输出文件发布在了仓库中。
Kaggle 任务
我们从 OpenAI MLE-bench Lite 中选择了两个任务:Spooky Author Identification 和 Jigsaw Toxic Comment 挑战。这些任务易于复现,且无需下载海量数据。我们关注这两个基准测试,主要是想看看智能体能否端到端地解决整个 Kaggle 任务。我们给出的问题提示非常宽泛,不提及挑战的具体内容;只是引导智能体到指定目录,并指示它解决挑战(这意味着它需要先阅读 README 文件来理解任务)。
面对这些任务时,智能体能够端到端地完成整个流程。具体包括:查看说明、加载数据、进行初步预处理、训练一些 Sklearn 模型并运行它们。智能体会保存一个提交文件,可用于在排行榜上评估其性能。两个提交都给出了合理的结果,但距离顶尖分数还很远。这通常是因为智能体采用的技术对于初次尝试来说不错,但不足以获得更好的结果。
有趣的是,当被要求使用更现代的技术(如句子嵌入甚至微调 BERT 模型)时,智能体也能成功运用这些技术,并实现评估流程来验证(例如)微调是否成功。这意味着,指导智能体使用什么工具仍然非常重要。
DABstep 基准
DABstep 是由 Adyen 和 Hugging Face 开发的一个综合性基准,用于评估 AI 智能体在真实世界数据分析任务中的能力。它包含超过 450 个源自实际业务负载的数据分析挑战,测试 AI 系统在结构化和非结构化数据上的表现,要求它们在不同分析场景中进行多步推理。
这个基准特别有用的一点在于,它几乎无需设置:我们可以通过 Huggingface 下载问题和数据集文件;智能体只需访问一组有限但全面的文件即可回答所有问题。
该基准专门用于评估语言模型和 AI 智能体处理需要顺序问题解决的复杂数据任务的能力,而非单次解答。
具体来说,DABstep 假设智能体会阅读包含特定术语定义(例如,计算“费用”需要使用特定公式,如果不阅读文档,智能体永远无法得到正确答案)的文档。因此,我们使问题提示与挑战的领域高度相关,迫使智能体阅读所有文档,并在提供答案时思考重要细节。当前的性能指标显示,改进空间很大,即使是最先进的基于推理的智能体,在该基准上的准确率也很低。

DeepSeek V3 在简单任务上的准确率优于其他智能体,在较难任务上也保持了有竞争力的结果。
从结果来看,智能体擅长解决基准中的简单问题。目前,在已验证的排行榜上,我们的智能体在简单任务上得分最高(可查看我们的提交文件)。对于难题,它的表现与 Claude4 和 GPT4.1 ReAct 智能体等非常强大的基线模型相当,并且优于 Gemini 数据科学智能体!对于一个简单的智能体来说,这是个相当不错的结果,考虑到这也是最好的开源提交之一!
当然,并非所有问题都能正确解决!在某些情况下,我们看到智能体混淆了部分指令,并将 Python 代码作为最终答案输出(你可以查看实际结果了解具体情况)。这或许可以通过进一步改进提示或改变答案提取方式来解决。
结语
构建一个有效的数据科学家智能体比预想的要容易。利用开源模型、ReAct 框架和 Together Code Interpreter,我们简单而有效的实现在 DABStep 等基准测试中取得了有竞争力的表现。
虽然这个智能体在控制和用户交互方面存在局限,但它展示了推理智能体使用现成工具处理复杂、多步骤数据科学任务所需的基本模式。
如何构建好的智能体?
从基础开始。 好的提示(Prompt)能让你走得更远。例如,在 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: Synergizing reasoning and acting in language models. Proceedings of the International Conference on Learning Representations (ICLR).
Wang, X., Chen, Y., Yuan, L., Zhang, Y., Li, Y., Peng, H., & Ji, H. (2024). Executable code actions elicit better LLM agents. Proceedings of the International Conference on Machine Learning (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: Evaluating Machine Learning Agents on Machine Learning Engineering. ArXiv, abs/2410.07095.
Iglesias, M., Egg, A., & Kingma, F. (2025, February). Data Agent Benchmark for Multi-step Reasoning (🕺DABstep). Adyen. https://www.adyen.com/knowledge-hub/data-agent-benchmark-for-multi-step-reasoning-dabstep
1 实现这种模式有几种不同的方式。例如,在 smolagents 中,令牌会持续流式输出,直到遇到代码标签。而 Qwen-Agent 则使用更标准的工具调用(Tool Calling)。
2 实际上,也可以以 Python 函数 find_weahter_in 的形式向智能体添加工具。这正是 smolagents 背后智能体的工作原理。
觉得有用?分享给更多人