
1. 为什么“从零开始”这么有吸引力做AI工程这件事我第一次被问最多的问题就是“现在各种框架和低代码平台都这么成熟了直接拿来用不就行了为什么要自己从零搭一遍”我能理解这种想法毕竟这个领域的工具链一年比一年丰富拖拽式编排、一键微调平台层出不穷好像谁都能在几个小时内“做出”一个AI应用。但真干过几轮实际项目就会发现用别人封装好的东西和真正理解自己系统里每一层发生了什么完全是两码事。从零开始做AI工程不是要排斥现成工具而是要亲手把那些“黑盒”拆开搞懂里面是怎么运转的明白自己做决策时到底在选什么。什么叫“从零开始”放到AI工程这个语境下就是你要独立设计一套完整方案从需求拆解、数据处理、模型接入、提示词编排到结果校验、异常兜底、性能观测和部署迭代每一个环节都由你亲自定义和实现。市面上确实有大量工具能包办其中一环但当你尝试从空白目录开始一点点把自己的工程搭起来你会被迫回答很多平时忽略的问题比如“这个模型返回的结果真的可以用吗”“用户重复提交时我怎么处理”“模型挂了怎么办”。这些问题的答案恰恰才是工程能力的真正分水岭。这篇文章适合谁我的核心读者群大概有两类。一类是刚接触AI应用开发的新人有点编程基础但没系统走完一个完整项目想搞明白到底哪些是真正绕不开的另一类是已经在用现成平台或封装库做功能的从业者希望补上底层理解不再只是“调接口、看效果”以后遇到问题能自己定位和修复。我在这篇分享里会尽量用实际案例和代码来讲不是说教就是把你带入一个真实的项目现场跟着我从零走一遍。顺带说一句如果你期望的是一个“十分钟搞定一切”的速成教程那这篇文章可能不适合你。我会反复强调设计、验证和兜底这些看起来慢、看起来“不需要”但到了线上环境它们往往比某个花哨的模型调用更值钱。从零开始的真正价值不在于让你从头发明轮子而在于让你知道自己手里拿的轮子到底是怎么造出来的。2. 核心概念AI工程不只是写提示词2.1 提示工程与大模型基础很多新人一上来就问“提示词怎么才能写好”但我建议把“提示工程”放回它本来的位置它只是整个AI工程链条里很靠前的一环远未覆盖系统的复杂性。提示词决定了模型解读任务的方式但决定不了数据质量、调用稳定性、反馈闭环和系统性能。如果把AI工程比作盖房子提示词更像是一张户型图上的标注说明画得再细你仍然得先有地基、墙体和管线。大模型的基础能力有几个关键点你必须心里有数。第一是上下文窗口它限制了你能放进一次请求的资料总量工程上经常需要通过摘要、分片、检索来控制输入长度。第二是温度等采样参数它们控制输出的随机程度做客服机器人时就该调低做创意文案时可以调高一些。第三是输出格式的约束能力虽然模型能听懂“请输出JSON”但没有强约束时它还是会偶尔夹带解释文字这部分工程上要有缓冲和处理预案。对这些基础特性的理解引自公开技术资料中的通用原理决定了你后续在流程设计上能否合理决策。再说回提示词本身我有一套比较朴素的写法可以概括成四个层次角色定义、任务描述、约束条件、输出示例。角色定义让模型明确立场比如“你是资深数据分析师”任务描述说清楚要做什么约束条件划出边界比如“不要编造数据”“只基于给定材料回答”输出示例则直接给出你期望的结构。实际做下来第4层往往最管用因为大模型对“你想要什么”的理解很多时候是依赖“你能给什么样子”的例子。2.2 提示修辞与工程边界的区分真正做过一段时间你会意识到提示词写得再精妙也不是AI工程的全部。工程的核心是把不可控的模型行为装进一个可控的系统框架里。比如模型输出的格式漂移光靠提示词约束不靠谱我一般在系统代码里加一层解析函数把返回文本里的JSON段提取出来解析失败就走重新生成的逻辑再不行就直接返回人工兜底提示。这种思维在AI工程中特别重要术语叫“防御性设计”。另外不少教程会鼓吹“用自然语言就能实现全自动开发”真实落地时你会发现越是在流程严谨的场景里越不能把关键判断完全交给模型。我的经验是模型适合做单点能力比如摘要、分类、抽取、改写而全链路编排、权限控制、多轮状态管理这类事情最终还是要落在严谨代码上。说白了人负责搭骨架模型负责填血肉两者边界清晰项目才不会“跑着跑着变成玄学”。3. 从零到一设计并搭建一个可运行的AI工程项目3.1 项目目标与技术选型我从零做过的第一个完整AI项目是从空目录开始搭一个典型的Agent式文档问答系统用户上传PDF资料系统负责切片、索引、召回最终回答问题时给出有据可查的答案。这个项目把AI工程里最核心的要素都覆盖了语言模型调用、数据预处理、向量检索、结果校验、性能优化。我选这个例子来展开因为它既有足够代表性又不会复杂到让人跟不动。技术栈我没有选很重的东西核心就是Python FastAPI做服务层OpenAI兼容接口做模型底座一套本地向量数据库处理文档索引再加一个最基础的前端页面做交互演示。选它的理由很简单这套组合在当下生态里最通用、资料最全、且能让你看清楚每个环节的边界。有人可能会问为什么不直接用一个编排平台我在3.1开头说了平台会隐藏很多中间细节当你想理解“为什么慢”“为什么不准”“为什么流量翻倍就挂”时还是得自己掌控这些底层依赖。3.2 服务端框架与依赖管理我习惯先搭服务骨架把一个最小的FastAPI应用跑起来确认端口、路由、健康检查都通了再往上加AI逻辑。下面这段就是最基础的一个版本from fastapi import FastAPI app FastAPI(titleai-engineering-from-scratch) app.get(/health) def health_check(): return {status: ok}依赖管理这块我要多说两句。Python项目的依赖千万不要一股脑全装进全局环境后面版本冲突能把人折磨死。我一般用pyproject.toml配合虚拟环境来固定版本每个项目独立一套解释器和依赖树换机器迁移的时候直接整包拉起来省心很多。项目初期就定好Python版本我推荐3.11以上新特性和第三方库的适配度都更好。3.3 文档解析与切片策略文档问答里第一个容易翻车的环节是文档解析。PDF看着规整但里面的表格、页眉页脚、双栏排版解析出来经常是乱的。我试过很多库最终用了一款开源的文档解析服务能比较干净地抽出版本、章节和连续段落。处理逻辑是先把各类文件统一转成纯文本再做清洗去掉无意义的空行、修正断行问题、过滤掉页眉页码。清洗之后的文本要切片这一步直接决定了后续检索的准确率。切片策略没有万能解我实践下来的原则是“按语义块切而不是按固定长度硬切”。比如一个章节下的小标题和它下面的几段最好分到同一个切片里表格单独成片超长段落可以二次切分但相邻部分要保留overlap重叠避免检索时因为上下文截断而丢失关键信息。我常用的切分大小在300到800个词之间具体参数要看你的文档领域和模型上下文能力这个没有标准答案建议多做几组试验用检索质量去反推最优值。3.4 向量化与检索链路切片之后要做的就是把文本块转成向量存入向量数据库。选型上我偏向本地优先的策略数据不需要传到外部服务适合开发和测试阶段的快速迭代等到数据量上来了再考虑把索引迁移到专业化的线上向量服务。向量化的模型选择也是一个工程决策通用场景用常见的嵌入模型就够垂直领域则可以收集一批领域数据做微调但这个成本高通常只有到了需要显著提升召回质量时才值得做。检索链路组装起来大概是收到用户问题先对问题做一次改写或扩展比如“X产品的退款政策”补成“X产品在什么条件下可以退款、退款的流程和时限”然后拿改写后的内容做向量检索取回top-k个相关切片再拼进提示词上下文。很多初学者容易忽略“检索再排序”这一步我建议在向量召回后多加一个重排环节用模型对候选片段打分选出和问题最匹配的一到三段这样回答质量的提升非常明显成本增加却很微小。4. 核心细节解析与工程实操4.1 提示词模板与结构化输出进入AI部分后第一个要设计的细节就是提示词模板。模板不是简单往字符串里塞变量它需要严格区分“系统指令”“用户输入”“参考资料”三个区域。系统指令写模型的角色和长期约束比如“你是一个帮助用户解答产品问题的客服助手回答必须基于给定资料资料中没有信息时明确说不知道”用户输入区放当前问题参考资料区放检索回来的上下文片段。结构化输出方面我把自己的做法直接分享出来如果业务下游需要拿输出继续做逻辑判断就明确要求模型只返回一段JSON并在解析时用正则手段提取JSON块而不是直接对整段输出做json.loads因为模型偶尔会输出一些额外解释。解析失败就进入重试逻辑重试两次还失败就降级为普通文本模式返回给用户保证服务不中断。我贴一段核心示意代码你感受一下import json, re def extract_json_from_text(text: str) - dict: 从模型输出中提取JSON对象避免格式漂移导致解析失败 pattern r\{.*\} matches re.findall(pattern, text, re.DOTALL) for match in matches: try: return json.loads(match) except json.JSONDecodeError: continue raise ValueError(no valid json found)这个函数不是银弹但它在真实环境中帮我挡掉了大量解析问题是我个人项目里的必备工具。4.2 关键参数选择与成本控制模型参数里我日常最关注四个模型名、temperature、max_tokens、top_p。温度字段默认给0.2用于事实性问答如果任务偏创意我再酌情调到0.7到0.9max_tokens要按任务预留回答太短可能截断回答太长又会拖慢响应。top_p我通常保持默认不做太多改动除非有特别强烈的风格要求。成本控制这件事做成期的工程尤其容易忽略。很多人一上来就调大模型回答一次花几毛钱几千tokens看着不多量一上来就肉疼。我常用的省钱手段有几个缓存高频问题的答案、用小模型做意图分类和文档粗筛、重复内容不重复向量化。这些手段都不复杂但组合起来成本能降一个数量级而且对用户体验几乎没有损伤。5. 实操过程与核心环节实现5.1 构建完整问答接口我把整个问答流程串成一个服务接口代码结构大致如下from fastapi import FastAPI, UploadFile, Form from pydantic import BaseModel class AskRequest(BaseModel): question: str history: list [] app.post(/ask) async def ask_question( question: str Form(...), session_id: str Form(...), ): # 1. 检索相关文档片段 fragments retrieve_fragments(question) # 2. 组装提示词上下文 prompt build_prompt_with_context(fragments, question) # 3. 调用模型并解析结果 answer call_llm_with_fallback(prompt) # 4. 记录日志用于后续质量评估 log_interaction(session_id, question, fragments, answer) return {answer: answer}这个接口看起来简单但每个步骤内部都藏着细节。检索函数为什么要先做问题改写因为用户口语化问题直接拿去向量检索经常搜不到好结果。组装环节为什么要明确划分上下文和问题因为模型容易把不同的输入源混在一起输出时就会串味。日志记录为什么不能省因为判断一个AI系统的效果靠的不是感觉而是回头能从日志里看到什么组合召回了什么片段、产出了什么答案。5.2 从开发到上线要补的工程课本地跑通不算完上线前我通常会补上三件事接口限流、结果校验、监控告警。接口限流保护的是你的模型成本预算防止脚本和异常流量把账号打爆结果校验保护的是用户信任模型输出可能胡乱或跑偏要在返回前做一次规则判断监控告警则是保障运维安心服务调用失败率、平均延迟、token消耗量这些指标用一套简单的日志统计就能看到趋势。我在项目里用一套轻量级的可观测组件把每次调用的关键数据打点上报再用一个看板展示基本能做到秒级发现问题。6. 常见问题与排查技巧实录6.1 高频问题速查表我把自己从零搭建过程中遇到过的典型问题整理成了一张表每一条背后都有实际踩坑背景不是泛泛而谈问题现象根因分析解决方案回答质量不稳定时好时坏检索召回片段不精准上下文混乱引入问题改写 增加检索后重排环节模型输出JSON频繁解析失败格式漂移夹带解释性文字用正则提取JSON块 重试降级策略接口响应特别慢同时请求多个模型调用串行等待把相互独立的调用改成并发同样的文档换个PDF就检索不到内容解析环节依赖版式表格和扫描件处理不足升级解析工具、加OCR兜底、清洗策略标准化用户多轮对话中模型忘了前文上下文保留策略过于简单引入摘要记忆机制控制历史长度线上出现短时间请求暴涨缺少限流成本失控接入Rate Limiter按用户维度和IP维度双限制向量检索一直返回某个固定文档同质化片段过多检索被“胖文档”淹没调整切片策略限制单文档召回权重6.2 独立AI工程师的避坑经验最后集中说几条我觉得特别重要的经验都不是从文档里能直接查到的。第一不要急着上复杂架构先做出一个能跑的端到端最小闭环再去一点点加功能这个顺序能让你少掉一半头发。第二工程里的每一层都给自己留“逃生门”——模型解析挂了有兜底、检索结果为空有兜底、整个服务不可用也要有缓存方案系统能不能撑住用户压力靠的往往不是你主链路写得有多好而是兜底设计得有多密。第三尽量用可量化的指标去评价系统而不是主观感觉“回答挺好的”给自己建立一套日志和评估脚本每次改动都能对比前后效果这样迭代才有方向。我还有一个小习惯每次模型升级换代时都先将一个固定的测试集跑一遍观察输出风格和质量变化然后才考虑是否切换。模型层的变更影响面其实很大轻率升级可能让线上表现“莫名其妙变差”有了固定测试集你至少能快速定位是否是模型侧行为漂移导致的。7. 这条路还能怎么往下走写完这些我特别想说一句心里话从零起步做AI工程最大的收获不是“我会调接口了”而是你建立了一套属于自己的判断体系。以后再看到新框架、新模型你不会只是跟风替换而是会先问自己它在哪一层解决什么问题替换的代价是什么对我的系统哪些指标会真正变好很多人觉得AI工程的技术门槛主要在模型待久了你会发现真正的门槛在工程整合能力把数据、模型、代码、用户体验焊成一个可靠的整体。这个能力无法靠“看教程”获得只能靠亲手踩坑、亲自修错、反复打磨。希望这篇分享能给你一张还算清晰的地图接下来的路还得你自己一步步走。