ARTICLE DETAIL

资讯详情

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

从零开始做AI工程:提示词、RAG、Agent编排与落地实践

从零开始做AI工程:提示词、RAG、Agent编排与落地实践 1. AI工程到底是个什么工程1.1 AI工程不是“调API”是五种能力的组合很多人一听到“AI工程”就以为是在写几个openai.ChatCompletion.create()调用或者对着界面点点点。我刚开始也这么想直到真正把一个AI功能推到线上才发现完全不是这么回事。所谓“from scratch”不是让你从零训练一个大模型而是从零建立起一套完整的AI应用体系。这套体系至少包含五个部分第一是需求拆解能力。用户的真实痛点是什么哪些环节适合用大模型哪些环节用了反而更慢。第二是数据工程能力。模型输入输出怎么清洗、怎么构造上下文、怎么设计评测集。第三是提示词工程与Agent编排能力。不是把问题甩给模型而是设计一套提示策略和任务流程。第四是工程化交付能力。接口、缓存、限流、监控、回滚这些和传统后端开发一样但又有自己的特殊性。第五是评测与迭代能力。模型行为不是确定的没有一套评测机制上线就是埋雷。这五个能力缺一个都不行。只擅长提示词交付不了稳定系统只擅长后端做不出智能效果只擅长算法落不到业务场景。AI工程真正考验的是把这几件事捏在一起的能力。1.2 为什么“从零开始”这件事值得认真做很多团队引入AI的方式是“先接个API试试”。试完之后发现demo能跑一到生产环境就各种问题模型回答时好时坏上下文越传越长成本越花越多出了问题不知道是提示词的问题还是数据的问题还是模型本身的问题。我经历过一次特别典型的翻车。一个客服问答系统上线前用100条测试集人工看过几乎全部通过。上线后却发现用户问同样的问题有时候回答得很准有时候答非所问。排查了半天发现是提示词里有个示例在不同模型版本下产生了完全不同的注意倾向。这种问题如果一开始就按工程化的方式来构建是可以提前发现的。“from scratch”真正的价值不是“从零开始造轮子”而是“从根上建立正确的方法论”。它逼着你把每一个环节都理清楚数据怎么来上下文怎么组织模型怎么调用答案怎么校验系统怎么降级。等这套逻辑通了后面换模型、加场景、扩团队都只是工作量问题不是认知问题。2. 从零开始的技术路线怎么选2.1 基础理论学到什么程度就够了关于“要不要学机器学习理论”这件事市面上有两种极端。一种说“不需要直接用API就行”另一种说“不学清楚Transformer就别碰AI”。我的看法是不需要成为算法专家但必须理解大模型的基本工作原理。至少需要掌握几个核心概念Token和上下文窗口、温度等采样参数、Embedding相似度、向量检索的基本逻辑、模型的训练与微调区别、上下文注入与RAG检索增强生成的基本原理。这些知识不用啃论文但要用在实践里。比如你设计提示词的时候知道模型实际上是“基于概率预测下一个Token”你就理解为什么它在你要求“必须用JSON格式输出”时偶尔还是会冒出多余的文字。又比如你知道Embedding之间可以用余弦相似度衡量语义距离你就会明白为什么RAG需要做向量检索而不是简单的关键词匹配。我个人的建议是花一两天时间把Tokenizer怎么切词、Transformer怎么计算注意力、Embedding怎么映射语义这三件事搞清楚后面就能hold住绝大多数工程问题。再深入的东西等遇到具体问题再去查效率更高。2.2 工具链选型编程语言、框架与模型从我自己的实践来看Python依然是AI工程的主力语言因为AI相关的生态基本都在Python这边。但如果你要做的是企业级后端集成Java、Go这些语言也不是不行关键是找到对应语言的SDK和社区支持。框架方面如果你做的是完整的AI应用LangChain和LlamaIndex值得一学但不是必须。它们的价值在于把“模型调用 工具调用 记忆管理 检索增强”这些常见组件封装好了。缺点也很明显封装层级多出错之后定位问题会绕圈子。我见过很多新手项目用LangChain搭了一个复杂的Agent最后报错都不知道是哪个chain出的问题。我的建议是第一版尽量少用重量级框架先用原生SDK把最基本的调用写明白然后在实践过程中按需引入框架。这样你对底层逻辑有感觉以后出问题能快速定位。模型选型上先选一个足够强的通用模型把整套链路跑通再评估是否需要针对具体场景换模型。不要一上来就追求本地化部署那是业务规模到了一定程度之后才需要考虑的事情。2.3 第一个AI项目的完整落地步骤从零开始做一个完整的AI工程项目我建议按下面这条路径走第一步选一个边界清晰的场景。比如“根据产品文档回答用户问题”或者“把一段长文总结成三个要点”。边界越清晰评测越容易工期越可控。第二步准备数据。收集至少50到100条真实输入作为种子评测集。这些数据不需要一开始就完美但要能代表真实使用场景。第三步编写提示词并跑通最小链路。用最简单的代码实现“输入 - 组装提示词 - 调用模型 - 输出结果”这条通路。第四步建立评测机制。把种子评测集跑一遍人工逐条看输出质量记录问题类型。这一步最重要因为后面你改任何东西都需要拿这套评测集来回测。第五步补齐工程细节。包括输入输出的校验、错误重试机制、响应格式约束、日志记录、超时处理等。第六步灰度上线与线上监控。先让一小部分真实流量进来观察模型输出质量和调用成本再逐步放开。这套流程走完你其实已经拥有了一个可以持续迭代的AI工程骨架。之后无论是换模型、加功能、扩场景都是在骨架上进行增量修改。3. 提示词工程与Agent编排真正的分水岭3.1 提示词工程从自然语言到结构化协议提示词工程是AI工程里最基础也最容易被人低估的一块。很多人觉得提示词就是“把需求说得更清楚一点”。事实没那么简单。一个稳定的生产级提示词本质是一个结构化的协议不是一句人类的自然语言。我推荐使用分块结构来写提示词。一个完整提示词通常包含角色定义、任务描述、输入格式、输出格式、约束条件、示例演示、边界处理。以“客服问答”为例我会这样组织角色定义你是一位熟悉某产品手册的资深客服。任务描述根据给定的文档片段回答用户问题。输入格式用明确的XML标签圈出文档和用户问题。输出格式JSON对象包含answer和confidence两个字段。约束条件只能基于文档回答文档没有提到就说“手册中未提及”。示例演示给1到2组输入输出对应示例。边界处理如果用户问题与文档无关礼貌引导回主题。这种结构化的写法有几个实际好处。一是方便调试哪个环节出问题可以独立修改。二是方便自动化结构化的输入输出让模型输出更容易被程序解析。三是方便迭代你可以在一个配置或模板文件里统一维护这些提示词而不是散落在代码里。我自己踩过一个大坑提示词写得太“自由”。那时候觉得越自然越好加上场景多变很快提示词就变成了一坨互相矛盾的要求。后来痛下决心把提示词全部结构化才找回了掌控感。3.2 Agent编排把一个大任务拆给多个角色Agent不是炫技它是解决“单一Prompt处理不了复杂任务”的方法。复杂任务如果一股脑塞给模型回答质量会明显下降。更合理的做法是把任务拆成多个子步骤每个子步骤由不同的角色或工具来处理。举个具体例子我做过一个“需求文档分析助手”。这个任务如果直接让一个模型输出完整分析报告效果非常差。因为一个模型同时要做理解、检索、提炼、评论、给出建议注意力会被撕成碎片。后来我改成多Agent协作的架构读者Agent负责理解原始需求提取关键实体和约束。检索Agent拿着关键实体去知识库或文档库检索相关资料。分析Agent结合检索结果给出可行性分析和风险提示。报告Agent把前面各步骤的结果汇总成结构化报告。这里有个关键点“Agent”本质上不是另外的模型而是“提示词 上下文 工具”的打包。每个Agent可以共享同一个底层模型但角色设定、输入范围、输出格式完全不同。用户跟这些Agent交互时感受上是在跟一个团队协作而不是跟一个什么都干的大模型对话。实际开发中我建议不要让Agent之间自由对话太多轮否则成本会爆炸。最好的方式是“编排 固定流程”把步骤写死每步的输出作为下一步的输入。这比让多个Agent自由商量再决定怎么做要可控得多。3.3 AI辅助测试开发把模型当作被测系统来管理很多人提到“AI测试开发”就想到“让AI写测试用例”。这确实是其中一块但更重要的层面是把AI应用本身当作被测系统用工程的方法来管理它的输出质量。传统软件的输入输出是确定的AI应用则不是。同一个Prompt模型可能给出不同的答案。这就意味着测试不能用“断言某个具体值”的方式而要用“评分卡回归套件”的思路。我的做法是维护一个评测集里面每条数据包含输入、期望的行为倾向、不应出现的内容。每次修改提示词、换模型、调参数都把评测集完整跑一遍逐条记录输出出现的问题类型。输出质量的评测可以考虑几个维度相关性回答有没有切中问题。完整性该覆盖的点有没有覆盖到。合规性有没有出现越权、有害或与事实不符的内容。格式正确性该输出JSON的时候有没有输出纯文本。稳定性多次询问相近问题回答风格和结论是否一致。有了这套评测机制AI应用才算真正迈进了“可测试、可回归”的门槛。没有评测机制的AI项目本质上还是实验不是工程。4. 实操过程与核心环节实现4.1 一个典型场景的完整配置示例下面我拿“基于产品文档的问答系统”作为例子把核心环节的代码骨架写一遍。这套东西不算复杂但踩坑点都隐藏在细节里。先是最基础的模型调用我习惯用最简的方式起步from openai import OpenAI client OpenAI() def ask_model(system_prompt, user_content): resp client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: system_prompt}, {role: user, content: user_content} ], temperature0.2, max_tokens1024, response_format{type: json_object} ) return resp.choices[0].message.content这里有两个容易忽视的点。第一个是temperature0.2不是随便设的。问答类任务要求稳定一致温度越低输出越保守。如果要做创意写作或者头脑风暴再调高到0.8甚至1.0。第二个是response_format让模型强制输出JSON对象这样下游程序解析成本会低很多。然后是提示词的拼装。我不用长长的字符串拼接而是用模板占位SYSTEM_PROMPT 你是一位熟悉公司产品手册的资深客服。 请严格依据context标签内的文档内容回答用户问题。 【输出要求】 必须输出JSON对象字段如下 - answer: string类型对用户问题的回答。 - confidence: 0到1之间的float表示回答的置信度。 【约束】 - 如果文档中没有相关内容answer输出手册中未提及相关内容。 - 不要输出任何文档中不存在的信息。 【文档】 context {context} /context 这个提示词模板放在单独的配置文件中不直接散落在业务代码里。以后要改语气、加约束只要改这一个文件不需要翻代码。4.2 把外挂知识库真正跑通RAG的完整链路当时遇到的问题很典型产品文档更新快模型不知道新版本的变化。直接把全部文档塞进上下文窗口既不现实效果也差。所以我在问答系统里接入了RAG链路。RAG的核心思路是不把所有内容给模型只给与问题最相关的那一部分。实现起来分三步。第一步把文档切块并向量化入库from openai import OpenAI import chromadb client OpenAI() chroma_client chromadb.Client() collection chroma_client.create_collection(product_docs) def embed_text(text): resp client.embeddings.create( modeltext-embedding-3-small, inputtext ) return resp.data[0].embedding # 假设docs是切好的文档块列表 for i, doc in enumerate(process_docs()): vec embed_text(doc) collection.add( ids[str(i)], embeddings[vec], documents[doc] )第二步收到用户问题时先去向量库里面召回最相关的文档块def retrieve_context(query, top_k4): query_vec embed_text(query) results collection.query(query_embeddings[query_vec], n_resultstop_k) return \n.join(results[documents][0])第三步把召回结果作为上下文填充到提示词模板的{context}位置再调用模型。这里有几个细节要提醒。文档切块的大小需要反复试。切得太小语义不完整切得太大召回的噪音多、token成本高。我一般先按段落切段落太长的再按句群切最后看召回效果来调整。另外召回结果不一定要全部塞给模型。我先做一次粗召回再用一个轻量判断来剔除与当前问题无关的块这样上下文更干净回答也更准。4.3 Agent编排的代码骨架再来看Agent编排。一个简单的协作流程我通常这样组织agents { reader: { system: 你是需求文档阅读助手提取关键实体和目标约束。, output_key: entities }, searcher: { system: 你是知识库检索助手根据实体信息检索相关文档并返回检索摘要。, output_key: search_summary }, analyst: { system: 你是资深分析师结合检索摘要给出可行性分析与风险点。, output_key: analysis } } def run_pipeline(input_text): state {input: input_text} for name, cfg in agents.items(): response ask_model( cfg[system], build_agent_input(state, name) ) state[cfg[output_key]] response return state每个Agent的输入来自前序步骤的输出形成一个固定流程。这里没有让Agent“自由商量”而是把整个流程串成管道。这样做的好处是每一步都能单独测试、单独替换、单独加日志。实操中我还会给每一步增加“重试机制”。比如searcher输出格式不对就解析失败触发一次修正请求。修正请求的提示词也很简单“你上次的输出格式不符合要求请只输出JSON对象。”这种小机制能显著提升整体成功率。4.4 上线前的评估表格上线之前我建立了一套简易评估表。你完全可以照抄使用用例编号用户问题期望行为实际输出问题类型QA-001产品支持哪些支付方式准确列出不编造列出了信用证、信用卡无关编造QA-002退款周期多久引用手册中条款回答准确格式规范通过QA-003如何联系技术支持引导到官方渠道提供了错误邮箱信息错误QA-004你们能开发信息系统吗礼貌引导回主题输出“手册未提及”通过每个用例至少要跑三遍因为模型有随机性。如果有任何一遍出现问题就要把问题类型记录下来集中分析。经常看到的问题有编造事实、遗漏关键点、格式错乱、语气不一致。这些问题的根因各异有的是文档切块太碎导致上下文缺失有的是提示词约束不够硬有的是模型本身能力不足。5. 常见问题与排查技巧实录5.1 模型输出不稳定先别急着骂模型遇到模型输出不稳定我现在的第一反应是先检查三样东西温度设置、上下文内容、提示词约束强度。温度过高是常见原因。问答类系统我默认0.2几乎很少超过0.4。如果你发现系统“偶尔跑偏”先看是不是有人把temperature调高了。上下文内容不稳定是另一个大坑。比如RAG召回结果时好时坏导致模型接收到的文档片段每轮不一样回答自然就不稳定。这种情况要去检查召回排序逻辑可以尝试提高top_k数值或者对文档切块方式做调整。最后才是提示词约束强度。如果模型中英文混杂或者输出多余文字就在提示词里明确加上“必须使用中文回答禁止输出任何解释性文字”。约束越明确模型跑偏的可能性越低。5.2 成本失控一个真实案例我见过最夸张的成本失控是一个做日报生成的工具。提示词里把用户过去24小时的所有操作记录全部塞进去再加上各种历史汇总单次请求token量轻松上万。结果一个月成本直接爆掉。排查下来问题出在“上下文越长越准”的错误认知上。实际上模型不会因为塞入大量历史记录就变得更聪明反而会因为注意力分散而容易忽略真正关键的信息。解决方案是分两步走先做一次“历史摘要”把冗长的原始记录压缩成要点再把压缩后的要点作为上下文传给主模型。这样既保留了关键信息又把token开销降到原来的十分之一以下。另外建议给所有上线接口都加上token用量监控每天看一眼每个功能的平均消耗。成本问题不监控爆炸只是时间问题。5.3 格式解析失败别让异常堆在调用层AI输出格式异常是高频问题。明明要求输出JSON模型就是多输出一段解释性文字。如果在代码里用json.loads直接解析就会当场抛异常。我的做法是在解析之前先做一层“清洗”先用正则把代码块标记比如 json去掉。再尝试从文本中截取第一个{到最后一个}之间的内容。如果仍然无法解析调用一次修正提示“你刚才的输出没有遵循JSON格式要求请只输出合法JSON。”这套小逻辑看似简单却能把格式解析成功率从85%左右提升到99%以上。很多看起来是“模型问题”的故障其实是调用方没有做足够的容错设计。5.4 上下文污染多个任务混用同一个会话我踩过的另一个坑是“对话历史上下文污染”。用户开启一个新对话时因为程序复用了某个全局会话列表导致模型带着上一轮对话的上下文来回答新问题输出一些莫名其妙的内容。排查思路是每一轮对话都应该有独立的session_id上下文存储也按session维度和时间窗口隔离。如果你的系统涉及多个不相关业务场景最好按场景创建不同的system prompt不要一套提示词到处套用。这个问题的隐蔽性很强因为单测的时候永远发现不了只有当真实用户在连续操作几次之后才会触发。一旦出现用户会觉得这个AI“智力不稳定”甚至“是不是有人在背后人工回复”。实操心得我从零到一这一路如果让我提炼几个最关键的建议我会说第一不要从“我要做一个AI产品”开始而是从“我要解决一个具体问题”开始。前者会让你陷入技术选型里出不来后者会让你自然地找到技术方案。第二把评测当作第一优先级。没有评测集你后续所有优化都是盲人摸象。我每次做AI项目第一周一定会把评测集搭出来哪怕只有30条真实数据也足够支撑后续迭代。第三提示词、上下文、模型能力三者是联动的。遇到效果不好优先调整上下文组织方式其次优化提示词结构最后才考虑升级模型。盲目换更大模型很多时候性价比极低。最后分享一个我常用的习惯每次做完一个阶段的改动都会把评测集跑一遍然后记录“改动前 vs 改动后”每类问题的数量变化。这样每轮迭代到底是变好了还是变差了一目了然。这套做法让我避开了无数“感觉改好了上线就翻车”的坑。从零开始学AI工程最大的收获不是学会了某个工具而是形成了“发现问题 - 定位根因 - 设计实验 - 验证迭代”的闭环。有了这个闭环你面对新的场景、新的模型、新的业务时心里不会慌知道下一步该做什么。
返回列表