ARTICLE DETAIL

资讯详情

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

AI工程从零搭建:数据、模型与Agent的工程化实战

AI工程从零搭建:数据、模型与Agent的工程化实战 ai-engineering-from-scratch 这个词翻译成人话就是不靠现成模板把 AI 应用从环境搭建、数据准备、模型调用、效果调优到上线监控整条链路亲手走通。我最近刚用一个最小项目完整跑了一遍期间踩了不少坑也把很多文档里没写明白的决策逻辑给捋清了。这篇文章适合正在入门 AI 应用开发的工程师也适合已经在调 API、但始终觉得“差点底层直觉”的同学。读完你会发现AI 工程的难点其实不在模型而在模型之外的工程约束——数据、评估、服务化、和那根看不见的“行为缰绳”。我会把完整思路、选型理由、可复现步骤和排障记录全部分享出来。1. “从零开始”到底在零什么AI 工程的能力地图很多人一听到 from scratch第一反应是“从零写神经网络”。但实际做工程时真正需要从零搭的是体系不是模型本身。你要面对的是数据怎么来、效果怎么测、延迟怎么压、Agent 怎么管这些才是 AI 能不能落地的命门。1.1 为什么值得亲手完整走一遍我现在特别推荐团队新人做一件事在一周内不允许接任何现成的 AI 应用脚手架从头搭一个能用的对话 Agent。哪怕功能很弱也一定要走完整条链路。为什么因为只有亲手走过你才知道一个最简单的 AI 应用背后挂着多少隐性成本。比如你以为“调一下大模型 API”就完事实际还要考虑提示词版本怎么管理用户输入变了导致输出格式崩了怎么兜底模型今天回答好、明天回答差你怎么量化这些问题不亲自踩一遍光看文档永远建立不了直觉。另一个原因是“决策链路”很难从外部资料里学到。每个项目的数据质量不一样业务容忍度不一样预算不一样所以别人所谓的“最佳实践”到你这里往往不适用。你只有自己从零搭一遍才能把每个环节的参数调节点和约束条件记在脑子里。这种能力是面试造火箭、工作拧螺丝式的速成班给不了的。1.2 一个合格 AI 工程需要同时握住三条线我在实操中把 AI 工程拆成三条主线缺一条都会出问题。第一条是数据线。包括原始语料的清洗、格式统一、评测集的构建、敏感信息的过滤。很多教程只教你“把数据扔给模型”但真正决定效果上限的往往是这些不起眼的数据工程。第二条是模型线。你需要决定用闭源 API 还是开源模型要不要微调是用 RAG 还是靠上下文硬撑推理时是原始精度还是量化部署。每一个选择都是成本和效果的权衡而不是简单的好坏。第三条是工程线。包括服务封装、并发控制、日志追踪、可观测性、评测回归、灰度上线。模型是易变的而工程系统必须稳定。这条线最容易被忽略但也最决定项目能不能长期跑起来。三条线交织在一起我习惯用一个“最小闭环”来拉动先造一个带评测集的最小样本跑通“数据-模型-输出-评估”的循环再逐步加工程化能力。这样每一步都有反馈不会做到一半才发现方向错了。2. 先拆解核心链路与工程化的关键决策从零开始不等于蛮干我建议先想清楚几个关键决策点。下面这几个问题是每个人都会遇到的。2.1 数据侧从“能跑”到“稳定”的关键数据工作最核心的目标不是“多”而是“对齐”。模型输出风格、回答边界、调用格式全部依赖你对数据的对齐程度。我推荐从三份数据开始示例数据50 到 200 条输入输出对覆盖正常场景和边界场景。不需要一次做多但要聚焦你真正要解决的问题。评测集至少 30 条带标准答案的样本用来做每一次改动的回归对照。没有评测集后续所有“优化”都只是自我感动。对抗数据专门挑会让人工智能“犯晕”的输入比如带诱导、带错误前提、带格式要求变化的样本。这类数据最能反映工程护栏是否有效。实操时别急着写爬虫也别急着买数据。先把业务场景里最常见的 2 到 3 类问题手工整理成几十条样本足够启动第一版了。之后再做规则清洗、去重、格式校验。数据清洗有一个特别容易踩的坑不要过度清洗。比如你为了格式统一把所有换行符都去掉结果模型输出也变得挤成一团又把标点标准化结果业务方使用的特殊符号全被改了。清洗的目标是去掉“与任务无关的噪声”而不是改变自然语言的表达多样性。我的经验是每一道清洗规则都要单独记录并且在评测集上跑一次对比确认规则有效再加进去。2.2 模型侧基座、微调还是纯提示词这一节是新手最纠结的地方。我的建议是先默认用纯提示词方案也就是“Prompt Engineering 少量示例”把基座模型调到可用的状态。只有当纯提示词确实兜不住的时候再考虑微调。为什么因为微调的成本不只是训练费还有后续的运营成本。微调后的模型需要持续更新、持续评测、持续处理数据漂移这已经是一个二等团队的工作量。在业务效果还没被验证之前这种投入是危险的。我比较推荐的做法是“三层递进”用提示词加少量示例把任务跑通。这一步能验证业务逻辑是否成立。如果输出格式不稳定加一层结构化解析和重试机制而不是立刻微调。当提示词方案需要频繁增加“屎山”规则时再考虑收集失败样本做微调。基座模型的选择也有讲究。在预算允许的情况下能够私有化部署的开源模型优先原因不是数据安全口号而是你能拿到完整日志和可控的采样参数。闭源 API 固然省事但在排查问题时容易被黑盒限制住。2.3 推理侧服务化与资源估算把模型接到业务前先做一道简单的显存计算题。以 7B 参数模型为例使用 FP16 精度推理模型权重占 14GB 左右。加上 KV Cache 和激活值实际部署在单张 24GB 显卡上比较稳妥。如果你用 INT8 量化权重降到约 7GB一张 16GB 显卡也能跑。但这只是“能跑”不是“能并发”。并发越高KV Cache 越大显存占用会线性上升。我实际用的估算公式很简单显存 ≈ 参数(GB) * 精度字节数 KV Cache 2GB余量比如 7B 模型FP167 * 2 14GB 权重 假设 4 并发序列长度 2048KV Cache 约 3GB 再加 2GB 余量总共约 19GB这个数字说明单张 24GB 显卡带 4 个并发是极限。别被“模型 7B 很小”这句话骗了工程上显存瓶颈常常在 KV Cache 和并发。服务化推荐用成熟框架不要自己写请求透传。我常用的是 FastAPI 加推理后端外挂请求队列。这里有个细节模型推理是长耗时操作一定要把 HTTP 超时时间调到 30 秒以上否则网关会给你大量超时错误。2.4 Agent 与 Harness 工程给模型套上行为约束热词里“harness engineering”和“Agent”放在一起其实就是国外常说的“智能体缰绳”。模型本身没有稳定的行为边界你需要通过工程手段给它套上约束让它在可控范围内干活。我的理解中Harness 工程包含三层内容工具层给 Agent 定义可调用的外部工具规定输入输出 JSON Schema避免它自由发挥。控制层限制模型的行为选项包括最大步数、允许调用的工具列表、终止条件。观测层完整记录模型每一步思考、每个工具调用参数和结果方便回溯。实操中最容易失控的 Agent 场景是“循环调用”。模型发现某个工具返回了意料之外的结果就会反复调用同一个工具试图修正直到步数耗尽。没有 Harness 控制这种问题几乎必然出现。我的做法是给 Agent 增加三个硬性限制每轮任务最多执行 5 步工具调用超过立即终止。每次工具调用前强制输出一段“当前目标”说明方便观测它是不是偏了。工具结果必须经过一层解析和校验非法输出直接标记失败不让模型自由解释。这套东西听起来不复杂但真做起来你会发现它才是 AI 工程里最能提升稳定性的部分。3. 手把手落地一个最小可用的 AI 工程样例下面用一个“文档问答 Agent”作为例子带你把整个链路跑通。这个 Agent 需要做到用户问一句它会检索本地文档调用大模型生成答案并附带引用来源。3.1 搭建工程骨架和依赖我习惯用 Python 加 FastAPI整个工程只有几个核心目录app/ main.py # 服务入口 agent/ core.py # 调度逻辑 tools.py # 工具定义 data/ raw/ # 原始文档 processed/ # 清洗后的文档 eval_set.json # 评测集 services/ llm.py # 模型调用封装 retriever.py # 检索模块 tests/ test_eval.py # 自动评测脚本依赖尽量精简fastapi、uvicorn服务封装openai / transformers模型调用sentence-transformers向量化faiss-cpu / 向量库检索pytest评测不用上来就把 RAG 全家桶、监控平台全砌上先跑通一个最小闭环。等确认效果后再逐步加组件这是最省时间的路径。3.2 实现数据清洗与评测集首先把原始文档切成段落过滤掉表格和图片占位符保留标题层级作为上下文。这一步很关键因为检索的颗粒度直接决定了回答质量。切得太细检索结果零散切得太粗上下文窗口容易被无关内容填满。我用的默认参数是按标题和空行分段每段 200 到 600 字段与段之间保留 10% 的文本重叠。为什么留重叠因为切分点通常不在语义边界上重叠可以避免关键句被截成两半。接着构造评测集。每个样本包含三个字段{ id: case_001, question: 文档中提到的重试机制默认次数是多少, reference: 默认次数是3。, source_doc: docs/ops_guide.md }评测集不需要大30 条足够启动。关键是要覆盖三类问题能直接回答的、需要跨段落检索的、提问方式带有歧义的。歧义样本最考验 Agent 的真实水平一定要放进去。3.3 封装推理服务模型层我不建议在业务代码里直接写模型逻辑而是封装成一个独立的 LLM 模块接口保持简单async def generate( messages: list[dict], temperature: float 0.2, max_tokens: int 512 ) - str: ...这里有两个参数需要解释。第一个是 temperature问答类任务我固定设 0.2避免模型自由发挥创意类任务可以调到 0.7 以上但这个项目不需要。第二个是 max_tokens设 512 是为了防止单次回答过长拖慢响应也方便外部在超时控制上统一处理。服务入口我写成这样app.post(/chat) async def chat(request: ChatRequest): context retriever.search(request.question, top_k3) messages build_prompt(request.question, context) answer await generate(messages) return {answer: answer, sources: [x.id for x in context]}为了让检索结果可追溯我返回了命中的 source id。上线后你会非常依赖这个字段因为用户遇到回答错误时能快速判断是“检索错了”还是“生成错了”。3.4 让 Agent 跑起来并接入自动评估把 Agent 调度逻辑跑通后立刻接上评估脚本。这一步不能等越早越好。def run_eval(): results [] for case in eval_set: response agent.run(case[question]) score evaluate(response, case[reference]) results.append({id: case[id], score: score}) return sum(r[score] for r in results) / len(results)评估指标不要一上来就上 BLEU、ROUGE先用一个“硬指标加软判断”的组合硬指标回答是否包含参考答案中的关键实体词。软判断让一个固定 prompt 的模型给答案打 1 到 5 分。硬指标能保证基本事实不出错软判断能捕捉语义差异。两者结合至少能挡住 80% 的回归问题。第一次跑完评测后你会看到一个非常真实的场面模型输出的答案格式五花八门有些完全符合预期有些则完全跑偏。这正是自动评测存在的意义。接下去要做的不是去改模型输出而是根据失败样本回到提示词和检索逻辑里找原因。4. 常见问题与排查技巧实录最后一部分我把实操中反复踩过的坑整理成速查表每个问题都附上我的排查思路。4.1 模型输出“看起来对实则错”怎么抓这是 AI 工程最头疼的问题语法通顺、语气正常但事实是错的。很多人第一反应是“加提示词”但我建议先做归因。排查顺序是先确认检索到的上下文是否正确再确认模型是否在基于上下文回答。如果检索结果本身不包含参考答案那生成错是大概率事件该改的是检索。如果检索结果包含答案但模型没引用那问题出在提示词约束或模型本身的幻觉倾向。我处理幻觉还有一个土办法在提示词里强制要求“回答必须以参考文档为依据没有依据时明确说不知道”。这话不复杂但实测能降低不少幻觉率。同时把“没有依据”这种拒绝类回答也加入评测集防止模型为了讨好用户而硬编。4.2 Agent 跑飞、死循环和工具调用失败Agent 跑飞是常态尤其是工具较多时。我见过最离谱一个循环模型连续调用 12 次搜索工具每次都换关键词却始终不读结果最后把上下文塞满后报错。解决这类问题不靠提示词靠工程强制。Harness 里的“最大步数”必须是最优先级任何一个 Agent 框架都要有这个参数。同时记录每一步的完整调用链方便复盘。工具调用失败也非常常见比如工具返回 JSON 多了一个逗号模型解析不出来。我会在校验层做容错先尝试严格的 JSON 解析失败后尝试修复常见错误例如去掉末尾逗号、补齐引号。不要让模型在线解析那是把不确定性放大到整条链路上。4.3 显存与并发资源不够时的降级方案资源不足时我按顺序做三件事量化、批处理、裁剪上下文。量化优先用 INT8几乎不影响小模型效果显存直接减半。批处理可以把多个请求拼成一个 batch 推理显著提高吞吐但要注意单请求的 max_tokens 不要相差太大否则低吞吐请求会阻塞长输出。裁剪上下文则是把与当前问题无关的检索片段强行去掉减少 KV Cache 消耗。如果服务端压力还是大就在网关层加“排队机制”而不是粗暴返回 429。排队虽然延迟变高但至少能让用户体验连贯而且可以避免雪崩。4.4 评测指标与线上反馈不一致的问题自动评测显示 95 分上线后被业务方吐槽得一塌糊涂这种情况我把原因总结为三类第一评测集太干净。真实用户的输入带错别字、带口语、带超长上下文你的评测集里没有评分自然失真。所以评测集必须加入真实流量里的失败案例持续迭代。第二指标偏向“字面匹配”却忽略了意图。修改评估 prompt明确告诉模型“只要事实正确、逻辑通顺即使描述方式不同也可以给满分”。第三线上用户的问题分布和评测集不一致。评测集往往是垂直领域的但上线后混入了跨领域问题。解决方法是把评测集按来源和质量分层每次改动后分别计算各层得分而不是只看平均分。这些坑我几乎每个都在真实项目里遇到过。踩平它们之后你才能建立起对“自动评测”的信任也才敢让模型应用持续迭代。我个人在实际操作中的一个体会是AI 工程不是把模型接到业务里就结束而是要在模型的不确定性外面搭建一层确定性的壳。从零走过的意义就是亲手摸清这层壳的每一个接缝。最后再分享一个小技巧保持一个失败样本库所有线上 Backend 日志里的 Bad Case 都往里丢隔一段时间就去重归因一次。这个库越厚你的系统越稳也越能在下一次迭代里快速找到方向。
返回列表