拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零搭建可复现AI工程:数据清洗、Prompt与Agent实践

从零搭建可复现AI工程:数据清洗、Prompt与Agent实践 我一直觉得“AI工程”听起来特别高大上但实际上它离我们普通开发者的日常特别近。今天想聊的就是这个从零开始的完整过程怎么从只会写几个Python脚本到能独立搭出一个有数据、有模型、有测试、能上线的AI工程。我自己走这条路时踩过不少坑最开始以为是要去啃一堆算法论文后来才发现真正的门槛根本不是算法而是你能不能把一整套流程管起来。如果你正打算做AI项目或者已经在做但总觉得乱这篇文章应该能帮上忙。我会从最基础的项目骨架讲起一路聊到数据清洗、Prompt Engineering、AI Agent、测试评估和上线监控。核心目标只有一个让你能复现、能迭代、能上线而不是永远停留在“能跑通”的阶段。1. 先想清楚AI工程到底是“工程”还是“算法”很多初学者一听到“AI工程”第一反应就是学PyTorch、学Transformer然后疯狂调参。我自己踩过这个坑。第一个项目是一个文本分类任务我在模型上花了两周反复调学习率、层数效果一直卡在80%左右。后来把原始数据翻开看了一眼发现标注错误率超过10%。那一刻我突然意识到AI工程的第一关键不是模型而是你和数据的关系。模型只是把数据里的规律抽取出来如果数据本身就是乱的再强的模型也只能学到乱规律。AI工程和算法研究的区别可以类比成盖房子和做装修。算法研究可能是在实验室里打磨一种新型材料而AI工程是从地基到水电再到软装把整个系统稳稳当当地搭起来。用户反馈、线上数据回流、成本控制、版本迭代这些都属于工程问题任何一个环节没跟上项目都会翻车。1.1 大多数人的误区把AI工程当成炼丹这里说的“炼丹”就是那种不断改参数、跑实验指望模型效果突然变好的状态。我以前也这样没有弄清楚问题是什么就开始选模型、调参最后结果不好只能怪硬件不行、数据不够。后来我明白了一个道理如果你不能用规则或者简单方法把问题描述清楚那你大概率也不会用AI解决它。举个例子假设你要做一个客服工单自动分类。你连“工单类型有哪些”“什么算支付问题什么算退费问题”都没定义清楚就直接丢给模型那模型给你乱分是很正常的。反过来如果你先把问题拆细再在提示词或者模型输入里把这些约束表达清楚效果会立刻稳定不少。我个人的习惯是做任何AI功能前先强迫自己写一段伪代码或者业务规则。如果这段规则写得出来后面的模型方案基本能成如果写不出来那先别急着上AI回去把需求问清楚。1.2 从零开始前要补的三个基本功数据、评估、流程如果真要从零开始我不会让大家先冲模型而是先补三样基本功数据、评估、流程。数据是AI项目的粮食。这里说的数据不只指训练集还包含测试集、验证集、用户实时反馈。数据能力包含怎么收集、怎么清洗、怎么做标注规范、怎么防止数据泄漏。我见过太多项目模型在测试集上准确率到了95%上线后直接掉到70%很大概率就是测试集和训练集混在一起了。这种问题特别隐蔽因为报错不会报你只能通过效果对比去怀疑。评估是这个项目能不能继续迭代的标尺。很多人说“效果感觉不错”但感觉不能作为标准。你需要把它拆解成准确率、召回率、F1、人工抽检通过率这些指标。而且评估集一定要从真实业务场景里抽不能只在网上找现成的公开数据集因为公开数据和你业务里的实际数据分布差太远测出来的数字根本不是真实水平。流程是AI工程的骨架包括需求分析、数据准备、建模或提示词开发、评估、上线、监控、迭代。看着像废话但绝大多数失败项目死就死在流程缺失。比如上线前才发现没有日志出了问题根本无从排查又比如没有配置管理代码改到哪一版都不知道。从零开始我的建议是先拿一个能出效果的小项目把整个流程跑通一遍哪怕只是一个简单的规则分类器。关键是让你脑子里产生那条完整链路后面的模型再复杂也只是在替换链条里的某个环节而已。2. 从零搭建一个可复现的AI项目骨架项目骨架的作用是让所有东西都有地方放、有迹可循。很多人写AI代码喜欢把所有逻辑塞进一个notebook里跑完就丢。这种方式做实验可以做工程绝对不行。因为两周后你根本记不住哪里调了参数、哪里改了数据处理逻辑。我自己的做法是从第一天就按照工程标准来搭目录。这样看起来麻烦但一旦项目进入迭代期回报会非常明显。2.1 项目目录怎么设计才不后悔下面这个结构是我多次调整后留下的习惯版本适合大多数组件化的AI项目ai-engineering-from-scratch/ ├── data/ │ ├── raw/ # 原始数据只读不改动 │ ├── processed/ # 清洗后的数据 │ └── samples/ # 小样样本用于调试 ├── src/ # 项目核心代码 │ ├── data_processing/ # 数据清洗、转换 │ ├── models/ # 模型封装、调用逻辑 │ ├── agents/ # Agent相关代码 │ ├── prompts/ # 提示词模板 │ └── evaluation/ # 评估逻辑 ├── configs/ # 所有配置文件 ├── tests/ # 单元测试、回归测试 ├── scripts/ # 训练、评估、上线脚本 ├── notebooks/ # 探索性分析 ├── logs/ # 运行日志 ├── models/ # 本地模型文件占位 └── reports/ # 评估报告、实验记录为什么要把data/raw单独放因为原始数据是唯一不可再生的资产任何清洗、转换都不应该覆盖它。哪怕你后来清洗逻辑写错了只要原始数据还在就能重来。反之如果直接对着原始文件改出错后就再也找不回来了。cuisines/这类目录名我用过一段时间后来发现太容易引起歧义。干脆叫configs/里面放dev.yaml、prod.yaml、default.yaml简单直接。配置和代码分开是工程里的老规矩AI项目也一样。2.2 环境与依赖管理虚拟环境、版本锁定Python项目第一步永远是创建虚拟环境。我见过太多人图省事直接在全局环境里pip install结果不同项目之间包版本互相冲突最终只能重装系统。正确做法是给每个项目单独建一个环境python -m venv venv source venv/bin/activate pip install -r requirements.txt这里的requirements.txt只写顶层依赖比如openai1.0、transformers4.0。等你确定某个版本跑起来没问题再执行一次pip freeze requirements.lock把完整版本锁住。为什么要锁因为AI生态变化太快今天transformers 4.30能跑的代码换到4.50可能就因为API改动直接报错。版本锁定是你保证“昨天能跑的代码今天还能跑”的唯一办法。我在实际项目里常用这样的对比文件作用更新时机requirements.txt顶层依赖给人看添加新依赖时requirements.lock完整依赖给机器看每次环境稳定后如果项目里用到了模型权重文件或者大的数据文件别塞进Git仓库。用.gitignore把models/、data/raw/、logs/过滤掉依赖和代码才适合进版本管理。2.3 配置管理和实验记录把每次调试变成可回放的历史配置管理是AI工程里最容易被忽略、但最值钱的一环。我的第一个正经AI项目因为没有记录配置出现过一种很尴尬的情况模型效果不错但准备上线时怎么都复现不出同样的效果。原因是中间某次调参改了学习率代码里却没保存对应版本。最后只能靠回忆白白浪费了好几天。所以现在我一定会用一个配置文件来集中管理所有可变参数。最简单的做法是config.yaml加一个 dataclass 加载model: name: gpt-4o-mini temperature: 0.2 max_tokens: 1024 data: raw_path: data/raw/orders.csv processed_path: data/processed/orders_clean.csv eval: golden_set_path: data/samples/golden_set.jsonl然后在代码里加载from pydantic import BaseModel class ModelConfig(BaseModel): name: str gpt-4o-mini temperature: float 0.2 max_tokens: int 1024 # config.yaml - config对象 import yaml with open(configs/dev.yaml) as f: raw yaml.safe_load(f) model_config ModelConfig(**raw[model])别小看这个步骤。有了配置文件你调参时只用改YAML不用动代码。每次实验还会额外记录一个文件比如experiment_log.csv每次改动都往里面追加一行字段至少包括时间、Git commit、数据版本、模型名称、关键指标。这样两周后你回来看每个数字都有出处。经验哪怕懒得用MLflow或者Weights Biases也一定在项目里留下一个experiment_log.csv。这可能是你做过的最划算的工程投资。3. 核心环节数据、模型选择与提示词工程的交接项目骨架搭好之后接下来就是实打实的业务逻辑了。这个阶段最核心的活其实不是“写模型代码”而是把数据和模型之间的交接处理好。交接不好后面全是窟窿。3.1 数据清洗与构建没有好数据模型就是花瓶数据清洗这件事听着不酷但它决定AI项目的生死。我见过有人拿到数万条用户评论直接丢给模型做情绪分类结果准确率惨不忍睹。后来发现数据里有一堆HTML标签、重复文案、乱码模型学到的全是噪音。我的清洗流程一般是这样去重df.drop_duplicates(subset[text])防止同一条数据反复出现影响分布。格式统一全角半角、大小写、换行符统一处理。噪音过滤去掉URL、无意义符号、过长或过短的文本。抽样统计随机看几百条确认标注质量。切分数据按时间或ID哈希切分保证测试集不泄露。有个细节特别容易翻车数据切分。如果你直接train_test_split(random_state42)把同一个人或者同一个用户的多条文本同时分进训练集和测试集那模型其实已经“见过”测试数据了。正确的做法是先按用户ID分组再把用户分成训练组和测试组。这时候模型面对的是完全没见过的人效果才真实。在LLM时代数据清洗的意义其实被很多人低估了。你以为模型自己啥都能处理但它处理不了你给它的上下文里全是重复、矛盾、格式混乱的内容。清洗后的数据不仅喂给微调模型有用喂给Prompt模板也一样重要。干净的数据会让输出稳定不少。3.2 模型选型什么时候该调模型什么时候该调提示词很多人上来就问“该用哪个模型”。我的回答通常是先想清楚你是要“解决问题”还是“追求前沿”。如果是前者能用提示词解决的就别急着微调能用小模型解决的就别上大模型。可以看这个对照表场景推荐方案理由简单分类、抽取数据量不大提示词 中/小模型成本低、迭代快需要固定输出格式、强逻辑提示词 结构化解码稳定可控领域数据丰富开源模型可用微调开源模型数据隐私和成本有优势任务极其复杂需要深度推理大模型API Agent能力上限高但成本高我个人的经验是优先用现成API跑一个Prompt版本哪怕效果差点也能把你对任务的理解固化下来。等业务跑通了再评估要不要换模型、要不要微调。千万不要一开始就想着训练一个专属模型那个成本极高而且最后效果往往没比好好写提示词好多少。选型时还有几个工程指标必须看时延、吞吐、成本、上下文长度。有时候大模型效果确实好但线上用户等不了三秒才看到回复那就得考虑模型蒸馏或者在关键词场景用小模型先顶一版。3.3 Prompt Engineering实战从零把提示词调到可用状态提示词工程不是玄学它有很清晰的套路。我常用三段式结构角色、任务、约束。再加一到两个示例效果立刻不一样。拿客户评论分类举例一个能用的Prompt长这样你是一个电商客服质检助手。 任务把下面的用户评论分类为“物流问题”“质量问题”“退换货需求”“其他”四类。 约束 - 只返回分类名称不要解释。 - 如果评论包含多个问题选择最核心的一个。 - 如果无法判断返回“其他”。 示例 评论快递三天没动客服也不回话。 - 物流问题 评论收到的衣服拉链坏了想换一件。 - 退换货需求 请分类 评论这个杯子颜色和图片有色差不过客服态度很好。这个Prompt看起来普通但每一项都有目的。“角色”给模型一个定位“任务”明确要做什么“约束”把输出的边界框死“示例”则是少样本学习让模型明白你的格式偏好。如果缺少约束模型很可能输出成一段话而不是简单分类解析起来就很麻烦。复杂任务还能再加一步“思维链”提示。比如让模型先列出推理过程再给结论。不过要注意启用思维链会增加Token消耗如果业务场景只要快速结果没必要每次都让它慢慢推理。温度参数也很关键。分类、抽取这类确定性任务我基本设到0需要创意文案或者头脑风暴才会调到0.8左右。很多不稳定的输出其实不是Prompt写得差而是温度太高导致模型随机性太大。4. AI Agent与工作流从单次调用到多步任务现在做AI项目单次模型调用往往不够用。真实业务里经常要模型“调用工具”“记住前文”“完成多个步骤”这就需要Agent。从工程角度看Agent不是魔法它就是一个可控的任务调度系统。4.1 Agent的基本结构模型、工具、记忆可以把Agent想象成你请的一个实习生。实习生很聪明但需要你给他任务目标、办公工具和会议记录。对应到技术上就是三件事模型负责决策判断下一步该做什么。工具模型可以调用的函数比如搜索、查询数据库、发邮件。记忆保存对话上下文和历史操作让模型不会忘记前面说了什么。工程上你需要定义一个“工具清单”让模型只能调用白名单里的函数。比如def get_weather(city: str) - str: 查询城市天气 return f{city}今天阴天最高22度。Agent拿到用户问题“北京天气怎么样”先规划调用get_weather(city北京)拿到结果后再组织回答。这个过程可以用while循环实现模型输出函数名和参数 - 代码解析 - 执行工具 - 把结果再喂回模型 - 判断是否结束。这个循环看起来简单但隐藏着很多工程细节。比如模型可能乱编参数、可能陷入死循环、可能在工具调用几次后忘记原始任务。所以工程上必须给Agent加上“最大迭代轮数”“单次超时”“Token预算”这些硬约束。这也是AI工程和单纯聊天的最大区别你要为失控做准备。4.2 一个完整案例用CodeBuddy实现Harness Engineering思路Harness Engineering可以理解为给AI应用装上“安全护栏”和“控制机制”。核心思想是只给模型有限的工具和权限并且在每一次调用前后都做校验。这个思路特别适合用AI编程工具来实现我自己就用CodeBuddy辅助写过一版。举个例子我想要一个能查天气和订单状态的Agent。先明确工具白名单只允许查天气和查订单不允许访问其他数据。然后让CodeBuddy帮我生成一个简单的Harness框架import json from typing import Callable, Dict TOOLS: Dict[str, Callable] { get_weather: get_weather, get_order_status: get_order_status, } MAX_STEPS 5 def run_agent(user_query: str): messages [{role: user, content: user_query}] for step in range(MAX_STEPS): response model_chat(messages) if response.is_final_answer: return response.content tool_call parse_tool_call(response.content) if tool_call.name not in TOOLS: return Error: 工具不在白名单内 if not verify_args(tool_call.args): return Error: 参数校验失败 result TOOLS[tool_call.name](**tool_call.args) messages.append(response) messages.append({role: tool, content: json.dumps(result, ensure_asciiFalse)}) raise TimeoutError(Agent达到最大轮次)粗看可能觉得代码多但有几个点特别关键。MAX_STEPS避免模型无限循环verify_args避免模型传明显非法参数工具白名单意味着即使模型“想”调用别的功能也没有对应的入口。这些就是Harness Engineering的实践你不依赖模型自觉而是用代码把行为边界焊死。用CodeBuddy辅助的好处是这类重复的工程模板生成很快。你可以直接告诉它“我要一个Agent只能调用这两个函数最大迭代5次输出必须是JSON格式”它就能给你一个可复用的骨架。然后你再根据自己的业务逻辑去改。4.3 多AI协作与工作流的编排别让Agent变成脱缰野马单个Agent能力有限所以现在大家喜欢让多个Agent协作。比如一个Agent负责理解用户意图一个负责检索资料一个负责写初稿一个负责审核。这个想法很好但工程复杂度成倍上升。多Agent协作最怕什么最怕级联失败。A Agent输出乱了B Agent基于乱输出继续处理结果越来越离谱。所以编排层必须做到每一步都有超时、每一步都有校验、每一步都写日志、每一步都有预算。我给你推荐一个务实的做法先把Agent之间的“接口协议”定义清楚比如都用JSON传输字段包含status、data、error。这样任何一个Agent出错上层都能立刻感知并中断。千万不要让Agent之间直接传自然语言那样你根本没法做断言和测试。另外多AI协作里一定要有人类审批的关键节点。比如在自动回复用户之前加一道“置信度低于阈值则转人工”的规则。这不是不信任模型而是工程上的风控意识。很多线上事故都是在最后一个环节缺了人为开关导致的。工作流编排工具方面LangGraph、LangChain、自研状态机都可以。我的建议是如果团队小、业务简单自己写一个状态机反而最清晰。外部框架虽然灵活但出了问题排查起来特别费劲。5. 测试、评估与上线工程化的分水岭代码写出来能跑不等于能上线。AI工程和普通后端开发最大的区别就是模型输出的不确定性。普通函数你写return 11永远得到2模型你让输出JSON它某天可能多给一段解释。所以测试和评估才是AI工程的分水岭。5.1 离线评估用评测集给模型打分离线评估的道理很简单准备一批标注好的输入输出对每次改动后让模型跑一遍用固定指标衡量效果。和训练好的模型相比这更像是一个针对Prompt和工具链的“期末考”。我习惯先做一个Golden Set黄金评测集规模不需要大50到100条就够。关键是覆盖面要广典型场景、边界场景、易错场景都要有。比如客服分类里“申请退款”和“投诉并退款”必须同时存在不然模型很可能把第二种也归成单纯投诉。每次改动Prompt、换模型、加工具都在Golden Set上跑一遍记录准确率变化。这个过程要自动化最好一个脚本能出结果python scripts/run_eval.py --config configs/dev.yaml输出类似Accuracy: 0.92 Precision: 0.90 Recall: 0.93 F1: 0.91有了这个脚本你就不怕“感觉变好了但不知道变好多少”。在AI工程里没有数据的评价都是耍流氓。生成式任务的评估会更难一点。除了人工打分可以用关键词命中、相似度计算等辅助指标。如果预算允许也可以用更强的模型当裁判但要注意自己的模型可能存在偏好。核心是评估要和业务目标对齐你要的是用户满意不是单个指标好看。5.2 测试开发给AI应用写单元测试和回归测试很多人觉得测试是传统开发的事AI项目不用测。这是大错特错。AI项目的测试不仅要做还要做得更细。因为你不仅要测业务逻辑还要测模型输出结构。最典型的例子是解析模型返回的JSON。模型偶尔会返回带前后缀的文本比如json ...如果你直接json.loads就会抛异常。正确的做法是用一个健壮的解析函数把杂讯剥掉。然后给这个解析函数写测试import pytest def test_extract_json_with_code_block(): raw json\n{status: success}\n assert extract_json(raw) {status: success} def test_extract_json_with_extra_text(): raw 好的结果是{status: success} 请查收 assert extract_json(raw) {status: success}这种测试价值极高。因为AI工程的坑往往不是一次性的而是模型每次输出都有微小变化。如果你没有一个“契约测试”帮你在源头拦截等到了下游再发现解析失败定位成本会非常高。另外给Prompt模板也要建版本。我见过一个项目某次同事顺手改了一个字整体效果掉了5个点但没人发现。后来把Prompt模板纳入版本管理并且每次修改都强制跑一遍Golden Set才止住这个风险。5.3 可观测性日志、追踪和成本监控上线前必须做可观测性。AI应用和普通服务一样需要日志、指标、追踪。但AI项目多了一个特别重要的指标Token消耗。每次请求都应该记录类似下面的结构化日志{ request_id: req_20250101_abc, timestamp: 2025-01-01T12:00:00Z, model: gpt-4o-mini, prompt_tokens: 320, completion_tokens: 180, latency_ms: 850, status: success, error: }有了这些日志出问题时你能立刻回答三个问题调用了什么模型花了多少钱用了多久成本监控尤其重要。很多人上线前只看模型效果上线后才发现成本超出预算。算笔账假设每天1000次请求每次输出500个token不同模型价格不一眼但API按千万token计费时这个量级可能一天也要几十上百元。如果Agent内部还循环调用了好几次成本就不是线性增长而是成倍上涨。所以我建议给Agent设置“单次会话最大Token预算”比如3000。达到预算就强制中断让用户简化问题或者转人工。这既保护成本也保护用户体验。6. 常见问题与排查技巧实录AI项目上线后大概率会遇到一些反复出现的坑。我整理几个最常见的问题附上排查思路应该能帮你节省不少时间。6.1 模型输出不稳定是温度参数还是提示词问题模型输出不稳定的现象很典型同一个问题隔几分钟问一次答案变了。第一步先检查温度参数如果它大于0先把温度改成0再看输出是否稳定。如果稳定了就是随机性问题如果还不稳定大概率是提示词里给了模型太多自由裁量空间。我之前遇到过一个客服机器人经常在长回复里莫名插入Markdown格式断断续续。排查半天发现系统消息里写的是“可以使用Markdown”模型把它当成了一个可选动作。改成“必须使用纯文本不要Markdown”后问题立刻消失。所以提示词里要尽量用“必须”“禁止”而不是“可以”“最好”。如果你的输出是结构化数据务必启用JSON模式或者正则约束。不要指望模型自己记住“只输出JSON”它会被上下文带跑。工程上要双保险提示词约束加上解析层兜底。6.2 效果突然变差数据漂移与缓存失效线上效果变差先别急着怀疑代码。我看过太多人调试了半天模型最后发现是上游数据接口的字段名变了。所以排查顺序应该是先看输入数据再看依赖服务然后才轮到模型本身。数据漂移在AI项目里很常见。比如你训练时用户评论都是中文线上突然涌进来一批英文评论模型没见过自然表现差。这时候你需要监控输入数据的分布变化比如关键词频次、文本长度分布一旦偏离基线就自动告警。缓存失效也是一个隐性问题。如果你的Agent在每一步之间用了Redis缓存前段时间缓存命中率高响应很快后来数据量大增或者缓存过期命中率下降外部调用变多表现为响应变慢。这时候查日志里各个调用耗时很快就能找到瓶颈。6.3 工程调试清单十分钟定位问题这里放一个我实际用的速查表排查时可以对照现象可能原因排查方法响应超时模型API慢、网络波动、重试过多看追踪耗时增加超时与熔断输出乱码、JSON解析失败模型输出格式漂移增强提示词约束加解析兜底成本飙升单次会话Token超预算、循环调用设置最大轮次和Token上限看日志统计效果下降数据分布变化、Prompt被改对比Golden Set检查配置变更记录Agent卡死循环调用、工具无返回加最大迭代给工具加超时还有一个个人技巧给项目准备一个“一键烟测脚本”把核心场景的输入输出写死每次改动上线前先跑一遍脚本确认整体流程没断。这个脚本不要和你正常的评估脚本重叠它只做连通性检查能快速暴露环境、配置、依赖问题。一些最后的体会从零开始做AI工程真正改变我的不是某一次模型效果突破而是一种习惯的养成不管上下游多复杂都要让每次实验可复现、每次结果可衡量、每次问题可追踪。这个过程确实平淡远没有“训练出个大模型”听起来刺激但它才是工程落地最有价值的部分。最后再分享一个小技巧如果你还在“从零”阶段不要一次性追求完美架构。先做一个能跑通的最小版本哪怕就是玩一个分类、写一个输出模板也把它放到项目骨架里走一遍完整流程。你会发现当流程成为习惯时后面加Agent、加测试、加监控都只是往里填东西而已。
返回列表