smol developer:基于LLM的智能代码生成工具,实现从需求到原型的快速开发
1. 项目概述:你的“小”开发伙伴
如果你曾经对着一个空白的项目目录发呆,心里盘算着要搭建一个完整的应用需要多少脚手架、配置文件和样板代码,那么smol-ai/developer这个项目可能就是为你准备的。它不是什么庞大的企业级开发平台,而是一个被开发者社区亲切称为“小开发”(smol dev)的智能体。它的核心想法非常直接:你给它一段用自然语言描述的产品需求,它就能为你生成一个结构完整、可运行的代码库。这听起来像是魔法,但背后其实是一套精心设计的、将大语言模型(LLM)的能力与经典软件开发流程相结合的工程实践。
这个项目最初只是一个实验性的脚本,旨在探索 GPT-4 等模型在“全程序合成”上的潜力。没想到发布后迅速在开发者社区中走红,因为它精准地戳中了一个痛点:降低从想法到可运行原型之间的启动成本。与create-react-app这类固定框架的脚手架不同,smol developer的目标是成为“create-anything-app”。你不再需要去寻找一个恰好匹配你技术栈的启动器,而是直接告诉它你想要什么——一个带动画的井字棋网页游戏、一个 Chrome 扩展、一个简单的 CRM 系统——它就会尝试理解你的意图,并生成相应的 HTML、CSS、JavaScript、Python 等代码文件。
更重要的是,它的设计哲学是“以人为本且连贯的整体程序生成”。这意味着它并非追求完全自主的、黑盒式的代码生成,而是强调“人在回路中”的协作。你把smol developer看作一个初级的、精力充沛的搭档。它负责完成繁重的、模式化的代码搭建工作,而你作为资深开发者,负责提供清晰的需求、审查生成的代码、运行测试、并将遇到的错误或新想法反馈给它。这种协作模式,被项目作者称为“用提示词进行工程开发”,而非单纯的“提示词工程”。项目提供了三种使用模式:在 Git 仓库中直接运行脚本、作为smol_dev库集成到你自己的 Python 应用中,或者通过一个符合 Agent Protocol 标准的 API 服务器来调用,这使得它非常灵活,能适应不同的工作流。
2. 核心设计思路与架构拆解
smol developer的成功并非偶然,其架构设计巧妙地规避了早期代码生成工具的许多陷阱,并形成了一套可复用的模式。理解其背后的思路,比单纯调用它更有价值。
2.1 分阶段生成:从规划到实现
最核心的创新在于其分阶段的生成流程。它没有让 LLM 一次性吐出所有代码,而是将其分解为三个逻辑清晰的步骤,这极大地提高了生成代码的连贯性和质量。
规划阶段:首先,系统会要求 LLM 根据你的产品描述,生成一份名为
shared_dependencies.md的文档。这份文档是整个项目的“蓝图”和“契约”,它定义了项目的主要组件、它们之间的交互关系、关键的数据结构、全局变量、函数接口以及跨文件共享的常量。例如,如果你要生成一个“待办事项应用”,这份文档可能会明确:“有一个TodoItem数据结构,包含id,title,completed属性;主应用组件App负责状态管理;有一个utils.js文件提供本地存储函数saveTodos()和loadTodos()。” 这个步骤强制 LLM 先进行高层设计思考,而不是急于陷入具体语法的细节。文件路径规划阶段:有了蓝图之后,系统会要求 LLM 根据蓝图和原始需求,列出需要创建的所有文件路径。例如
['index.html', 'styles.css', 'app.js', 'utils.js']。这一步利用了 OpenAI 的函数调用功能,可以稳定地输出一个 JSON 数组,确保了程序的可预测性。这相当于在动工前,先确定好要建哪些房间。逐文件生成阶段:最后,系统会遍历上一步得到的文件路径列表,针对每一个文件,将原始需求、
shared_dependencies.md蓝图以及当前文件名再次提交给 LLM,要求它生成该文件的具体代码。关键点在于,生成每个文件时都会附上shared_dependencies.md作为上下文。这相当于告诉 LLM:“你在写app.js时,要记得我们之前约定好的TodoItem结构和saveTodos函数,并且在其他文件里也会用到它们。” 这种做法显著减少了文件间接口不一致、变量名冲突或函数调用错误等“幻觉”问题,保证了整个代码库的内在一致性。
注意:这个“蓝图共享”机制是项目成功的关键。它模拟了人类团队开发时先进行技术方案评审,再各自编码的工作流程,有效解决了早期端到端代码生成工具产出“缝合怪”代码的问题。
2.2 技术栈与工具选型
项目的技术选型也体现了其实用主义导向。
- 核心模型:默认且强烈推荐使用
gpt-4(特别是gpt-4-0613等具有函数调用能力的版本)。虽然也支持gpt-3.5-turbo,但在生成复杂、连贯的代码逻辑时,GPT-4 的规划能力和对长上下文的遵循度明显更优。这背后的考量是,代码生成的质量直接决定了工具的可用性,因此愿意为更强大的模型支付更高的成本。 - 开发与部署环境:项目早期重度依赖Modal。这是一个服务于 Python 的云平台,它解决了几个棘手问题:首先,它通过容器化封装了 Python 依赖环境,避免了“在我机器上能运行”的困境;其次,它提供了简单的并行计算能力,可以同时生成多个文件,加快整体速度;最后,它提供了从本地开发到云端 API 部署的无缝路径。不过,项目也保持了纯粹的本地运行能力,通过
poetry管理依赖,确保开发者可以灵活选择。 - 交互协议:为了便于集成,项目实现了Agent Protocol。这是一个旨在标准化智能体交互的开放协议。通过实现这个协议,
smol developer可以轻松地被任何兼容该协议的平台(如 e2b)发现、部署和管理,也方便开发者将其作为一个服务来调用,而不仅仅是脚本。
2.3 “人在回路”的哲学
smol developer明确将自己定位为“初级开发者”。这意味着它不试图取代人类,而是作为增强工具。整个工作流被设计成一个可中断、可介入的循环:
- 人类编写或修改
prompt.md(需求描述)。 - 运行
smol developer生成代码。 - 人类阅读、运行、测试生成的代码。
- 如果发现 bug 或需求不明确,人类可以将错误信息或新的说明直接粘贴回
prompt.md,就像在 GitHub 上提交 Issue 一样。 - 回到第 2 步,继续循环。
项目甚至提供了一个debugger.py脚本,它可以将整个代码库和错误信息一起喂给 LLM,请求其给出具体的代码修改建议。这种设计承认了当前 AI 的局限性,并将最终的控制权和责任交给了人类开发者,使得整个工具用起来更加踏实、可控。
3. 三种使用模式深度解析与实操
了解了核心思想后,我们来看看如何具体使用它。项目提供了三种模式,适合不同的场景。
3.1 Git 仓库模式:快速原型开发
这是最直接的使用方式,适合快速验证一个想法或搭建项目初版。
实操步骤:
环境准备:
# 克隆仓库 git clone https://github.com/smol-ai/developer.git cd developer # 安装依赖(推荐使用 poetry) pip install poetry # 如果未安装 poetry poetry install使用
poetry能确保你获得与项目完全一致的依赖环境,避免版本冲突。设置 API 密钥:在项目根目录创建
.env文件,并填入你的 OpenAI API 密钥:OPENAI_API_KEY=sk-your-api-key-here这是必须的步骤,否则程序无法调用 GPT。
编写需求文档:在项目根目录创建一个
my_prompt.md文件。这是你与smol dev沟通的主要界面。内容应尽可能清晰。一个不好的例子是:“做一个网站。” 一个好的例子是:# 项目:个人读书笔记管理器 ## 核心功能 1. 一个单页应用,顶部有导航栏,显示“首页”和“我的书库”。 2. 首页展示一个表单,用于添加新书笔记。表单包含字段:书名(文本)、作者(文本)、评分(1-5星)、阅读状态(未读/阅读中/已读)、笔记内容(多行文本)。 3. 提交表单后,新笔记以卡片形式添加到下方的网格布局中。 4. “我的书库”页面以网格展示所有笔记卡片,每张卡片显示书名、作者、评分和状态。卡片可以点击进入详情页(或展开)查看完整笔记。 5. 所有数据使用浏览器的 localStorage 进行持久化存储,页面刷新后数据不丢失。 ## 技术要求 * 使用纯 HTML、CSS 和 JavaScript 实现,无需后端。 * CSS 使用 Flexbox 或 Grid 进行布局,整体风格简洁现代。 * 评分使用星星图标(⭐)表示。 * 为“添加”按钮和卡片添加简单的悬停动画效果。越详细、越结构化的描述,越能生成符合预期的代码。
运行生成:
# 使用默认的 GPT-4 模型 python main.py --prompt my_prompt.md # 如果想用更便宜的 GPT-3.5 Turbo 试试(质量可能下降) python main.py --prompt my_prompt.md --model=gpt-3.5-turbo-0613 # 开启调试模式,查看更详细的生成过程日志 python main.py --prompt my_prompt.md --debug=True程序会依次执行规划、文件列表生成、代码生成三个步骤,并将最终的文件输出到当前目录(或
--outputdir指定的目录)。
实操心得:
- 迭代是关键:第一次生成的代码很少能完美运行。查看生成的
shared_dependencies.md,检查 LLM 对需求的理解是否准确。如果不准,直接修改my_prompt.md,补充或澄清描述,然后重新运行。这个过程很像是在和一位理解力很强但经验不足的实习生沟通。 - 善用错误信息:运行生成的代码,把浏览器控制台或终端的错误信息直接复制到
my_prompt.md的末尾,加上一句“运行时报错:...,请修复这个问题。” 再次运行,smol dev往往会给出修复方案。 - 管理输出目录:建议每次重要的迭代都使用一个新的
--outputdir,比如v1,v2,这样可以方便地回退和对比不同版本的生成结果。
3.2 库模式:将“小开发”嵌入你的应用
这是项目的强大之处。你可以将smol developer的核心能力作为库安装到自己的 Python 项目中,从而构建自定义的代码生成流水线或工具。
安装与基础使用:
pip install smol_dev核心 API 解析:库模式暴露了三个核心函数,对应其三个生成阶段:
from smol_dev.prompts import plan, specify_file_paths, generate_code_sync import asyncio from smol_dev.prompts import generate_code # 异步版本 # 1. 定义你的产品需求 prompt = "创建一个 Flask API 服务器,提供一个 /sum 端点,接收 JSON 格式的 {'a': number, 'b': number},返回它们的和。" # 2. 生成项目蓝图 shared_deps = plan(prompt) print("=== 项目蓝图 ===") print(shared_deps) # 此时,你可以将蓝图展示给用户确认,或者基于它进行一些逻辑判断。 # 3. 规划需要生成的文件 file_paths = specify_file_paths(prompt, shared_deps) print(f"\n=== 需要生成的文件 ===") for fp in file_paths: print(f"- {fp}") # 输出可能为:['app.py', 'requirements.txt', 'README.md'] # 4. 同步生成每个文件的代码 for file_path in file_paths: code = generate_code_sync(prompt, shared_deps, file_path) print(f"\n=== 文件内容: {file_path} ===") print(code) # 这里你可以将代码写入文件:with open(file_path, 'w') as f: f.write(code) # 或者,使用异步版本提高效率(如果生成大量文件) async def generate_all_files_async(): tasks = [] for file_path in file_paths: # 创建异步任务 task = asyncio.create_task(generate_code(prompt, shared_deps, file_path)) tasks.append((file_path, task)) for file_path, task in tasks: code = await task print(f"\n=== 文件内容: {file_path} ===") print(code) # 写入文件... # 运行异步函数 # asyncio.run(generate_all_files_async())自定义与扩展场景:库模式让你可以完全控制生成流程。例如:
- 交互式生成工具:你可以构建一个 CLI 工具,在
plan之后将蓝图呈现给用户,允许他们编辑后再进入下一步。 - 集成到 IDE 插件:开发一个 VSCode 插件,用户选中一个文件夹,输入描述,插件调用
smol_dev库直接在该文件夹中生成代码文件。 - 特定领域代码生成器:如果你经常需要生成某种特定类型的代码(如数据库模型、API 控制器),你可以先让
smol_dev生成一个基础框架,然后基于此框架和你的业务规则,编写脚本进行二次处理和定制。 - 与现有项目融合:你可以只使用
specify_file_paths和generate_code来为现有项目添加新模块或文件,只需将现有项目的部分关键代码作为上下文附加到prompt中即可。
注意:使用库模式时,你需要自行处理 OpenAI API 密钥的配置(通过环境变量
OPENAI_API_KEY)以及可能出现的网络错误、速率限制等问题。smol_dev库本身只负责组织提示词和调用模型。
3.3 API 模式:以服务形式提供能力
通过 Agent Protocol 实现的 API 模式,使得smol developer可以作为一个独立的微服务运行,任何能发送 HTTP 请求的客户端都可以调用它。
启动服务:
# 在项目根目录下 poetry run api # 或 python smol_dev/api.py服务默认会在http://localhost:8000启动。
使用 curl 调用:
# 1. 创建一个任务 curl --request POST \ --url http://localhost:8000/agent/tasks \ --header 'Content-Type: application/json' \ --data '{ "input": "创建一个 Python 脚本,读取当前目录下的 data.json 文件,计算其中所有数字的平均值,并打印结果。" }' # 响应会包含一个 task_id,例如:{"task_id": "abc123", ...} # 2. 执行该任务的步骤(即开始代码生成) curl --request POST \ --url http://localhost:8000/agent/tasks/abc123/steps执行步骤后,API 会返回生成的代码结果。根据 Agent Protocol 的设计,一个复杂的任务可能包含多个步骤,但smol developer目前将一次完整的代码生成作为一个步骤来处理。
使用 Python 客户端调用:这对于将代码生成能力集成到其他 Python 后端服务中非常方便。
import asyncio from agent_protocol_client import AgentApi, ApiClient, TaskRequestBody async def generate_code_via_api(prompt: str): async with ApiClient(host="http://localhost:8000") as api_client: api_instance = AgentApi(api_client) # 创建任务 task_request = TaskRequestBody(input=prompt) task = await api_instance.create_agent_task(task_request_body=task_request) print(f"任务创建成功,ID: {task.task_id}") # 执行任务步骤(生成代码) step = await api_instance.execute_agent_task_step(task_id=task.task_id) # step 对象中会包含生成的代码等输出信息 # 具体结构需要查看 Agent Protocol 的响应格式 print(f"步骤执行完成。输出: {step.output}") return step.output # 运行异步函数 # asyncio.run(generate_code_via_api("你的需求描述"))API 模式的价值:
- 解耦:将计算密集型的模型调用与你的主应用服务分离。
- 标准化:遵循 Agent Protocol 意味着你的服务可以接入一个不断增长的智能体生态系统。
- 多语言支持:你的前端(JavaScript/TypeScript)、移动端或其它后端服务(Go, Java)都可以通过简单的 HTTP 请求来调用代码生成能力,无需关心 Python 环境。
4. 高级技巧、避坑指南与未来展望
在实际使用中,我积累了一些能显著提升成功率和效率的经验,也总结了一些常见的“坑”。
4.1 编写高效提示词的技巧
smol developer的输入是 Markdown 格式的提示词,其质量直接决定输出。
- 结构化与分节:像写产品需求文档一样组织你的
prompt.md。使用#标题划分“项目概述”、“核心功能”、“用户界面”、“技术要求”、“非功能需求”等部分。LLM 对结构良好的文本理解更深。 - 混合代码与描述:这是项目强调的“Markdown is all you need”的精髓。你可以在描述中直接插入你希望它使用的变量名、函数签名甚至代码片段。
在生成代码时,请使用这个确切的结构。## 数据结构 请定义一个 `User` 对象,包含以下字段: ```javascript { id: string, // UUID name: string, email: string, createdAt: Date } - “复制粘贴”编程:对于 LLM 知识截止日期之后的新 API 或不熟悉的库,最有效的方法就是把官方文档的示例
curl命令或代码片段直接贴到提示词里。smol developer最初的 Chrome 扩展 demo 就是这样教会 GPT-4 使用 Anthropic Claude API 的。 - 逐步细化:不要指望第一版提示词就完美。先用一个简短的描述生成一个基础版本,运行看看。然后根据生成的代码和你的进一步想法,不断追加内容到
prompt.md中。这种“日志驱动”的开发方式非常自然。
4.2 常见问题与排查实录
即使提示词写得很好,生成过程中也可能遇到问题。以下是一个常见问题速查表:
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| 生成的文件列表不全或奇怪 | LLM 对项目结构理解有偏差。 | 1. 检查shared_dependencies.md,看蓝图是否准确理解了组件划分。2. 在提示词中更明确地指定技术栈和文件结构,例如:“请创建一个标准的 React 项目,包含 src/App.jsx,src/index.js,public/index.html。” |
| 生成的代码有语法错误或无法运行 | LLM 的“幻觉”,或上下文长度限制导致细节丢失。 | 1.这是常态,不必焦虑。直接运行代码,将完整的错误信息(堆栈跟踪)复制到prompt.md末尾,要求修复。2. 使用项目自带的 debugger.py脚本:python debugger.py --codebase /path/to/generated/code --error “你的错误信息”,它会分析整个代码库并给出修复建议。 |
| 文件间的接口不一致 | shared_dependencies.md不够详细,或生成时未被充分参考。 | 1. 在提示词中强调:“请确保shared_dependencies.md明确定义所有跨文件共享的函数名、参数和返回值。”2. 手动编辑 shared_dependencies.md,补全缺失的接口定义,然后重新生成特定文件。 |
| API 调用超时或失败 | OpenAI API 不稳定、网络问题或达到速率限制。 | 1. 项目内置了重试和退避机制,但偶尔仍会失败。检查网络连接。 2. 如果使用 gpt-4,确认账户有足够配额。3. 考虑使用 --model=gpt-3.5-turbo进行快速原型迭代,最后再用 GPT-4 精修。 |
| 生成速度很慢 | 默认使用 GPT-4,且是顺序生成文件。 | 1. 这是目前最大的瓶颈之一。生成一个中等复杂度的项目可能需要 2-4 分钟。 2. 在库模式下,你可以尝试用 asyncio并行调用generate_code(异步版本)来加速文件生成步骤。 |
一个典型的调试循环示例:
- 运行
python main.py --prompt my_app.md。 - 尝试运行生成的代码:
python generated_app/app.py,发现ModuleNotFoundError: No module named 'flask'。 - 将错误信息添加到
my_app.md末尾:[后续指令] 运行生成的 `app.py` 时出现错误:`ModuleNotFoundError: No module named 'flask'`。 请确保在 `requirements.txt` 文件中正确添加了 `flask` 依赖,并且生成的代码是可运行的。 - 重新运行
python main.py --prompt my_app.md。这次,它很可能会修正requirements.txt并重新生成app.py。
4.3 生态、替代方案与项目局限
smol developer激发了一个小型的生态,也出现了一些优秀的替代实现,各有侧重:
- smol-dev-js:一个纯 JavaScript/TypeScript 的实现。它的一个有趣特性是支持“增量提示”,你可以在现有代码库的某个文件上直接给出修改指令,而不用每次都从头生成整个项目。这对于将 AI 助手集成到现有开发流程中非常有用。
- smol-ai-dotnet / smol-dev-go:分别为 .NET 和 Go 社区提供的移植版本。这说明其核心模式具有普适性,不同语言社区的开发者可以基于此构建符合自己习惯的工具。
- smol-plugin:一个专门用于生成 OpenAI 插件配置和代码的衍生项目。这展示了
smol developer模式在垂直领域的应用潜力。
当前局限性:
- 上下文长度限制:尽管有蓝图机制,但复杂的项目可能需要更长的上下文来理解所有细节。虽然 GPT-4-32k 或 Claude 等模型能提供更大窗口,但成本和控制复杂度也会增加。
- 无自我修复能力:项目目前不能自动运行生成的代码并基于错误自我修复(“self-heal”)。这个功能在概念上很吸引人,但在实现上涉及安全、环境隔离和错误解释等诸多挑战。
- 依赖管理:它不会自动安装 Python 的
pip包或 Node.js 的npm包。虽然生成requirements.txt或package.json,但执行pip install或npm install仍需手动完成。更复杂的依赖和环境问题(如特定系统库)目前不在其处理范围内。 - 对特定任务的特殊处理:最初的 demo 包含了一些针对 Chrome 扩展图像生成的硬编码逻辑,这些逻辑没有很好地抽象为通用功能,体现了从具体用例泛化到通用工具的挑战。
4.4 未来可能的方向
社区和作者提出了一些有趣的未来演进思路,这也是项目保持活力的原因:
- 文件级提示词:为每个要生成的文件(如
App.jsx.md)提供独立的、更细致的提示词,用于微调该文件的生成结果,实现更精细的控制。 - 代码库反向工程:开发一个能从现有代码库自动生成描述性提示词的工具(“bootstrap the prompt”)。这样,你可以先手动创建一个理想的项目结构,然后让 AI 学习这个结构,以后就能生成类似风格的项目。这接近于让
smol developer具备学习能力。 - 集成执行与测试:将代码生成、依赖安装、运行测试甚至部署整合到一个自动化流水线中。结合 Docker 或 WebContainers 等技术,可以创建一个安全的沙箱环境来执行生成的代码并捕获结果,为“自我修复”提供基础。
- 多模型支持与优化:除了 OpenAI 的模型,集成 Claude、CodeLlama 等开源或商业模型,让用户可以根据速度、成本和质量进行选择。同时,优化提示词工程和生成流程,减少 API 调用次数和令牌消耗。
从我个人的使用经验来看,smol developer最大的价值不在于生成生产就绪的代码,而在于极大地压缩了项目的“冷启动”阶段。它帮助你将模糊的想法快速具象化为一个可以运行、可以触摸的原型。这个原型可能粗糙,充满 bug,但它提供了一个坚实的、可迭代的基础。你不再需要从零开始创建几十个文件,而是可以立即进入“阅读-修改-调试”的实质性开发循环。它就像一把强大的“思想铲”,帮你快速挖出第一个坑,至于把坑修成宫殿,那依然是你作为工程师的智慧和手艺的舞台。在 AI 辅助编程工具层出不穷的今天,smol developer以其简洁的哲学、实用的设计和开放的架构,为我们展示了一种高效的人机协作范式,值得每一位对开发效率有追求的工程师深入尝试和思考。
