基于CrewAI与Ollama的自动化高质量数据集构建实战
1. 项目概述从零到千条数据集的自动化构建之旅最近在做一个需要大量高质量、结构化文本数据的实验项目手头的数据要么质量参差不齐要么格式不统一清洗和标注的工作量巨大。我就在想能不能让AI自己来生成一个符合我特定需求的、干净的数据集这个想法催生了这次为期72小时、产出1065条高质量数据条目的自动化实验。整个系统的核心是让两个开源的AI框架——CrewAI和Ollama——协同工作模拟一个从“需求理解”到“数据生成”再到“质量校验”的完整数据生产线。简单来说CrewAI在这里扮演了“项目经理”和“质检员”的角色它负责规划任务、协调不同的AI智能体Agent并确保最终输出的质量。而Ollama则是我本地运行的“专家工人”它提供了强大的开源大语言模型如Llama 3、Mistral等负责执行具体的文本生成、格式转换和逻辑判断任务。整个流程完全自动化无需人工干预最终生成的数据集不仅数量可观而且在一致性和准确性上远超手动收集或简单脚本爬取的结果。这套方法特别适合需要定制化数据的研究者、开发者或者任何想快速构建高质量数据原型进行模型微调、算法测试的人。2. 核心架构与工具选型解析2.1 为什么是CrewAI Ollama组合选择这个技术栈是基于几个核心考量成本可控、流程可定制、数据隐私安全。市面上当然有现成的数据生成API但它们通常按调用次数收费生成上千条高质量数据的成本不菲且对于数据格式和内容的控制粒度不够细。而CrewAI和Ollama都是开源框架部署在本地或自己的服务器上除了电费和硬件成本几乎没有额外支出。CrewAI的本质是一个多智能体协作框架。你可以把它想象成一个虚拟的办公室里面坐着不同职位的员工智能体。每个员工有明确的职责角色、擅长的技能工具和需要遵循的工作准则目标。CrewAI的“任务”Task系统就是工作清单它定义了每个步骤要做什么、由谁来做、输出的标准是什么。而“流程”Process则规定了这些员工是依次工作顺序执行还是可以并行处理。在这个数据生成项目中我设置了至少三个核心智能体一个“需求分析师”负责解析我的初始指令并拆解成可执行的任务一个“数据生成工程师”负责调用模型生产原始数据一个“质量审核员”负责对生成的数据进行校验和过滤。Ollama则是一个让我能在本地轻松运行和管理各种开源大语言模型的工具。它解决了模型下载、环境配置、服务部署等一系列麻烦事。我只需要一条简单的命令如ollama run llama3:8b就能启动一个模型服务并通过标准的API接口进行调用。我选择在本地运行Ollama最大的好处是数据完全不出本地隐私和安全有绝对保障。同时我可以根据生成任务的特点灵活切换不同规模和能力的模型。比如对于需要较强逻辑推理的审核任务我可能会使用70B参数的大模型而对于格式相对固定的数据填充任务7B或8B参数的小模型就足以胜任速度更快。2.2 系统工作流设计整个自动化数据生成器的核心工作流是一个精心设计的闭环管道如下图所示概念图[用户输入需求] ↓ [CrewAI 需求分析智能体] - 解析需求定义数据schema、生成规则、数量 ↓ [CrewAI 任务规划] - 创建“生成”与“审核”任务链 ↓ |------------------| | | ↓ ↓ [生成任务] [审核任务](并行或顺序) (调用Ollama模型A) (调用Ollama模型B) | | |------------------| ↓ [数据聚合与格式统一] ↓ [结果输出JSON/CSV文件] ↓ [日志与性能报告]初始化与需求注入我向系统输入一个自然语言描述的需求例如“生成一个关于‘用户对智能家居设备抱怨’的数据集每条数据需要包含用户ID模拟、设备类型、具体问题描述、情感极性正面/负面/中性和严重程度等级1-5。需要1000条问题描述要多样且真实。”智能体协同解析CrewAI的“需求分析师”智能体会首先解读这个指令。它会利用Ollama提供的模型能力将模糊的需求转化为精确的、结构化的“数据生成规范书”。这份规范书会明确每个字段的定义、取值范围、生成逻辑如用户ID的生成规则、以及字段间的约束关系如“负面”情感通常对应较高严重程度。任务分解与执行根据规范书CrewAI创建两个核心任务数据生成任务和质量审核任务。这两个任务可以被设置为顺序执行先全部生成再审核或穿插执行生成一批审核一批。每个任务都绑定到特定的智能体并指定使用哪个Ollama模型。数据生产与质检流水线生成端“数据生成工程师”智能体接收任务它内部包含一个调用Ollama API的工具。它会构造详细的提示词Prompt引导模型严格按照规范书生成一条数据。提示词会包含示例few-shot learning以确保格式绝对正确。审核端“质量审核员”智能体同样调用Ollama可能是另一个更擅长推理的模型。它的提示词要求模型扮演严格的质检员检查生成的数据是否符合所有规范字段是否齐全、格式是否正确、逻辑是否自洽例如一条描述“设备完全无法开机”的抱怨其情感极性不应是“正面”。审核不通过的数据会被丢弃或打回重生成。聚合与输出通过审核的数据会被送入一个聚合模块统一转换成指定的格式如JSON Lines或CSV。系统会持续运行直到达到预设的数据条数1065条。整个过程的所有日志包括生成耗时、审核通过率、模型响应内容等都会被记录下来用于后续分析和优化。注意在实际架构中生成和审核任务之间最好有一个缓冲队列。不要让生成任务直接等待审核结果而是生成后放入队列审核任务从队列中取数据。这样可以实现松耦合提高整体吞吐量避免因为审核模型速度慢而拖累生成速度。3. 实操搭建环境配置与智能体定义3.1 本地环境与Ollama部署我的实验环境是一台配备RTX 4090显卡的工作站拥有24GB显存这让我可以流畅运行较大的模型。但即使没有高端显卡Ollama也支持纯CPU运行只是速度会慢一些。第一步安装Ollama访问Ollama官网根据你的操作系统Windows/macOS/Linux下载安装包。安装过程非常简单几乎是一键完成。安装后打开终端或命令行你就可以通过ollama命令来操作了。第二步拉取并运行模型Ollama的核心模型库Ollama Library提供了众多精选模型。对于数据生成任务我主要测试了以下几款llama3:8bMeta的最新款在指令跟随和格式输出上表现均衡速度较快是生成任务的主力。mistral:7b以高效率和不错的推理能力著称在审核任务中有时比Llama 3更“严格”。qwen2:7b在中文场景下表现优异如果你的数据需求涉及中文这是个好选择。拉取模型的命令是ollama pull 模型名例如ollama pull llama3:8b。拉取完成后使用ollama run llama3:8b就可以在交互式命令行中测试模型了。但对于我们的自动化系统我们需要它以API服务器模式运行。第三步启动Ollama API服务Ollama默认会在http://localhost:11434提供兼容OpenAI API格式的接口。确保服务已启动。你可以通过访问http://localhost:11434/api/tags来查看已下载的模型列表验证服务是否正常。3.2 构建CrewAI智能体与任务接下来是CrewAI的部分。我使用Python进行开发首先安装CrewAI包pip install crewai。定义智能体Agents智能体是系统的“员工”。每个智能体需要定义角色、目标、背景描述以及它可以使用的工具。from crewai import Agent, LLM from langchain_community.utilities import SerpAPIWrapper # 示例工具本项目未使用 from langchain_community.tools import DuckDuckGoSearchRun # 示例工具本项目未使用 # 首先定义我们连接Ollama的LLM对象 # 注意CrewAI目前可能更适配OpenAI格式我们需要配置base_url指向本地Ollama ollama_llm LLM( modelollama/llama3:8b, # CrewAI的特定格式表示使用Ollama base_urlhttp://localhost:11434, # Ollama API地址 api_keyollama, # Ollama不需要真正的key但有些框架要求非空可随意填写 temperature0.7, # 控制创造性生成任务可稍高如0.8审核任务应较低如0.1 ) # 1. 需求分析智能体 requirements_analyst Agent( role高级数据需求分析师, goal准确理解用户模糊的自然语言需求并将其转化为清晰、无歧义、可执行的结构化数据生成规范。, backstory你是一位在数据科学领域有十年经验的专家擅长与业务人员沟通并能将业务语言翻译成技术语言。你以严谨和细致著称。, llmollama_llm, # 为该智能体指定使用的模型 verboseTrue, # 输出详细思考过程便于调试 ) # 2. 数据生成智能体 data_generator Agent( role高效数据生成工程师, goal严格依据《数据生成规范》快速、多样地生成符合格式和内容要求的高质量模拟数据条目。, backstory你是一个不知疲倦的数据工厂核心引擎你的代码提示词完美无缺总能产出符合预期的结果。你痛恨格式错误和偏离要求的输出。, llmollama_llm, verboseTrue, ) # 3. 质量审核智能体 quality_inspector Agent( role苛刻的数据质量审核员, goal对每一条生成的数据进行多重校验确保其100%符合规范逻辑自洽并过滤掉低质量、重复或荒谬的条目。, backstory你曾因在金融数据审计中发现一个微小错误而避免了数百万损失。你对“差不多”零容忍眼里容不下任何沙子。, llmollama_llm, # 可以为审核员指定一个不同的模型例如 temperature0.1 的 llama3:70b verboseTrue, )定义任务Tasks任务是智能体要执行的具体工作。任务需要描述、指派给哪个智能体、以及期望的输出是什么。from crewai import Task # 任务1需求分析 analysis_task Task( description分析用户需求{user_input}。请输出一份详细的《数据生成规范》文档必须包含1. 数据集名称与描述2. 每条数据的字段定义名称、类型、示例、约束3. 数据生成的总条数4. 对生成内容多样性、真实性的具体要求5. 输出格式JSON。, agentrequirements_analyst, expected_output一份结构清晰、技术团队可直接执行的Markdown格式规范文档。, ) # 任务2数据生成 # 注意在实际循环中这个任务会被动态创建多次或者在一个任务内处理批量生成。 generation_task Task( description根据附带的《数据生成规范》生成 {batch_size} 条数据。你必须严格按照规范中的字段和格式要求输出每条数据输出为一个独立的JSON对象。确保内容多样且真实。, agentdata_generator, context[analysis_task], # 此任务依赖于分析任务的结果 expected_output一个包含 {batch_size} 个JSON对象的列表每个对象都完全符合规范。, output_filegenerated_batch.json # CrewAI支持直接输出到文件 ) # 任务3质量审核 validation_task Task( description审核文件 {input_file} 中的每一条数据。依据《数据生成规范》检查字段完整性、格式正确性、逻辑合理性。将审核结果分为‘通过’、‘修正’、‘拒绝’三类并给出简要理由。只输出‘通过’的数据。, agentquality_inspector, context[analysis_task], # 审核也需要依据规范 expected_output一个只包含‘通过’审核的数据的JSON列表文件名为 validated_{input_file}。, )3.3 编排流程与执行引擎最后我们需要一个“船长”Crew来把智能体和任务组织起来并定义他们的工作流程。from crewai import Crew, Process # 创建 Crew data_factory_crew Crew( agents[requirements_analyst, data_generator, quality_inspector], tasks[analysis_task, generation_task, validation_task], # 这里是简化示意实际生成任务会循环 processProcess.sequential, # 顺序执行分析 - 生成 - 审核。对于批量可以设计更复杂的流程。 verbose2, # 输出详细执行日志 ) # 执行Crew这是一个简化的一次性执行 # 在实际72小时运行中这里是一个复杂的循环控制逻辑 result data_factory_crew.kickoff(inputs{user_input: 生成关于智能家居设备抱怨的数据集...}) print(result)然而一次性的kickoff无法满足我们持续运行72小时、生成上千条数据的需求。我们需要自己编写外层的流程控制器。这个控制器负责接收最终的用户需求。启动需求分析任务得到规范。根据规范中的总条数如1065条决定分批策略比如每批50条。循环执行为每一批数据创建一个新的“生成任务” - 执行 - 将生成结果保存为临时文件 - 创建一个针对该临时文件的“审核任务” - 执行审核 - 将审核通过的数据追加到最终数据集文件。监控进度、处理异常如模型调用失败、记录日志。达到目标数量后停止循环生成最终报告。这个控制器是项目真正的“大脑”它用Python脚本实现利用CrewAI的API来动态创建和提交任务而不是依赖Crew的一次性编排。4. 核心挑战与优化策略实录4.1 提示词工程从“粗略”到“精确”最初的失败几乎都源于糟糕的提示词。让模型生成“一条用户抱怨”它可能会给你一段自由的、格式不定的文字。我们的目标是结构化的JSON。提示词的质量直接决定了输出数据的质量和系统的稳定性。第一版粗糙失败率高请生成一条用户对智能家居设备的抱怨。结果模型自由发挥格式千奇百怪无法解析。最终版精确通过率95%{ “instruction”: “你是一个高质量数据生成器。请严格按照以下要求生成一条数据”, “requirements”: { “fields”: [ {“name”: “user_id”, “type”: “string”, “format”: “前缀‘USER_’后接6位数字如 USER_123456”, “generation_rule”: “随机生成不重复”}, {“name”: “device_type”, “type”: “string”, “enum”: [“智能音箱”, “智能灯泡”, “智能门锁”, “智能 thermostat”, “扫地机器人”]}, {“name”: “complaint_text”, “type”: “string”, “constraints”: “长度在15到50字之间描述一个具体、真实的问题例如‘唤醒词经常识别失败’而非‘不好用’”}, {“name”: “sentiment”, “type”: “string”, “enum”: [“正面”, “负面”, “中性”], “logic_link”: “必须与complaint_text描述的问题在情感上一致”}, {“name”: “severity”, “type”: “integer”, “range”: [1, 5], “logic_link”: “通常‘负面’情感对应 severity3‘正面’对应 severity2‘中性’对应 severity3。但也允许合理例外。”} ], “output_format”: “你必须输出且仅输出一个合法的JSON对象键名与上述字段名完全一致。不要有任何额外解释。” }, “examples”: [ {“user_id”: “USER_654321”, “device_type”: “智能音箱”, “complaint_text”: “在嘈杂环境下即使大声喊唤醒词也经常没反应。”, “sentiment”: “负面”, “severity”: 4}, {“user_id”: “USER_111223”, “device_type”: “智能灯泡”, “complaint_text”: “颜色切换很平滑但预设的‘阅读模式’色温我觉得偏冷。”, “sentiment”: “中性”, “severity”: 3} ] }优化心得结构化约束使用类JSON的格式在提示词中明确字段定义、类型、枚举值、格式和逻辑关系。模型对结构化的指令理解得更好。提供示例Few-shot learning至关重要。提供1-3个完美的输出示例能极大提高模型输出的格式符合率。输出格式强制使用“你必须输出且仅输出一个合法的JSON对象”这样强硬的措辞并在审核环节严格检查逐步“训练”模型遵守规则。逻辑链接在字段定义中加入logic_link明确不同字段间的约束让模型生成的数据在逻辑上更自洽。4.2 稳定性保障错误处理与重试机制让一个系统无人值守运行72小时稳定性是首要问题。网络波动、Ollama服务内存溢出、模型响应超时或返回非预期内容都是家常便饭。我的错误处理策略指数退避重试对于网络超时或服务暂时不可用HTTP 5xx错误实现重试逻辑。第一次失败后等待1秒重试第二次失败等待2秒第三次等待4秒……最多重试5次。import time import requests from tenacity import retry, stop_after_attempt, wait_exponential retry(stopstop_after_attempt(5), waitwait_exponential(multiplier1, min1, max60)) def call_ollama_with_retry(prompt): # 调用Ollama API的代码 response requests.post(...) response.raise_for_status() # 如果状态码不是200会抛出异常触发重试 return response.json()响应内容校验即使API调用成功返回的内容也可能是无效的如模型“胡言乱语”。在将数据交给审核智能体之前先做一层语法防火墙用try-except包裹json.loads()捕获所有JSON解析错误。解析失败的数据直接丢弃或触发一次“重新生成”该条数据的任务。批次隔离与状态持久化不要一次性把所有任务扔进队列。采用“小批次”策略比如每生成和审核完20条数据就将这20条成功数据立即写入磁盘并记录当前进度。这样即使程序在运行到第50小时崩溃重启后可以从最近的检查点恢复而不是从头开始。资源监控编写一个简单的监控脚本定期检查Ollama进程的内存和CPU占用。如果发现内存持续增长可能内存泄漏则自动重启Ollama服务。同时监控生成和审核的通过率如果通过率在某一时间段内骤降可能意味着模型状态不佳或提示词出了问题系统应发出警报如记录到错误日志文件并暂停。4.3 效率提升并行化与模型分工串行执行“生成一条 - 审核一条”效率极低。我的优化方法是生成与审核并行这是最大的性能提升点。我使用Python的concurrent.futures线程池或asyncio库。维护两个队列生成队列和审核队列。启动多个“生成工作线程”不断从生成队列取任务生成N条数据完成后将数据块放入审核队列。同时启动多个“审核工作线程”从审核队列取数据块进行审核。这样生成和审核可以同时进行。模型分级调用并非所有任务都需要最强大的模型。我的配置是需求分析使用能力较强的模型如llama3:70b因为这一步需要深度理解。数据生成使用速度较快的模型如llama3:8b或mistral:7b在保证格式正确的前提下追求吞吐量。质量审核使用最严谨、推理能力最强的模型如llama3:70b或专门调优过的审核模型但可以适当降低其temperature如0.1使其判断更稳定。审核任务量通常是生成任务量的一半因为不是每条都需要复杂审核所以对整体速度影响可控。批次处理不要一次只让模型生成1条数据。通过精心设计提示词可以让模型一次生成一个包含5-10条数据的JSON数组。这能大幅减少HTTP请求和上下文切换的开销。同理审核也可以批量进行。5. 成果分析、问题排查与未来展望5.1 72小时运行成果深度分析经过72小时的不间断运行系统成功生成了1065条通过最终审核的数据条目。以下是一些关键指标和分析指标数值分析与说明总运行时间72小时并非满负荷包含了排队、重试、监控暂停等时间。原始生成条数~1250条生成器实际生产的原始数据量。最终有效条数1065条通过审核关卡的数据即最终数据集大小。审核通过率~85.2%(1065 / 1250) * 100%。这是一个健康的值说明生成质量总体可控。平均单条生成耗时~12秒从发起生成请求到获得有效JSON输出的平均时间取决于模型和批次大小。平均单条审核耗时~8秒审核通常比生成快因为提示词更简单判断是/否。主要失败原因1. 格式错误 (60%)2. 逻辑矛盾 (25%)3. 内容重复/低质 (15%)格式错误早期多优化提示词后大幅减少。逻辑矛盾是主要难点。数据集质量评估我随机抽取了100条数据进行了人工复核。发现格式正确率100%。所有数据均为完美JSON字段齐全。逻辑自洽率约93%。有7条数据存在轻微逻辑问题例如抱怨文本是“设备完全无法连接”但情感被标记为“中性”。这提示审核模型的提示词还可以进一步强化逻辑约束。内容多样性良好。通过在设计提示词时要求“从不同角度、不同场景描述问题”并让生成器在每批任务中使用不同的随机种子有效避免了数据模式僵化。5.2 典型问题与排查记录在72小时运行中遇到了形形色色的问题以下是排查记录问题一运行到第40小时数据生成速度突然变慢最后卡住。现象日志显示Ollama API调用超时。排查登录服务器运行ollama list查看模型状态正常。但通过nvidia-smi发现GPU内存几乎占满。原因Ollama在长时间处理大量请求后可能没有完全释放缓存导致显存泄漏。解决临时写一个脚本定时重启Ollama服务例如每生成500条数据后。优化在调用Ollama API时显式地在请求头中设置keep_alive: -1或一个较短的时间告诉服务端不要长时间保留模型上下文。同时尝试使用Ollama的show命令查看模型配置调整num_ctx上下文长度参数避免设置过大。问题二审核环节误杀率突然升高。现象某一批次的数据审核通过率从85%骤降到40%。排查检查该批次生成和审核的日志。发现生成环节的提示词文件因误操作被覆盖成了一个旧版本其中缺少了关键的“输出格式”强调。原因生成数据格式变差导致即使内容合格也因格式问题被审核员拒绝。解决立即停止该批次任务恢复正确的提示词文件并让系统从上一个检查点重新生成该批次数据。教训所有配置文件、提示词模板都应纳入版本控制如Git并在每次任务启动前进行校验。问题三生成的数据出现“重复模式”。现象连续几十条数据中user_id的后几位数字呈现明显的递增规律complaint_text的句式雷同。原因LLM在缺乏随机性注入时容易陷入某种输出模式。虽然我们要求“随机”但模型对“随机”的理解可能只是基于上下文的微小变化。解决在给生成模型的系统提示词system prompt中加入“请充分发挥创造力确保每条数据在表述上都有显著差异”。在每批生成任务的用户提示词user prompt中加入一个随机种子或变化因子例如“请想象今天是2023年{random_month}月{random_day}日用户在不同时间遇到了问题”。定期如每200条轻微调整生成提示词中的示例给模型新的刺激。5.3 扩展思路与未来优化方向这次实验验证了用CrewAIOllama构建自动化数据流水线的可行性。基于此还有更多可以探索的方向引入“数据增强”智能体在生成和审核之后增加一个“数据增强”环节。这个智能体可以对通过审核的基-础数据进行变换如同义词替换、句式改写、添加无害的噪声等在不改变语义的前提下扩充数据集多样性这对于训练更鲁棒的NLP模型尤其有用。实现动态难度调整系统可以监控审核通过率。如果通过率持续高于某个阈值如90%说明生成任务太简单可以自动调高生成提示词的难度例如要求生成更复杂、更边缘的案例。反之则调低难度保证产出效率。与向量数据库结合将已生成的数据实时存入向量数据库如Chroma、Weaviate。在生成新数据前先进行向量相似度检索如果发现与已有数据过于相似则要求生成器重新生成或修改。这能从根源上降低数据重复率。多模态数据生成Ollama也开始支持一些多模态模型。这套架构可以扩展例如让一个智能体生成描述图片的文本提示词另一个智能体调用文生图模型如Stable Diffusion生成图片第三个智能体审核图文匹配度从而构建图文对数据集。构建这个系统的过程更像是在设计和运营一个数字工厂。每一个智能体是一个工位提示词是操作手册任务流是生产线而Ollama提供的模型则是生产设备。调试的过程就是优化生产线、培训员工、维护设备。当这个工厂能够稳定、高效地生产出符合标准的产品时那种成就感远超手动收集数据。它解放了我的双手让我可以去思考更本质的问题我到底需要什么样的数据以及如何设计更好的“工厂蓝图”。