Stone Soup AI:组装式AI应用开发范式与工程实践

发布时间:2026/8/30 22:35:09
Stone Soup AI:组装式AI应用开发范式与工程实践 如果你在 2024 年关注过 AI 工程圈一定会反复听到一个词Stone Soup AI。它字面意思是“石头汤 AI”这个名字本身来自一个经典寓言——一个陌生人带着一口空锅走进村庄说要煮一锅石头汤。村民们好奇你带一根胡萝卜我带一把洋葱他拿几块土豆最后真的煮出了一锅浓汤。2024 年的 AI 应用开发越来越像这个故事真正撑起一个产品的往往不是某个“神秘大模型”而是把已有的组件一件件放进锅里的人。这里想给出一个明确判断Stone Soup AI 并不是某个具体的开源仓库也不应该被理解成“用 AI 生成一切”的口号。它更准确地说是一种面向 2024 年 AI 工程现实的开发范式——模型能力已经由大厂 API 或开源模型提供普通开发团队真正要做的不是从零训练模型而是像煮石头汤一样把 LLM、Embedding、向量数据库、工具调用、服务编排这些“食材”组装成一个可运行、可维护、可评估的业务系统。这篇文章会从概念到代码把 Stone Soup AI 这套思路完整落地。你会看到为什么 2024 年做 AI 应用的核心矛盾不是模型不够强而是工程化不够顺手一个最小 AI Agent 长什么样一个不依赖重型中间件的 RAG 示例怎么写以及把它封装成 FastAPI 服务后如何验证、如何排错、如何在生产环境避开那些“看起来不大炸起来很疼”的坑。无论你是后端工程师、算法工程师还是刚准备进入 AI 应用开发的初学者这篇文章都值得收藏备用。1. Stone Soup AI这篇文章真正要解决的问题先说结论2024 年普通团队做 AI 应用最大的痛点不是“没有模型可用”而是“不知道从哪开始”。你打开技术社区看到的是 Agent、RAG、微调、多模态、向量数据库、LangChain、LlamaIndex、模型部署、AI 应用开发学习路线……概念一个接一个但回到自己的项目里你还是不知道第一行代码该写在哪里。Stone Soup AI 要解决的正是这个“第一行代码”的问题。它不要求你从零训练一个 ChatGLM 或 LLaMA不要求你先维护几个 GPU 集群也不要求你一开始就设计一个复杂的多智能体协同系统。它建议你先搭一口空锅——也就是一个最简可运行的系统骨架然后根据业务的真实反馈把需要的“食材”一件一件加进去。从技术分工看2024 年开发团队其实只需要聚焦四件事一是明确业务问题到底是什么类型是文本分类、信息抽取、开放问答还是需要多步工具调用的 Agent 任务二是选好模型入口是通过 API 调用还是基于开源模型做私有化部署三是设计好上下文也就是如何把用户输入、检索资料、工具返回结果组合成模型能理解的 messages四是做好评估与控制保证模型输出在业务上是可接受的。换句话说2024 年做 AI 产品难点已经从“模型训练”转移到了“系统设计”。如果你还在纠结“我要不要训练一个自己的大模型”大概率是方向搞错了。更现实的路径是把别人的“石头”拿过来煮自己的“汤”。1.1 适合认真读这篇文章的人后端工程师想给自己的系统加入 AI 能力但不想被概念淹没需要一条可执行的接入路径。算法工程师熟悉模型原理但不熟悉工程侧的服务封装、向量检索、接口验证需要补齐工程短板。技术管理者 / 产品经理需要判断一个 AI 项目该用什么技术栈、需要多少成本、哪些功能应该先用现成方案快速验证。AI 初学者已经会调用 ChatGPT但不知道“AI 应用开发”和“单纯的 API 调用”到底差在哪里。如果只是打算“玩一玩 AI 工具”这篇文章可能偏重了但如果你要做一个真正给用户用的 AI 功能下面这些内容是绕不开的。2. 核心概念Stone Soup AI 的三种理解方式要先理解 Stone Soup AI不能只看字面。在 2024 年的技术语境里它至少可以拆成三层意思。第一层是“组装优于训练”。这个理念最早在开源社区很常见不需要每个人都从零写一遍基础组件把别人已验证过的组件拿过来按自己的业务场景拼装比自己“闭门造车”靠谱得多。大模型时代这一层被进一步放大了——你不能自己从头训练一个 GPT-5 级别的大模型但你可以把模型 API、向量检索、业务数据库、工具函数组装成一个外人看起来“很 AI”的系统。第二层是“渐进式构建”。石头汤的故事里那口锅最开始只有水和石头味道寡淡但随着越来越多村民贡献食材汤越来越好喝。AI 项目的正确启动方式也应该是这样第一天只需要一个最小的可运行 Demo哪怕只调用一次模型 API 并打印结果第二周再接入真实数据做检索增强第一个月再加评估、监控、灰度。不要一开始就追求“宏大架构”否则大概率会在第二周因为复杂度膨胀而放弃。第三层是“开放协作”。石头汤能煮成靠的是每个村民都愿意贡献一点。今天 AI 工程的可用组件非常丰富开源模型、RAG 框架、向量数据库、可观测工具、评测集几乎每一层都有成熟方案。团队真正要做的是定好接口标准让这些组件能互相配合而不是所有事情都自己做。2.1 与“从零训练模型”的差异很多人一谈到“AI 项目”第一反应是“我要训练模型”。这个反应在 2018 年合理在 2024 年已经过时了。下面用一张表看清差异维度从零训练 / 微调大模型Stone Soup AI 组装式开发核心成本数据清洗、GPU 算力、训练调参系统集成、上下文设计、工程交付团队要求算法团队为主工程团队配合工程团队为主算法聚焦评测启动速度数周到数月数小时到数天迭代方式重新训练或微调替换模型 / 增加工具 / 优化检索风险点算力成本高、数据合规风险大模型输出不稳定、组件之间兼容性适合情况特定领域效果要求极高、数据敏感大多数业务场景的技术验证和快速上线这里并不是说微调和训练没有价值而是提醒团队先判断自己到底处于哪个阶段。绝大多数业务场景在用户量和数据量都没有被验证之前贸然投入训练是一笔高风险投资。更稳妥的判断是先组装跑通业务闭环再评估哪些环节真正需要定制模型。2.2 Stone Soup AI 与 AI Agent、RAG 的关系AI Agent智能体和 RAG检索增强生成是 2024 年两个高频概念它们恰好都属于 Stone Soup AI 这种组装式开发范式里的“组件”。RAG 解决的是“模型不知道业务知识”的问题。模型是通用能力你的业务数据是私人资产RAG 通过先检索再生成的方式把相关资料塞进上下文让模型基于资料回答。AI Agent 解决的是“模型只会聊天、不会做事”的问题。它让模型可以调用外部工具比如查天气、查数据库、创建工单从而从“聊天机器人”升级为“业务助理”。编排层解决的是“多个组件如何协作”的问题。一个完整的 AI 应用往往同时需要 RAG 和 Agent还需要流程控制、权限校验、超时重试。在后面的示例里你会看到这三个层面如何落到代码中。你会发现它们并没有想象中那么神秘。3. 开始之前的架构设计先画锅再放食材“先把锅架起来”听起来很朴素但它是 Stone Soup AI 中最重要的一步。很多项目出问题不是因为某个组件不行而是因为锅里放的食材互相不兼容。在实际项目中我更推荐把 AI 应用按下面这个分层结构来规划接入层面向用户或上游系统的接口常见形态是 REST API、WebSocket、消息队列消费者。这一层负责参数校验、鉴权、限流。编排层核心业务逻辑所在决定“先做什么、后做什么”。它可以是简单的 if-else也可以是基于 Agent 的循环调用重点是把 LLM 的输入输出和业务状态管理好。模型层LLM 对话、Embedding 向量化、重排序模型。这一层要先定义好统一接口方便以后切换模型服务。存储层业务数据库、向量数据库、缓存。向量数据库负责存文档切片和 Embedding业务数据库负责存用户状态和交互记录。可观测层日志、链路追踪、模型输出评估。没有这一层你在生产环境里根本没法回答“模型答得好不好”这个问题。从调用链上看一个典型的请求是用户请求进来后编排层判断需要哪些上下文先通过 Embedding 做向量检索把相关资料拼到 prompt 里再调用 LLM 生成回答最后把回答返回给用户同时记录日志。如果需要工具调用就在 LLM 返回 tool_calls 后执行本地函数并把执行结果回传给模型让模型生成最终回答。设计阶段还有三个原则值得记住第一最小依赖原则。能用标准库和轻量库解决的问题就不要引入重量级编排框架。很多团队一上来就引入 Agent 框架结果被抽象层里隐藏的 bug 折腾得焦头烂额。起步阶段先自己写 50 行代码把链路走通再考虑是否引入框架。第二接口可替换原则。所有外部依赖都要收敛到一个薄薄的封装层后面尤其是模型 API。这样将来换模型、换 Embedding 服务不需要改业务代码。第三成本显性化原则。2024 年很多 AI 项目的失败不是技术达不到而是账单先到了。设计时就该考虑每个环节的 token 消耗包括 prompt 里的系统提示词、检索回来的上下文、模型多次调用造成的费用累积。4. 环境准备与基础配置下面开始实际操作。本机环境假设是 macOS 或 LinuxWindows 也可以运行只是激活虚拟环境的命令稍有不同。需要提前安装 Python 3.10 及以上版本以及 pip。先创建一个项目目录并初始化虚拟环境mkdir stone-soup-ai-demo cd stone-soup-ai-demo python3 -m venv venv source venv/bin/activateWindows 环境下的激活命令是venv\Scripts\activate4.1 安装依赖为了让示例保持轻量只安装下面这些库# 文件路径requirements.txt python-dotenv1.0 openai1.30 numpy1.26 fastapi0.110 uvicorn[standard]0.29安装命令pip install -r requirements.txt这里用 openai 库是因为它已经是事实上的“模型 API 客户端标准接口”。即使你使用的是其他提供 OpenAI 兼容接口的模型服务也可以用同一个 SDK 接入只需要修改环境变量。4.2 配置 API 密钥与模型参数在项目根目录创建.env文件内容如下# 文件路径.env OPENAI_API_KEYsk-your-key-here OPENAI_BASE_URLhttps://api.openai.com/v1 LLM_MODELgpt-4o-mini EMBEDDING_MODELtext-embedding-3-small需要特别提醒.env文件一定不能提交到 Git 仓库。建议把.env加入.gitignore# 文件路径.gitignore .env venv/ __pycache__/如果你的模型服务不是 OpenAI 官方只要它提供 OpenAI 兼容的/chat/completions和/embeddings接口就把OPENAI_BASE_URL改成服务方提供的地址。这是 2024 年做 AI 工程最值得养成的习惯把模型服务当成可替换的“外部资源”而不是把代码写死到某一家厂商。5. 从零拼装第一个 AI Agent这一节的目的是用最少的代码跑通一个带工具调用能力的 AI Agent。它会演示整个 Stone Soup AI 最核心的流程用户输入 → 模型判断需要工具 → 执行工具 → 把工具结果回传给模型 → 生成最终回答。5.1 核心流程拆解2024 年主流大模型已经原生支持 Function Calling工具调用。这意味着模型不再只输出文本而是可以输出一个结构化的“调用请求”比如我想调用get_weather参数是{city: 北京}。你的服务端拿到这个请求真正去执行本地函数再把函数的返回结果作为一条工具消息发给模型。一次完整的 Agent 交互如下用户提问“北京今天天气怎么样”系统把用户问题发送给模型并告诉模型可用的工具列表。模型返回一个 tool_calls内容是调用get_weather(city北京)。系统执行本地函数get_weather(北京)得到结果。系统把函数结果添加到消息序列里再次发送给模型。模型基于工具结果生成最终的自然语言回答。注意模型本身不会真正调用任何外部系统它只是“决定调用哪个工具并生成参数”。真正执行工具的是你的代码。这个边界想清楚就不会对 Agent 产生“什么都能干”的误解。5.2 完整示例代码创建weather_agent.py# 文件路径weather_agent.py import json import os from dotenv import load_dotenv from openai import OpenAI load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) def get_weather(city: str) - str: 模拟查询天气的工具。真实项目中这里应该调用第三方天气服务。 fake_data { 北京: 晴25℃, 上海: 多云28℃, 广州: 小雨30℃, } return fake_data.get(city, f暂未收录 {city} 的实时天气) def call_agent(user_input: str) - str: tools [ { type: function, function: { name: get_weather, description: 查询指定城市当前的天气情况, parameters: { type: object, properties: { city: { type: string, description: 城市名称例如北京, } }, required: [city], }, }, } ] messages [{role: user, content: user_input}] response client.chat.completions.create( modelos.getenv(LLM_MODEL, gpt-4o-mini), messagesmessages, toolstools, tool_choiceauto, ) message response.choices[0].message messages.append(message) if message.tool_calls: for tool_call in message.tool_calls: args json.loads(tool_call.function.arguments) result get_weather(**args) messages.append({ role: tool, tool_call_id: tool_call.id, content: result, }) second_response client.chat.completions.create( modelos.getenv(LLM_MODEL, gpt-4o-mini), messagesmessages, toolstools, tool_choiceauto, ) return second_response.choices[0].message.content return message.content if __name__ __main__: print(call_agent(北京今天天气怎么样))这段代码虽然只有 60 行左右但它已经具备了 Agent 的最基本结构工具定义、模型调用、工具执行、结果回传。后面无论你接入多少个工具核心骨架都不会变。5.3 运行与预期效果运行命令python weather_agent.py正常情况下你会在终端看到类似下面的输出北京今天晴25℃体感温度很舒适。这里真正容易踩坑的地方是如果模型返回的tool_calls参数为空说明模型认为不需要调用工具此时要直接返回message.content。另外如果tool_call.id回传错误服务端会报错“tool call id mismatch”这也是新手最容易遇见的 Agent 调试问题。6. 第二步用 Embedding 搭建知识库问答服务普通对话能力只解决了“会说话”的问题业务场景更常需要的是“懂业务”。比如你的系统里有一批内部手册你希望用户提问时AI 能基于手册内容回答而不是自己编造。这就用到了 RAGRetrieval-Augmented Generation检索增强生成。6.1 为什么需要 RAG大模型的参数里学不到你公司的私有知识。即使你喂了很长一段文档模型也受限于上下文窗口而且每次请求把全部文档塞进去成本不现实。RAG 的思路是先把文档切成小块用 Embedding 模型把每一块转成向量用户提问时把问题也转成向量然后找出语义上最相似的几个文档块只把这几块拼到 prompt 里让模型基于这些材料回答。为了体现 Stone Soup AI 的“渐进式构建”这里先用 NumPy 实现一个最小的本地向量检索不依赖任何重型向量数据库。这个示例用来理解原理完全够用。6.2 一个不依赖向量数据库的最小实现创建simple_rag.py# 文件路径simple_rag.py import os from dotenv import load_dotenv from openai import OpenAI import numpy as np load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) EMBEDDING_MODEL os.getenv(EMBEDDING_MODEL, text-embedding-3-small) def split_text(text: str, chunk_size: int 200, overlap: int 40) - list[str]: 按字符做基础切分生产环境建议换成语义切分。 chunks [] start 0 while start len(text): end min(start chunk_size, len(text)) chunks.append(text[start:end]) if end len(text): break start end - overlap return chunks def build_index(text: str): 把文本切片并生成向量索引。 chunks split_text(text) vectors client.embeddings.create(modelEMBEDDING_MODEL, inputchunks) return chunks, [item.embedding for item in vectors.data] def cosine_similarity(a, b): a np.array(a) b np.array(b) return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))) def search(query: str, chunks, vectors, top_k: int 3): query_vec client.embeddings.create( modelEMBEDDING_MODEL, input[query], ).data[0].embedding scored [ (cosine_similarity(query_vec, vec), chunk) for vec, chunk in zip(vectors, chunks) ] scored.sort(keylambda x: x[0], reverseTrue) return scored[:top_k] if __name__ __main__: docs [ Stone Soup AI 是一种把现成模型、工具和数据组件组装成 AI 应用的方法论。, RAG 是指检索增强生成先检索相关资料再让模型基于资料生成回答。, AI Agent 的核心是让模型可以调用外部工具并自主完成多步任务。, ] chunks, vectors build_index(\n.join(docs)) for score, chunk in search(什么是 RAG, chunks, vectors): print(round(score, 4), chunk)运行命令python simple_rag.py预期输出会显示问题“什么是 RAG”和第二条文档的相似度最高另外两条文档相似度明显更低。这种“先检索再生成”的能力是让 AI 系统基于你私有知识回答问题的地基。6.3 什么时候升级到正式向量数据库上面的示例只适合理解和原型验证。当你的文档量超过几千条、查询并发上来了、需要按标签过滤或者做增量更新时建议升级到专门的向量数据库组件。2024 年常见的可选方案包括方案特点推荐场景Chroma轻量Python 原生适合原型快速验证、单机测试QdrantRust 实现性能好支持过滤中等规模生产环境Milvus分布式能力较强组件较多大规模生产环境pgvector基于 PostgreSQL 的扩展团队已有 PG 技术栈时优先考虑从 Stone Soup AI 的角度看原型阶段的 NumPy 实现和正式阶段的向量数据库本质是同一个接口传入向量、返回最相似的 Top K。提前封装好这个接口后面替换存储层时你的业务代码基本不用改动。7. 完整示例用 FastAPI 封装一个可调用的 AI 接口前面的 Agent 和 RAG 都是命令行脚本真实业务还需要暴露成接口给前端或上游服务调用。这一节用 FastAPI 把 RAG 功能封装成一个POST /ask接口并告诉你如何验证它真的可用。7.1 完整服务端代码创建app.py# 文件路径app.py import os from dotenv import load_dotenv from fastapi import FastAPI from pydantic import BaseModel from openai import OpenAI from simple_rag import cosine_similarity load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) EMBEDDING_MODEL os.getenv(EMBEDDING_MODEL, text-embedding-3-small) LLM_MODEL os.getenv(LLM_MODEL, gpt-4o-mini) app FastAPI(titleStone Soup AI Demo) def embed(text: str): return client.embeddings.create( modelEMBEDDING_MODEL, input[text], ).data[0].embedding class AskRequest(BaseModel): question: str app.post(/ask) def ask(req: AskRequest): # 这里使用一个最小知识库实际项目中应该从向量数据库读取。 docs [ Stone Soup AI 是一种把现成模型、工具和数据组件组装成 AI 应用的方法论。, RAG 是指检索增强生成先检索相关资料再让模型基于资料生成回答。, AI Agent 的核心是让模型可以调用外部工具并自主完成多步任务。, ] query_embedding embed(req.question) scored [] for doc in docs: doc_embedding embed(doc) scored.append((cosine_similarity(query_embedding, doc_embedding), doc)) scored.sort(keylambda x: x[0], reverseTrue) context \n.join([doc for _, doc in scored[:2]]) messages [ { role: system, content: 你是一个知识库助手只能根据提供的上下文回答问题。如果上下文没有依据请明确告知不要自行编造。, }, { role: user, content: f上下文\n{context}\n\n问题{req.question}, }, ] answer client.chat.completions.create( modelLLM_MODEL, messagesmessages, ) return { question: req.question, answer: answer.choices[0].message.content, }这段代码演示了一个非常典型的 RAG 接口将问题向量化 → 与文档向量比较 → 取最相关的上下文 → 拼进 prompt → 让 LLM 生成回答。注意在真实项目中文档向量不应该每次请求都重新生成而应该在服务启动时构建一次或直接存入向量数据库。7.2 启动服务在项目根目录执行uvicorn app:app --reload --host 0.0.0.0 --port 8000看到如下日志说明启动成功INFO: Uvicorn running on http://0.0.0.0:8000 INFO: Application startup complete.7.3 验证接口打开另一个终端用 curl 发送一个测试请求curl -X POST http://127.0.0.1:8000/ask \ -H Content-Type: application/json \ -d {question: Stone Soup AI 是什么}预期会返回一段 JSON结构类似{ question: Stone Soup AI 是什么, answer: Stone Soup AI 是一种把现成模型、工具和数据组件组装成 AI 应用的方法论。 }如果请求失败第一步应该看 Uvicorn 所在终端输出的运行日志。常见错误是 API Key 无效、网络不通、模型名不存在。日志里一般会给出明确的 HTTP 状态码和错误信息比盲目猜测模型效果更有效。8. 常见问题与排查思路从命令行 Demo 到生产环境你会遇到一批规律性的问题。下面这些场景来自 2024 年 AI 工程实践的常见反馈值得提前对照检查问题现象可能原因排查方式解决方案模型返回空内容提示词触发了内容过滤或返回内容未正确解析打印原始 response检查 finish_reason调整提示词检查代码是否读取了正确的字段Tool call 死循环工具结果没有改变对话状态模型反复调用同一个工具设置最大迭代次数打印每次 messages 变化在 Agent 循环中加入 turn_limit 限制提示 tool_call_id mismatch回传工具消息时 tool_call_id 写错或漏写打印完整 messages检查每个 tool 消息严格从 tool_calls 中取 id 回传向量检索结果不相关文本切分过碎或过长Embedding 模型与业务语言不匹配单独测试 search 函数观察相似度分数调整 chunk_size 和 overlap必要时换重排序模型接口启动报错 pydantic 版本冲突FastAPI 和 pydantic 版本兼容性问题查看完整堆栈检查依赖树升级相关依赖保持 requirements 中版本一致上下文超限检索回来的文档过多prompt 太长打印 token 数量参考模型的 context length限制 top_k、缩短文档切片、使用摘要优化模型输出不稳定JSON 解析失败模型没有严格遵循输出格式检查原始输出确认是否被截断使用 response_format 或更严格的 few-shot 示例每次请求都很慢Embedding 和 LLM 调用串行且没有缓存增加耗时日志分析瓶颈对向量和热门回答做缓存必要时并发调用密钥被提交到 Git 仓库.gitignore 未配置团队协作不规范在仓库历史中搜索密钥吊销密钥并轮换配置 .gitignore 和密钥扫描排查这些问题时最重要的原则是“先看日志再看数据最后猜模型”。很多模型表现问题根因其实是上游传进去的上下文不对而不是模型变笨了。9. 最佳实践与工程建议到这里你已经跑通了一个带 Agent 和 RAG 的最小 AI 服务。但“能运行”和“能上线”之间还有一段路要走。下面这些工程建议来自真实项目的通用经验按重要程度排列。9.1 提示词与上下文管理提示词会被反复修改所以它应该作为代码资产来管理。建议把系统提示词、few-shot 示例、检索 prompt 模板单独拆成配置或 Python 常量而不是散落在业务代码里。对每一类提示词至少准备一个自动化用例避免改动一次 prompt 导致另一个场景回归。更重要的一点是不要试图把全部业务背景写进一个超长 system prompt。系统提示词越长模型越容易忽略关键信息token 成本也越高。更好的做法是尽量让业务信息通过 RAG 或工具结果进入上下文系统提示词只负责定原则和约束输出格式。9.2 安全、权限与合规边界2024 年 AI 应用的安全问题重点不是“防止 AI 反抗人类”而是“防止模型被利用产生业务风险”。首先任何 AI 服务都必须做鉴权不能让一个模型接口裸奔在公网上否则很容易被刷爆账单。其次要对用户输入做基本的注入防护模型应该被明确告知不能执行与当前任务无关的指令。最后涉及个人信息或商业敏感数据时尽量优先选择私有化部署或支持数据隔离的模型服务避免敏感信息进入第三方日志。所有需要模型做“决策”的高风险操作都必须有人工确认环节。比如模型判断“应该删除这条数据”系统不能直接执行而是应该生成一个待确认工单由业务人员审核后操作。并且所有带写操作的功能必须先走测试环境验证生产操作要有备份和回滚方案使用最小权限账号不要使用管理员权限。9.3 成本控制与性能优化大模型 API 的成本不是按调用次数算而是按 token 算这是新手最容易忽略的。一个 RAG 请求如果检索回 10 段文档prompt 可能膨胀到几千 token看起来只是“多了一点点”乘以每日几万次调用成本立刻变得可观。建议从第一天就做好三个动作一是缓存对重复提问和热门问题的回答做 Redis 或内存缓存这是成本优化效果最明显的手段二是限流对每个用户、每个 IP 设置调用频率限制防止异常流量和恶意刷接口三是模型分级简单任务用便宜的轻量模型复杂任务才用强模型而不是所有请求都打同一个模型。9.4 可观测性与模型评估模型输出不是确定性的所以上线前必须建立评估机制。最简单的方式是准备一份“评测集”包含几十条典型业务问题和对应的可接受答案标准。每次修改 prompt 或更换模型都跑一遍评测集人工或半自动判断回答质量是否下降。这是 2024 年 AI 工程实践里最能体现工程水平的部分。在日志方面除了普通的应用日志至少要记录模型名、prompt 版本、输入输出 token 数、响应延迟、返回内容摘要。有条件的话接入链路追踪工具把一次用户请求对应的检索、模型调用、工具调用串起来出问题时能快速定位。9.5 灰度发布与回滚模型服务的一大特点是“外部升级不受你控制”同一个模型可能过一段时间行为就变了。所以发布流程要设计成可回滚的模型名、prompt 版本、参数配置都要作为配置项而不是写死在代码里。生产环境可以先用 5% 流量做灰度对比新老版本的评估指标确认没问题再全量切换。9.6 团队协作与分工一个完整的 AI 项目至少需要三类角色工程侧负责接口、数据流、部署算法或 AI 侧负责模型选型、提示词策略、评测业务侧负责提供真实场景和验收标准。这三类角色之间的沟通界面应该是一份“评估集 通过标准”。谁改了 prompt谁更新了评测集都应该通过代码评审和文档记录沉淀下来。10. 总结与后续学习方向Stone Soup AI 这篇“石头汤”现在你应该知道该怎么煮了先搭一个能跑通的最小工程骨架再按业务需求逐步加入模型、工具、检索、服务封装、评测回归。它不强调一开始就追求大而全而是强调每一步都有可验证的产出让团队能够持续迭代。如果你打算继续深入建议按下面的路线推进第一阶段熟练封装模型调用。你会写统一的 LLM 调用函数理解 messages 结构、温度参数、输出格式控制。第二阶段掌握结构化输出和工具调用。让模型按照 JSON Schema 返回结果并能在 Agent 中正确执行工具。第三阶段搭建完整的 RAG 链路。从文本切分、Embedding、向量存储到检索重排理解每一步如何影响最终回答质量。第四阶段建设评估与可观测体系。建立评测集、维度评分、日志追踪这是从“能用”到“好用”的分水岭。第五阶段解决部署与运维。理解模型私有化部署、弹性伸缩、成本优化、并发控制逐步形成团队级的 AI 应用开发学习路线。如果你是第一次接触 AI 应用开发不要急着学完所有内容。把文章里的weather_agent.py和simple_rag.py复制到自己的项目里先跑通一次感受一下“模型输出”和“代码控制”之间的配合方式。跑通之后再对照最佳实践逐条优化。这篇文章更像一个起点而不是终点。2024 年的 AI 工程变化很快但面向业务的组装式开发思路不会过时明确问题选好组件控制成本持续评估。建议收藏备用项目里用到 AI 能力时再回来对照一遍。