拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AI Agent从零自主开发文本分类模型:一场全流程实验实录

在AI圈子里聊“AI到底能不能自己造AI”基本每次都会吵成两拨人一拨觉得这是失控前兆另一拨认为AI连自己代码该放哪个文件都搞不清楚。我不打算站队因为这种问题在没有明确操作定义之前根本没有答案。花了一个多星期我做了个完整实验让一个带规划和执行能力的AI Agent从空目录开始自己完成一个文本分类模型的全部开发流程——需求拆解、环境准备、数据脚本、模型训练、调参迭代最后产出一个真实可用的模型文件。结果比预想中更有说服力它不是摆设是真的做出来了只是过程远没有传说中那么科幻。这类实验现在不缺素材Cursor、AI Agent、AI编程相关的词在这段时间被反复刷屏但大部分讨论停留在“代码补全多强”“哪家IDE插件好用”这个层面很少有人把话筒递还给AI本身给你一个空项目、一个目标、一个能执行命令的环境你能不能从零造出一个AI应用这篇文章就把我完整的实验记录、半路翻车的过程、以及我对“AI到底能不能自己造AI”这件事的判断一次性讲清楚。1. 先把“造AI”问清楚这轮实验验证的是哪一层能力1.1 三种“造AI”的含义差得很远多数争论其实在定义层面就已经散了。我见过两种最极端的说法一种是把大模型API接进业务、写几段Prompt、套个企业微信机器人就宣称“我造了一个AI”另一种是看到能自动生成代码的Agent就惊呼“AI已经能自己造自己了”。这两种说法都不算错但压根不在同一个维度上吵起来自然各说各话。我倾向于把“造AI”分成三个层次第一种是调用现成大模型API做应用层开发。模型是别人训练好的你写的只是业务逻辑、编排逻辑、提示词和周边工程。门槛很低价值也有但这更像是“用AI”。第二种是机器学习工程意义上的造AI。从数据清洗开始设计或选用合适的模型结构完成训练、验证、调参、评估最后产出一个可以部署的模型文件。这是算法工程师的日常算是真正“制造”一个AI模型出来。第三种是研究型造AI。提出新架构、新训练范式让模型能力产生质变比如从CNN到Transformer这种级别的创新。当前没有任何工具能替代人的这种角色。这篇文章要验证的是第二种。因为自动编程工具目前最有可能替代或者放大的人是“能完成标准建模流水线的工程师”而不是论文作者。把目标定义到这个层面实验才有可验证性不需要动不动就聊到意识、失控这种大词上去。1.2 热搜里的AI编程/Cursor和我做的实验不是一回事最近大家讨论最热闹的主要是Cursor这类AI编程工具、各种AI Agent框架、还有一堆“AI编程提示词”“AI应用开发”的教程。这些都是真实有用的东西但是它们大多处于同一个阶段把大模型当作一个坐在IDE里的结对程序员你告诉它需求它补全代码你负责判断能不能跑、要不要改。这种模式确实很强但它有一个隐藏前提——人在闭环里。人类负责拆解需求人类负责验收结果人类负责把报错信息粘回去。一旦遇到环境问题、版本问题、逻辑漏洞真正做决策的还是人。所以我说句实在话单靠“AI写代码”不能证明AI能自己造AI只能证明AI是一个很好的代码生成器。我做实验的方式不一样。我让AI Agent直接面对一个真实环境它能执行Linux命令、能读写文件、能运行Python脚本然后自己判断下一步做什么。如果脚本报错它自己读报错、自己改、自己重跑不需要我再传话来传话去。整个系统里我给它的只有一个目标描述和验收标准。中间过程能不能完成完全看它自己。这样才有资格回答标题里那个问题。1.3 这轮实验验收标准是什么样的为了让结果不被“演示文件”糊弄过去我事先写死了验收要求任务做一个短信垃圾信息的二分类模型。环境Docker容器内预装Python、PyTorch、scikit-learn、pandas工作目录里放一份约850条文本的邮件数据集不加外部网络。产出必须有一个训练脚本train.py、一个推理评估脚本evaluate.py、一个模型文件model.pt、一个requirements.txt、一个README.md。指标在留出的测试集上F1值不得低于0.93脚本必须能一键复现。这里最关键的是“不加外部网络”。因为一旦允许联网很多Agent会直接去HuggingFace拉一个现成模型来微调那确实很省事但整个过程的自主性会被数据集、基座模型分享掉一大半。我要看的是在一个资源受限的环境里它能不能自己榨出方案来。至于人工干预我只做了一件事把任务书写清楚。剩下所有代码细节我不碰。我允许自己旁观、记录、给环境打补丁但不允许直接替它改代码。这是整个实验底线的核心。2. 自主开发Agent的搭建思路为什么我用LLM当主管、本地环境当手2.1 Agent的骨架能思考的循环、能执行的手、能看见反馈的眼睛先说结论整个系统写出来也就一百多行核心代码。很多人以为“让AI自主干活”得搞多复杂的框架其实关键在于把大模型放进一个能执行、能观察、能纠错的环境而不是单纯地跟它对话。我搭的系统由三部分构成大脑一个支持function calling的大模型接口。它负责理解任务、调工具、读返回结果、决定下一步动作。手Agent可以调用的工具集合包括执行shell命令、读文件、写文件、列出目录结构。每一个工具都返回真实的stdout、stderr和退出码。循环控制Agent不断向大模型发消息大模型返回要不要调工具、调哪个工具、传什么参数执行完把结果追加回上下文继续下一轮。直到大模型认为任务完成不再请求调用工具循环才结束。核心循环的代码长这样去掉了一些细节看起来像一套简化版的任务执行器while True: response client.chat.completions.create( modelMODEL_NAME, messagesmessages, toolsTOOL_SCHEMAS ) msg response.choices[0].message if not msg.tool_calls: # 不再调用工具说明Agent认为可以收尾了 print(final:, msg.content) break for call in msg.tool_calls: tool_name call.function.name tool_args json.loads(call.function.arguments) # 真实执行工具并把结果返回给模型 result dispatch_tool(tool_name, tool_args) messages.append({ role: tool, tool_call_id: call.id, content: str(result) })把大模型的API地址、模型名、系统提示词换成你自己的这个循环就能跑起来。在开始实验前我自己花了一晚上把日志、超时、结果截断补上否则后面会栽在流程控制上。比如工具输出的内容可能很长如果不限制返回给模型的字符数上下文很快就会被一大堆文件内容塞满百万Token也不够烧。2.2 为什么选择function calling而不是自由对话在大模型应用里让LLM输出自然语言来规划、再让程序解析关键词这种方案我也试过结论是极不可靠。模型会在规划里写“我先用python脚本处理数据再训练模型”但如果你真的让程序去解析这句话你会发现自己写了一个脆弱不堪的意图识别器。用function calling要稳得多。它会强制模型输出结构化的工具调用请求比如run_command、read_file这些函数名和对应参数而不是自由文本。程序拿到结构化指令后直接分发执行执行完把真实结果塞回去。整个闭环非常干净出错也容易定位。更重要的是function calling让“安全边界”有了落地的地方。我可以限制它能跑哪些命令、能访问哪些目录、不能让它在某个目录之外乱写文件。Agent在明处工具执行在暗处我能看见每一步。这比让它直接生成bash脚本然后丢给subprocess.run执行要安全很多。2.3 任务书的写法决定了一半的成败我给Agent的任务书不是简单一句话“帮我做个分类器”而是完整写清楚了五类信息角色和背景你是一个机器学习工程师现在要在/workspace目录里完成一个文本分类模型。数据和环境你有哪些可用文件目录里预装了哪些包网络不可用。交付物清单明确要生成哪些文件。验收标准测试集F1大于等于0.93跑起来不能靠人工微调。运行方式每一步执行完要检查退出码如果命令失败不要重复一模一样的命令。很多人低估了第5条的作用。如果没有这句话Agent在遇到某个命令报错时会进入复读机状态把同一段代码改一个空格又跑一遍然后又跑一遍。后来我发现真正让Agent表现稳定的不是模型本身而是你在任务书里给它的约束和自我检查要求。这种“任务目标明确环境边界清楚验收标准可执行”的文件本质上就是一个工程里的需求文档。它决定了大模型在自主执行时是漫无目的地瞎转圈还是能集中火力往终点推进。3. 全流程实录从空目录到F1 0.96的文本分类模型3.1 第1~14轮探索目录、识别数据、确认基线实验开始后Agent做的第一件事是查看工作目录。它调用了几次ls -la和find找到了数据文件的位置然后主动去读文件开头检查数据格式。$ ls -la /workspace total 64 drwxr-xr-x 4 root root 4096 ... drwxr-xr-x 1 root root 4096 ... drwxr-xr-x 2 root root 4096 data -rw-r--r-- 1 root root 421 task.md $ head -5 /workspace/data/mail.tsv label text spam Congratulations! Youve been selected for a free cruise... ham Hi Mike, are we still meeting tomorrow afternoon? spam URGENT: Your account has been locked. Click here to verify... ham Dont forget to pick up milk on your way home.它花了大概五六轮去理解数据结构然后做了一件典型工程师会做的事检查标签分布是否均衡统计文本长度确认需要不需要做类别重采样。它还很自觉地写了几个shell命令统计样本量。第一版方案它选择了自己动手搭一个两层MLP词向量部分用PyTorch的EmbeddingBag这样不需要额外下载预训练词向量符合网络受限的约束。如果你让一个只会写CRUD代码的人来干这活他大概率想不到这个方案但大模型的训练语料里见过太多文本分类的做法这种方案对它来说是常见套路。3.2 第15~28轮写出第一版训练脚本并踩中第一个API坑到第15轮左右Agent开始写真正的代码了。它先写了一个prepare_data.py用pandas读取TSV文件把文本分词后转成索引序列并手动完成了训练集和测试集的划分。这个环节我没有看到任何卡顿代码一次通过。真正的问题出在它写训练脚本时。第一版训练脚本里它试图用torchtext.data.TabularDataset来加载数据。这段代码看起来有理有据——因为PyTorch生态里处理文本分类确实常用torchtext——但问题在于新版本torchtext早就把这个接口移除了。结果一跑就报错AttributeError: module torchtext.data has no attribute TabularDataset这是非常典型的大模型幻觉它见过老版本教程里这么写但环境里装的已经不是那个版本了。Agent收到报错后没有硬撑它先执行了pip show torchtext确认版本号然后立刻决定弃用torchtext改用pandas手工构造数据集。整个过程一共花了三四轮看起来就像一个有经验的开发者在版本兼容性上踩坑后快速转向。3.3 第29~44轮loss不降与自动调参的拉锯战训练脚本第一次成功跑起来之后loss值是能下降的但降得很慢三个epoch之后验证集的F1只有0.82左右离0.93的验收线差着十万八千里。Agent这时做了一件让我相当意外的事它主动去读训练日志然后给自己写了一段调试总结大意是“当前学习率偏大导致loss震荡同时EmbeddingBag的维度可能过小我先尝试降低学习率并增大embedding维数”。它随后修改了模型代码把embedding维数从32调到128学习率从默认的1e-3改成5e-4并加了StepLR学习率调度器。重新训练后F1从0.82涨到了0.90左右。这时候Agent又开始折腾过拟合问题——它注意到训练集F1已经到0.99验证集却卡在0.90上下于是给模型加了一层Dropout还设置了max_norm3对词向量做裁剪。这一轮轮的操作你可以说是它在机械地试参数但在我看来它至少遵循了一个清晰的调试框架先看训练集和验证集差距判断是不是过拟合再针对性地改结构而不是盲目乱试。这种能力如果放到几年前我会以为是一个有经验的调参工程师在手把手带一个新手。3.4 第45~58轮独立完成测试评估、错误分析和交付文档模型效果达到验收线之后Agent没有直接收工而是开始补交付文档。它先写了evaluate.py在保留的测试集上重新加载model.pt并计算Precision、Recall、F1。最终结果如下$ python evaluate.py --data /workspace/data/test.tsv --model /workspace/model.pt Accuracy : 0.9520 Precision: 0.9406 Recall : 0.9702 F1-score : 0.9552F1最终落在0.9552超过了0.93的要求。它接着自动生成了一份README.md里面写了数据来源、环境依赖、训练命令、评估命令还老实地在“局限性”一栏里注明由于数据量较小且是自行整理的示例数据模型泛化能力仍需在更大规模真实数据上验证。看到那段话的时候我说实话是有点惊讶的因为它不只是把活干完了还知道自己生产出来的东西边界在哪里。整个过程中我唯一的介入是第30轮左右给Agent的上下文里追加了一条系统提示提醒它如果某条命令连续失败三次要停下来写一段“目前尝试了什么、为什么失败、下一步还有什么可选方案”再继续。除此之外所有代码都是它自己写的。4. 过程中翻得最狠的五个车以及我给Agent打的补丁4.1 幻觉式API调用它写的代码能骗过眼睛骗不过运行时报错在第一版训练脚本里Agent使用了一个旧的torchtext接口。这种错误你如果只让它生成代码、不运行代码根本发现不了。因为大模型的上下文里存了太多不同版本的API用法它在生成时不会自动去核对当前环境的版本号。单独把这段代码拿给一个人看也可能觉得“写得挺规范”。我后来在系统提示词里加了一条铁律每次项目开始前先执行一次pip list | grep torch和python --version确认环境版本后再决定API选型。之后这个问题再没出现过。这件事给我的启发是让大模型自己写代码的时候一定要把“验证环境”和“写代码”串成一个闭环。只盯着代码本身永远发现不了版本差异造成的坑。4.2 上下文越长越容易失忆文件读了等于没读实验进入中后期上下文已经积累了十几万Token。这时候出现了一个让我抓狂的现象Agent明明前面写过prepare_data.py后面却会在train.py里写from preprocess import ...而preprocess.py根本不存在。我一开始以为是模型蠢后来复盘日志才发现不是它蠢是它早期生成的文件列表埋在了很长的上下文里模型在写到一半时很可能只记得“我用python写了数据预处理模块”这个模糊概念具体文件名早就被冲淡了。这就像一个人翻一个五百页的文件夹翻到第两百页时已经不记得前面某个表格在第几页。我的补丁方案很土但很有效在每个工具调用的开头加一个“工作区当前文件”的固定字段只要是涉及写代码的动作Agent必须先调用list_files或read_file确认文件名和内容再动手修改。宁可每次多花一点Token也不能让它凭记忆写错。4.3 连续重试死循环第一次把Agent跑成复读机第30轮左右出过一段让人血压升高的记录。Agent在处理某个数据格式错误的时候连续四次生成几乎一模一样的代码只是改了变量名或注释然后重复跑再报错再改。看起来它其实没有理解错误根源只是在拿代码撞运气。我观察了十几分钟实在看不下去了才在系统提示词里加了“连续失败三次必须停下反思”的补丁。加了之后效果立竿见影。它在一段报错连续出现两次之后主动输出了一段总结指出问题可能出在标签类型没有转成torch.long于是不再顺着原来的思路继续撞而是跳出来分析了数据类型第三次就解决了问题。后来我意识到大模型天然有个倾向顺着当前对话的惯性一直往下走。这种惯性在代码生成顺利时是优点但在报错场景里就成了复读机病根。强制“反思”是打断惯性最直接的手段。4.4 Token和时间成本不可控烧起来比想象中猛这次实验总共消耗了大约130万Token折算下来大概2美元左右费用本身不算高。真正的问题是执行时间成本。因为Agent在跑训练脚本时一跑就是十几个epoch中间如果模型调参方向不对几十秒到几分钟就浪费了。整个流程走完用了将近两个小时其中大半时间花在等待训练完成和来回试错上。如果你想把它当成自动化流水线最需要关注的不是Token费用而是任务总时长和失败恢复机制。后来我在设计工具时给run_command加了超时参数比如训练类命令超过180秒就被杀掉把返回结果截断后告诉Agent“命令超时可能卡死”。这样它就不会干等一个永远不会结束的训练进程。4.5 没有约束时Agent会自作主张地越权尝试这个实验一开始我没有把Docker的网络断掉结果Agent在前几轮试图用pip install transformers去下载外部库。由于容器没配外网命令报错它才转向使用本地已有的包。你如果仔细想这件事会发现一个值得警惕的点Agent的目标是完成模型它并不知道“下载一个大型依赖”会带来的风险它只知道哪个方向看起来最省事。如果是一个生产环境Agent可能在未经审批的情况下给项目引入一堆版本不确定的包甚至尝试写文件到其他目录。所以我现在给任何Agent实验都定了硬规矩必须在容器里跑容器必须没有外网工作目录必须只读映射部分Agent能写的目录只有它自己的/workspace。这些安全边界不是锦上添花而是底线。你越放开Agent的权限它给你造的惊喜和惊吓就都是倍增的。5. 关于“AI能不能自己造AI”我现在敢说的结论5.1 实验验证出的能力边界清单先把这次实验证明能做的事列在明处给定一个验收指标清晰的建模任务AI Agent能独立完成数据处理、模型选型、训练、调参、评估、文档产出。中途遇到API版本、数据类型、模型过拟合等问题时只要环境能返回真实报错它就能自我纠正。它能自主判断何时该停止调参还会在最终报告里写清楚模型适用范围和数据局限性。在资源受限环境里它能主动抑制向外拉依赖的冲动转向本地资源求解。再说这次实验没有证明的东西它没有发明新模型结构没有质疑任务书本身是否合理没有主动对数据质量提出更深层的批判也没有在训练失败之后提出一个训练范式之外的替代方案。它做的一切本质上是在已有知识库里组合出最高概率成功的路径再把每一次运行结果当成反馈信号去修正路径。这套机制在标准流水线上已经够用但它还没到能开辟新方向的地步。5.2 当一个“开发主管”用什么任务适合交给它通过这次实验我对“什么时候可以放心让AI自主做项目”有了一个更清醒的判断。适合交给它的任务有这几个共同点目标是可量化的比如F1指标、准确率、运行时间。技术栈已经限定不需要跨领域引入全新框架。执行环境可控错误能被捕获并从反馈中恢复。人工只负责定义需求和验收不需要在过程中反复解释业务背景。反之任务目标模糊、需要大量外部业务知识、或者数据质量本身不可信的场景别指望Agent能自己搞定。如果连你自己都不知道“好模型”长什么样AI更不可能替你想明白。它本质上是一个无比积极的执行者不是一个能扛起需求定义和业务判断的决策者。5.3 给想复现这个实验的人几条可执行建议如果你也想亲自动手验证一次我建议从这四步开始撑一个Docker环境禁用外网预装熟悉的机器学习依赖。不需要在第一次就挑战高难度任务从文本分类或图像分类这种标准任务切入最稳。把任务书写成需求文档而不是Prompt。写清楚环境约束、交付物清单、验收指标、失败重试策略。一定要给工具执行加结果截断和超时机制。否则一次失误的命令可能把几十万Token的上下文全撑爆。记录完整日志。没有日志你会完全看不懂它在干什么出了Bug也没法复盘。最后再分享一个我个人在操作中的体会。实验进行到中段我看着Agent反复读报错、改代码、再运行的那个循环心里有一种很微妙的感觉——它像极了一个刚刚入行、干劲十足但没有太多大局观的年轻工程师。你需要给它划好边界给它明确标准盯紧它别在错误的方向上迷太久但你要承认那些重复性高、规则清晰的脏活累活它已经在相当程度上能自己扛下来了。这个现实不恐怖倒是挺值得认真对待的。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门