Stone Soup AI:从最小系统开始的AI工程化协作范式 开头的强判断AI 应用开发最大的成本已经不再是模型能力而是把零散能力组织成可复用系统的工程成本。Stone Soup AI2024这个标题看起来很像一个社区项目但把它放到 2024 年 AI 工程化的大背景里它更像一种值得认真对待的协作范式先用一块石头起锅让每个参与者往里加自己的一份配料最后所有人都能喝到一锅汤。如果只看字面很容易误以为它是一个具体的开源框架或者某个模型仓库。但更稳妥的判断是Stone Soup AI 背后隐喻的是一种构建 AI 系统的方法论不追求一开始就拥有完美的大一统平台而是从最小可行系统出发由社区、团队或个人持续贡献小模块逐步累积成生产可用的系统。这个思路在 2024 年特别有价值因为这一年里大模型的能力边界已经被反复验证真正拉开差距的反而是谁能更快地把模型、数据、工具、评测组织成一个闭环。这篇文章会从三个层次展开先讲清楚 Stone Soup AI 代表的协作模式到底是什么为什么放在 2024 年看有现实意义再给出一个可以直接落地的工程路径从最小系统起步逐步叠加能力最后补充常见的坑、最佳实践和验证方法。你可以把它理解成一份AI 工程化入门路线图而不是某个具体框架的使用手册。1. Stone Soup AI 到底在讲什么石头汤的故事很多人都听过一个陌生人用一块石头加水煮汤路过的人觉得好奇有人说我正好有根胡萝卜有人说我有点盐有人说我家里有块肉最后大家真的喝到一锅丰盛的汤。Stone Soup AI2024从命名逻辑上看正是借用这个寓言来隐喻 AI 系统的构建方式。如果你在各种渠道看到了这个名字大概率它指向的不是一个单一框架而是一种社区协作 模块化积累的工程理念。它强调的是你没有必要等到所有条件都齐备才开始做 AI 应用完全可以用一个很小的系统起步然后让数据、工具、评测、提示词这些配料陆续加进来。这个隐喻放在 2024 年尤其贴切。过去几年很多团队在 AI 项目上都有过类似的痛苦经历花了几周时间选型列了一堆需求等模型 API 稳定等标注数据到位等预算审批结果半年过去连一个能跑的 Demo 都没有。Stone Soup 的思路正好反过来——先煮一小锅能喝的汤哪怕只有石头和水然后让参与者在真实使用中发现自己能贡献什么。从技术架构角度看这种模式对应的是现代 AI 应用的分层组织方式。一个完整的 AI 系统通常由模型层、数据层、工具层、记忆层、评测层组成每一层都能独立演进和替换。Stone Soup 模式鼓励的正是这种松耦合架构某个贡献者只负责提供一套好的检索工具另一个人负责写评测集第三个人负责调提示词最后由一个最小的调度逻辑把它们串起来。这个理念说起来简单做起来难。难在很多人习惯了平台思维总想等一个万能框架把一切都安排好而 Stone Soup 要求你接受初始版本的粗糙然后用快速迭代去弥补。如果你是一位开发者、技术负责人或 AI 产品经理理解这个模式之后你会发现它能够直接指导你的项目起步方式、团队分工甚至是预算分配。2. 为什么 2024 年需要这种协作模式2024 年 AI 应用开发有一个非常明显的变化模型能力的差距正在被拉平工程落地的差距却在扩大。也就是说大家都能调用到质量不错的大模型但有的团队能在一个月内做出可用的 AI 产品有的团队却始终停在概念验证阶段。问题不在模型而在工程组织和协作方式。过去做一个 AI 功能流程相对线性确定需求找模型调 API写提示词上线。但现在一个稍微复杂一点的 AI 应用比如带知识库的客服助手或带工具调用的 Agent涉及的模块明显增多需要准备知识文档需要做向量化和检索需要设计工具调用协议需要管理多轮对话的记忆需要建立评测集来防止模型越改越差。这些任务已经超出了单个开发者的能力范围需要不同角色的人往同一个锅里加料。Stone Soup 模式在这方面有明显的优势。它假设系统一开始是能跑但简陋的然后通过参与者的贡献逐步完善。比如一个开源社区的 AI 项目最初可能只有一个模型调用封装和几个示例提示词后来有人贡献了文档解析模块有人加了 API 服务封装有人整理了评测数据集有人补充了部署脚本。每个贡献的难度都不算大但合在一起系统就从一个玩具变成了可以部署的工具。从成本角度看这种模式也合理地控制住了预算。一个典型的 AI 应用预算包括模型调用费用、数据准备成本、人工标注成本、开发人力和基础设施开销。如果你追求一步到位很容易在数据标注和平台建设上过度投入而 Stone Soup 思路讲究的是先投少量成本验证核心链路再按需追加资源。这本质上是一种渐进式投资策略对中小企业尤其友好。另外2024 年 AI Agent 的概念非常热但很多团队对 Agent 存在误解以为 Agent 是一个开箱即用的产品形态。实际上Agent 更像是一个由模型、工具、记忆、策略组合出来的系统它的可靠程度完全取决于各模块是否扎实。Stone Soup 模式恰恰提出了一个务实的构建路径你可以先做一个只调用一个工具的最小 Agent跑通后逐步添加更多工具并不断用评测数据校准它的行为。3. 石头汤 AI 的核心原则把 Stone Soup 的思想落到工程上可以提炼出五个核心原则理解这五条之后再去看具体的代码和架构会更容易。第一个原则是先有最小系统。不要在设计阶段试图覆盖所有场景先做一个能处理一条主路径的版本。这个版本可能不够聪明可能只能回答有限的问题但它必须端到端可运行。有了它你才有讨论的基准。第二个原则是能力按需加料。每个新能力都应该以独立模块的方式加入而不是把逻辑全部揉进主程序。比如你想让系统支持读取 PDF 文档那就写一个文档解析模块加进去想让它能查询天气就写一个天气工具模块。对现有系统的影响被限制在最小范围。第三个原则是贡献者与使用者的边界是模糊的。在石头汤协作模式里使用者往往也是贡献者。团队里谁发现模型回答经常出现某种错误谁就应该去补充对应的评测用例谁觉得检索效果不好谁就应该去改进数据分块策略。这种机制让系统能在真实使用中快速进化。第四个原则是验证驱动迭代。每次加料之后必须回答这东西到底有没有让系统变得更好。没有评测的加料只是在增加复杂度。你要有一组固定的评测问题在每次改动之后跑一遍比较改动前后的表现。第五个原则是开放与可复现。哪怕你是公司内部团队做 AI 项目也应该以开放心态管理产出物。提示词、评测数据集、工具封装都应该有清晰的版本记录这样别人才知道你的系统是基于什么构建的也才能放心地往里加自己的料。这些原则看起来不复杂但它们恰好解决了 2024 年 AI 工程化最常见的三个问题项目启动过慢、模块耦合过紧、改动无法验证。如果你正在设计一个新的 AI 项目不妨从第一条开始先确定你的石头是什么——也就是最核心的那条主路径。4. 环境准备与前置条件在用具体代码演示如何实践 Stone Soup 思路之前先明确环境准备。和很多直接介绍框架的文章不同我希望你理解的是通用思路因此下面会用一组简单的技术选型来演示你完全可以根据自己的实际情况替换成团队已有的技术栈。基础运行环境建议如下操作系统Windows 10/11、macOS、Linux 均可本文示例使用命令行操作。Python 版本建议使用 Python 3.10 及以上这是当前主流 AI 项目的基本要求。依赖管理使用 venv 或 conda 创建独立虚拟环境避免与系统 Python 环境冲突。模型服务需要一个可调用的 LLM 接口。你可以使用云厂商的模型 API也可以使用本地部署的开源模型。本文示例用llm.chat()作为通用调用抽象实际项目中替换成具体 SDK 即可。代码编辑工具任意支持 Python 的 IDE 或编辑器都行推荐 VS Code 配合 Pylance 插件。创建一个新目录准备虚拟环境mkdir stone-soup-demo cd stone-soup-demo python3 -m venv venv source venv/bin/activate pip install pyyaml这里只安装了pyyaml用来读取配置文件。实际项目里的依赖会更多比如 HTTP Server、向量数据库客户端等但本文重点是演示工程思路所以保持最小依赖。在开始写代码前先做一个项目结构规划。Stone Soup 的一个重要特点是模块边界清晰所以我们的目录也应该从第一天就按模块划分stone-soup-demo/ ├── config.yaml ├── main.py ├── core/ │ └── agent.py ├── tools/ │ ├── __init__.py │ └── registry.py ├── data/ │ └── eval_questions.json └── tests/ └── eval.pyconfig.yaml放全局配置core/agent.py放系统调度逻辑tools/registry.py做工具注册data/放评测数据tests/eval.py放评测脚本。这样的结构在你后续添加新模块时不会破坏已有功能。5. 完整示例从最小系统到逐步加料这一节我们用一个完整示例演示 Stone Soup 的实践过程。示例不会依赖某个特定的模型厂商 SDK而是用抽象接口表示模型调用这样你能看清楚整个工程骨架再对照自己的项目做替换。5.1 第一步先煮一锅石头汤最小系统的定义是能接收用户输入调用一次模型返回一个回答。这是所有 AI 应用的通用主路径也是那锅汤里的石头。先创建配置文件config.yamlmodel: provider: openai-compatible name: demo-model temperature: 0.2 system_prompt: 你是一个乐于助人的中文助手。注意provider和name只是示意字段实际使用时替换成你的模型服务商和模型名。再创建核心文件core/agent.py# 文件路径core/agent.py class LLMClient: 模型调用抽象层实际项目中替换为具体 SDK。 def __init__(self, config): self.model_name config[model][name] self.temperature config[model].get(temperature, 0.2) def chat(self, messages): # 这里只是示例用一个通用 HTTP 调用表示 # 实际项目中应替换为 requests.post(...) 或对应 SDK # 返回文本时默认固定返回一段提示方便离线演示 return f[demo response] 收到你的问题{messages[-1][content]} class MinimalAgent: def __init__(self, config): self.llm LLMClient(config) self.system_prompt config.get(system_prompt, ) def run(self, user_input): messages [] if self.system_prompt: messages.append({role: system, content: self.system_prompt}) messages.append({role: user, content: user_input}) return self.llm.chat(messages)再创建入口main.py# 文件路径main.py import yaml from core.agent import MinimalAgent def load_config(pathconfig.yaml): with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def main(): config load_config() agent MinimalAgent(config) while True: user_input input(请输入你的问题输入 exit 退出) if user_input.strip().lower() exit: break answer agent.run(user_input) print(f助手{answer}) if __name__ __main__: main()运行方法python main.py输入一个问题能看到助手返回一段模拟回答。到这里最小系统已经跑通。虽然它还很简陋但它已经具备了一个 AI 应用的完整骨架配置、模型调用、对话循环。接下来所有的功能都在这副骨架上叠加。5.2 第二步加上第一个配料——工具注册机制石头汤的第二步是让其他参与者有条件往里加料。在工程上这意味着需要有一个工具注册机制让不同的功能模块可以以插件形式加入系统。创建tools/registry.py# 文件路径tools/registry.py from typing import Callable, Dict class Tool: def __init__(self, name: str, description: str, func: Callable): self.name name self.description description self.func func def execute(self, *args, **kwargs): return self.func(*args, **kwargs) class ToolRegistry: def __init__(self): self._tools: Dict[str, Tool] {} def register(self, name: str, description: str, func: Callable): if name in self._tools: raise ValueError(fTool {name} already exists) self._tools[name] Tool(name, description, func) def get(self, name: str) - Tool: return self._tools.get(name) def list_tools(self): return [(name, tool.description) for name, tool in self._tools.items()] # 全局工具注册表方便各模块导入 registry ToolRegistry()定义两个示例工具分别用于获取当前时间和计算两个数字的和# 文件路径tools/builtin.py from datetime import datetime from .registry import registry def get_current_time(): return datetime.now().strftime(%Y-%m-%d %H:%M:%S) def add(a: int, b: int) - int: return a b def register_builtin_tools(): registry.register( nameget_current_time, description获取当前系统时间, funcget_current_time, ) registry.register( nameadd, description计算两个整数的和, funcadd, )在core/agent.py中扩展 Agent让它具备调用工具的能力# 文件路径core/agent.py扩展版 from tools.registry import registry class ToolCallingAgent: def __init__(self, config): self.llm LLMClient(config) self.system_prompt config.get(system_prompt, ) def run(self, user_input): messages [] if self.system_prompt: messages.append({role: system, content: self.system_prompt}) messages.append({role: user, content: user_input}) # 实际项目中这里应该让模型判断是否调用工具以及调用哪个工具 # 最简单的做法是维护一张工具与关键词的映射表 tool_keywords { 时间: get_current_time, 相加: add, } for keyword, tool_name in tool_keywords.items(): if keyword in user_input: tool registry.get(tool_name) if tool: if tool.name get_current_time: result tool.execute() elif tool.name add: # 从输入中提取两个数字作为一个简单演示 import re nums re.findall(r-?\d, user_input) if len(nums) 2: result tool.execute(int(nums[0]), int(nums[1])) else: result 请提供两个数字 return f工具 {tool.name} 返回结果{result} return self.llm.chat(messages)这里使用关键词匹配来判断是否调用工具只是一个演示用的最简实现。实际项目中应该通过模型输出结构化指令比如函数调用格式来决定工具调度。这个简化版本的价值在于演示工具注册和调用的整体流程。修改main.py以支持工具注册# 文件路径main.py import yaml from core.agent import ToolCallingAgent from tools.builtin import register_builtin_tools def load_config(pathconfig.yaml): with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def main(): config load_config() register_builtin_tools() agent ToolCallingAgent(config) while True: user_input input(请输入你的问题输入 exit 退出) if user_input.strip().lower() exit: break answer agent.run(user_input) print(f助手{answer}) if __name__ __main__: main()运行后输入现在时间或请把 3 和 5 相加会看到工具被调用并返回结果。到这里系统已经具备工具扩展能力。后续任何人新增工具只需要在tools/下添加新模块并调用register方法即可。5.3 第三步加一份知识配料——简易检索增强工具能力之外最常见的配料是外部知识。2024 年 AI 应用的主流做法是 RAG检索增强生成也就是把文档切块后向量化用户提问时先检索相关片段再把这些片段拼进提示词让模型基于资料回答。这里不引入重量级向量数据库而是用一个简单的顺序检索来演示机制# 文件路径core/knowledge.py import json from pathlib import Path class SimpleKnowledgeBase: def __init__(self, data_path: str): self.data_path Path(data_path) self.documents [] self.load() def load(self): if self.data_path.exists(): with open(self.data_path, r, encodingutf-8) as f: self.documents json.load(f) def search(self, query: str, top_k: int 1): # 极简关键词检索按 query 中的每个词在文档里出现的次数排序 scored [] query_terms set(query.split()) for doc in self.documents: score 0 for term in query_terms: if term in doc[content]: score 1 scored.append((score, doc)) scored.sort(keylambda x: x[0], reverseTrue) return [doc for score, doc in scored[:top_k] if score 0]创建知识文件data/knowledge.json[ { id: doc_001, content: 石头汤AI是一种强调社区协作和模块化积累的AI工程方法。 }, { id: doc_002, content: RAG技术通过检索外部知识来增强大模型的回答准确性。 }, { id: doc_003, content: 2024年AI应用开发的重点正在从模型能力转向工程协作和评测体系。 } ]修改core/agent.py加入知识检索# 文件路径core/agent.py加入知识检索 from core.knowledge import SimpleKnowledgeBase class RAGAgent: def __init__(self, config): self.llm LLMClient(config) self.system_prompt config.get(system_prompt, ) self.knowledge_base SimpleKnowledgeBase(data/knowledge.json) def run(self, user_input): messages [] if self.system_prompt: messages.append({role: system, content: self.system_prompt}) # 检索相关文档 docs self.knowledge_base.search(user_input) if docs: context \\n\\n.join([doc[content] for doc in docs]) prompt ( f请根据以下资料回答问题。\\n f资料\\n{context}\\n\\n f问题{user_input}\\n f如果资料不足以回答请说明不知道。 ) messages.append({role: user, content: prompt}) else: messages.append({role: user, content: user_input}) return self.llm.chat(messages)真正应用到生产环境时你会用向量数据库替代这个简单的关键词检索但架构思路是一样的外部知识作为配料被动态地加入提示词而不是预先写死在系统里。5.4 第四步建立评测集控制改烂风险每加一种配料系统都有可能变好也可能变差。模型输出不稳定这是 2024 年 AI 工程公认的挑战。评测集就是用来把控这条线的。在data/eval_questions.json里准备少量评测题[ { question: 石头汤AI的核心思想是什么, expected_keywords: [协作, 模块化] }, { question: RAG技术的目的是什么, expected_keywords: [检索, 增强, 准确性] }, { question: 2024年AI应用开发的重点是什么, expected_keywords: [工程协作, 评测] } ]评测脚本tests/eval.py# 文件路径tests/eval.py import json import sys from pathlib import Path sys.path.append(str(Path(__file__).resolve().parent.parent)) from core.agent import RAGAgent import yaml def run_eval(): with open(config.yaml, r, encodingutf-8) as f: config yaml.safe_load(f) with open(data/eval_questions.json, r, encodingutf-8) as f: eval_data json.load(f) agent RAGAgent(config) total len(eval_data) passed 0 for item in eval_data: answer agent.run(item[question]) keywords item[expected_keywords] match all(kw in answer for kw in keywords) if match: passed 1 print(f[PASS] {item[question]}) else: print(f[FAIL] {item[question]}) print(f 答案{answer}) print(f评测通过率{passed}/{total} {passed / total * 100:.1f}%) if passed / total 0.7: print(警告通过率低于 70%本次改动可能引入了回归。) sys.exit(1) if __name__ __main__: run_eval()运行评测python tests/eval.py评测脚本会逐条执行问题检查回答是否包含期望的关键词。这个朴素方法在实际项目中可以被替换成更复杂的语义相似度评估但核心思想已经到位每次加料之后跑一遍历史评测集用数字判断系统是变好还是变差。6. 运行结果与效果验证把这个示例完整跑通你最后会得到一个可以做三件事的小系统调用模型回答一般问题根据关键词调用简单工具从简易知识库检索上下文并回答。运行python main.py时输入石头汤AI的核心思想是什么系统会先从知识库里检索到与石头汤AI相关的文档再交给模型组装答案。如果输入请把 3 和 5 相加系统会命中工具关键词走工具调用路径。运行python tests/eval.py时系统会调用配置里的模型接口逐条回答评测问题并输出通过率。判断系统是否成功不能只看有没有报错。建议按下面的顺序验证第一链路是否完整。从用户输入到最终输出是否经过了你预期的模块。如果设计了工具调用但输入相关问题时没有触发说明调度逻辑有误。第二评测通过率是否稳定。同样的评测集连续跑三次如果结果波动过大说明模型温度参数太高或者提示词不够稳定。可以尝试把temperature调低到 0 或 0.1。第三新增模块后是否影响旧功能。这是 Stone Soup 模式必须守住的底线。每次加新配料之前先跑一次评测加完之后再跑一次对比两次分数。如果出现失败第一步永远应该看日志和异常堆栈。Python 报异常时先定位是模型调用失败、知识库文件路径错误还是评测数据格式问题。第二步检查配置文件config.yaml里的字段是否和代码读取的一致。这两步能解决大部分启动问题。7. 常见问题与排查思路在实践 Stone Soup 式的 AI 工程时你会遇到下面这些高频问题提前了解能节省不少排查时间。问题现象可能原因排查方式解决方案启动时报 ModuleNotFoundError虚拟环境未激活或依赖未安装检查pip list是否包含所需依赖执行pip install pyyaml等依赖安装命令调用模型时超时网络问题或模型服务不可达单独写脚本测试模型 API 连通性检查 API Key、网络代理和模型服务状态工具没有被触发关键词匹配逻辑没覆盖用户表达打印 user_input 和工具关键词表改进调度策略实际项目应使用模型结构化输出评测通过率很低提示词不稳定或检索质量差查看失败样例的实际回答调整 system prompt、温度参数或检索逻辑新增模块后旧功能报错模块之间存在隐式依赖用git diff看这次改了哪些文件保持模块独立避免在工具模块里 import 核心模块知识库检索不到内容知识文档格式或路径不对查看knowledge.json是否存在及其内容确认 JSON 文件格式合法且处于正确路径回答内容不稳定模型温度参数过高查看配置中的 temperature 值调低 temperature或改为固定种子测试这些问题的共同点在于大多数失败都不是模型能力不足而是工程实践细节没做好。这正好印证了 Stone Soup 模式的价值——系统的复杂度不是靠一个大而全的平台管理而是靠每个模块的边界和纪律来约束。8. 工程最佳实践与落地建议把 Stone Soup 的思路真正用到项目里除了代码层面还要在工程管理上形成一些习惯。这里基于 2024 年 AI 应用开发的常见痛点整理几条务实的建议。第一配置与代码分离。上面示例里的config.yaml看似简单但它承载了一个重要原则模型名称、温度、提示词、数据路径都应该可配置而不是硬编码在代码里。这样不同环境开发、测试、生产可以通过不同配置文件切换而不需要改动代码。第二建立评测集优先的习惯。在开始一个 AI 项目的第一天就应该创建评测集哪怕只有十条问题。每周往里加新的真实问题特别是那些曾经让系统答错的案例。这样系统会越用越稳而不是越改越乱。这个习惯比任何框架都重要。第三工具模块保持单一职责。一个工具只做一件事比如获取当前时间、查询天气、计算两个数相加。不要做全能工具否则后续复用和测试都很痛苦。第四模型选择要分层。不是所有问题都要调用最强的模型。简单分类、关键词提取可以用国产轻量模型或规则实现复杂推理再调用大参数模型。Stone Soup 模式下模型也是一种可以按需替换和组合的配料。第五考虑成本控制。每次加料前要预估它会增加多少模型调用量。比如 RAG 会增加单次请求的 token 消耗工具调用可能带来额外延迟。建议在评测脚本里同时统计 token 消耗让效果好和成本可控一起纳入决策。第六安全边界要提前划定。如果系统会执行工具调用尤其是读文件、写文件、访问外部 API 这类操作必须有白名单机制和权限控制。在示例里我们add工具是无害的但实际项目中的工具可能涉及数据库操作、邮件发送、文件删除稍有不慎就会造成事故。安全原则是默认拒绝显式授权记录所有调用日志。第七版本管理要细致。提示词、评测集、工具代码这三类资产都应该纳入版本管理。对于提示词每次修改建议记录改了哪个系统、原因是什么、评测结果如何。这可能是最容易被忽视的 AI 工程实践但也是决定长期维护难度的重要因素。9. 总结与后续学习方向Stone Soup AI2024如果被理解成一个具体的工具你会觉得什么都没学到如果把它理解成一种工程方法论它能直接改变你做 AI 项目的方式。这篇文章真正想讲清楚的是一个已经成立的事实AI 系统不再是一个模型文件而是一锅需要持续加料、持续验证的协作产物。起步可以很小但结构和纪律要有。如果接下来你要动手实践我建议按这个顺序走一遍先跑通一个最小 Agent就像示例里的MinimalAgent哪怕没有任何工具和知识库。然后在这个骨架上加第一个工具让它具备一个实际用处。接着加一个最简单的知识库看看同样的模型再加上检索之后回答质量是否变化、具体变在哪里。最后建立你的第一份评测集把十条真实问题放进去开始用数字管理你的 AI 应用。更深一层可以继续钻研这些方向RAG 工程优化文档切分策略、向量模型选择、混合检索、重排序。Agent 可靠性与评估如何用评测集、轨迹回放和结构化输出约束来减少 Agent 的不确定性。模型部署与成本优化本地部署模型、量化技术、缓存策略。多 Agent 协作多个模型分别承担规划、执行、校验角色而不是一个模型承担所有事情。这些方向在 2024 年都有大量开源项目和工程实践可以参考但它们的底层思维都离不开 Stonesoup 式的协作与演进。先把最小系统跑起来再让自己的锅里不断加料这个看似简单的过程才是 AI 应用工程化最真实的路径。