在初创公司经常要快速开发一个原型应用来验证自己的想法,特别是一人公司。我原来会选择:
【React / Next.js + FastAPI】:前后端分离架构,但对于一个不经常写前端的人,React总是感觉很重,今天推荐一个更轻更快的组合:【FastAPI + htmx】:服务端渲染 + 页面局部更新

先聊聊 “要不要用 Python”
首先要明确一个前提:有人会说 “没必要用 Python,从一开始用 TypeScript(Node.js)写全套不就行了”。说实话,这个观点确实值的思考,但为了AI的生态,还是要用Python,毕竟我们的应用是长在AI的生态上。具体如下:
1. LLM 相关库的生态,Python 更完善
LangChain、Transformers、OpenAI SDK、Anthropic SDK—— 这些主流工具的 Python 版本不仅功能更全面,更新速度也远超 TypeScript 版本。虽然部分库已移植到 TypeScript,但在功能覆盖度和更新及时性上,Python 仍有压倒性优势。
而且新的 LLM 技术出现时,最先推出的实现几乎都是 Python 版本,论文的参考代码也大多用 Python 编写。如果想尝试最新技术,用 Python 是绕不开的选择。
2. 运行 AI 模型,几乎只能选 Python
PyTorch、TensorFlow、JAX—— 主流深度学习框架基本都以 Python 为核心。
如果公司需要自研模型微调、训练,那根本无法避开 Python;即便只做模型推理,虽然 TypeScript 也能实现,但如果将模型开发纳入长期规划,Python 仍是必需的。
对 AI 初创公司来说,用 Python 其实是 “标准选择”,“不用 Python” 反而不现实。
既然确定用 Python,后端就选 FastAPI
基于以上前提,本文默认开发中使用 Python。那么后端框架的选择就很明确了 ——FastAPI。(这里的 “明确” 或许略显绝对,但在 Python 生态中,FastAPI 对 API 开发的适配性确实无出其右)
接下来的核心问题就是:前端该怎么处理?
为什么不选 React/Next.js?
问题 1:不符合 AI 初创公司的初期现状
可能有人会说 “那用 React 写不就行了?”,但请先冷静想想:AI 初创公司初期是什么样的?
大多数时候,1 个工程师要同时负责原型开发、AI 模型调试;就算有 2 个工程师,也基本都是偏后端 / AI 方向,没有专职前端。
这种情况下选 React,说实话太吃力了。
既要写 Python 代码、调试 AI 模型、优化提示词(Prompt Tuning),还要同时写 React、处理状态管理…… 一个人要扛下所有,根本不现实。
问题 2:配置复杂,门槛高
React/Next.js 的配置流程有多繁琐?
执行 npx create-next-app@latest,还要选择模板、是否用 TypeScript、是否启用 ESLint、是否用 App Router 等一堆设置
安装 axios react-query tailwindcss 等依赖,等待庞大的 node_modules 下载完成
还要维护 tsconfig.json next.config.js .eslintrc.json 等一堆配置文件,陷入 “配置文件地狱”
做个原型而已,需要这么复杂吗?
问题 3:需管理前后端,复杂度翻倍
选 React/Next.js,就意味着要同时管理前端和后端两个服务器:
前端(Next.js) ← HTTP 通信 → 后端(FastAPI)
前端需构建后部署到 Vercel 等平台,后端需部署到 AWS/GCP 等云服务
还要处理 CORS 配置、认证令牌管理,环境变量要在两处分别设置,部署也要做两次,还要考虑构建时间
问题 4:“为未来 考虑” 是种幻想
很多人会说 “为了将来可能的业务扩张,从一开始就该用 React”。
但这种 “将来”,真的会来吗?
大多数初创公司的业务最终会稳定在中小规模,不会走到 “需要高扩展性架构” 的阶段。反而会因为初期选择了过度复杂的架构,导致开发效率低下。
真到需要扩展的时候,再迁移技术栈也不迟。没必要从一开始就追求 “完美架构”。

最优解:FastAPI + htmx
接下来正式介绍【FastAPI + htmx】这个组合。
什么是 htmx?
htmx 是一个轻量级前端库,核心能力是仅通过 HTML 属性实现异步通信,无需写一行 JavaScript。
<button hx-get="/api/messages" hx-target="#result"> 获取消息 </button> <div id="result"></div>
只要这样写,点击按钮就能异步获取数据,并将结果显示在id="result"的元素中 —— 完全不用写 JS。
FastAPI 侧的实现
后端代码也非常简洁,只需返回 HTML 片段即可:
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/api/messages")
async def get_messages(request: Request):
messages = db.get_messages() # 从数据库获取消息
# 返回HTML片段模板
return templates.TemplateResponse("messages.html", {
"request": request,
"messages": messages
})服务器返回 HTML 片段后,htmx 会自动将其插入到页面指定位置。逻辑简单,但足以实现动态 UI。
FastAPI + htmx 的核心优势
1. 配置极简,上手快
只需安装 3 个 Python 依赖:
pip install fastapi uvicorn jinja2
然后写一个简单的main.py即可启动:
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.get("/")
async def read_root():
return HTMLResponse("""
<html>
<!-- 引入htmx -->
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<!-- 点击按钮异步获取数据 -->
<button hx-get="/api/data" hx-target="#result">
获取数据
</button>
<div id="result"></div>
</html>
""")整个流程围绕 FastAPI 展开,非常简洁。
2. 一个服务器搞定所有,部署简单
无需前后端分离,一个 FastAPI 服务器就能同时处理 API 和 HTML 渲染:
浏览器直接请求 FastAPI,获取完整 HTML
无需配置 CORS,环境变量只需在一处管理
部署只需一次操作,无需分别处理前端和后端
对原型开发来说,这种简化至关重要。
3. 全程用 Python,认知负荷低
这是最大的优势:
调试 AI 模型用 Python
写后端 API 用 Python
前端逻辑(通过 Jinja2 模板)也用 Python
无需在多种语言间切换,一个人就能轻松掌控全流程,极大降低了开发时的认知负担。
FastAPI + htmx 的实用实现模式
下面介绍几个在实际开发中常用的模式,覆盖 AI 产品原型的核心需求。
模式 1:自动更新(如实时刷新对话记录)
如果需要定期更新对话历史,只需用hx-trigger="every 5s"设置定时请求:
<!-- 5秒自动更新一次对话记录 --> <div hx-get="/api/conversations" hx-trigger="every 5s"> 加载对话记录中... </div>
后端代码:
@app.get("/api/conversations")
async def get_conversations(request: Request):
conversations = db.get_recent_conversations() # 获取最新对话
return templates.TemplateResponse("conversations.html", {
"request": request,
"conversations": conversations
})不用 WebSocket,仅通过简单的轮询就能实现实用的实时更新效果。
模式 2:筛选搜索(如对话记录检索)
实现带筛选功能的搜索,无需写 JS 逻辑:
<!-- 表单提交时自动发起搜索,结果显示在#results中 --> <form hx-get="/api/search" hx-target="#results"> <input name="query" placeholder="搜索关键词..." /> <select name="status"> <option value="active">进行中</option> <option value="completed">已完成</option> </select> <button type="submit">搜索</button> </form> <div id="results"></div>
后端代码:
@app.get("/api/search")
async def search(request: Request, query: str, status: str):
results = db.search_conversations(query, status) # 按条件搜索
return templates.TemplateResponse("results.html", {
"request": request,
"results": results
})表单提交后,htmx 会自动处理请求,无需手动写fetch()。
模式 3:删除功能(如删除对话记录)
实现删除功能并实时更新页面,无需管理删除后的状态:
<!-- 每个对话项带删除按钮,删除后移除当前元素 -->
<div id="conv-{{ conv.id }}">
<h3>{{ conv.title }}</h3>
<button hx-delete="/api/conversations/{{ conv.id }}"
hx-target="#conv-{{ conv.id }}" <!-- 目标是当前对话项 -->
hx-swap="outerHTML" <!-- 替换整个元素 -->
hx-confirm="确定要删除吗?"> <!-- 弹出确认框 -->
删除
</button>
</div>后端代码:
@app.delete("/api/conversations/{conv_id}")
async def delete_conversation(conv_id: int):
db.delete_conversation(conv_id) # 删除数据
return HTMLResponse("") # 返回空HTML,触发目标元素移除点击删除后,对应元素会自动从页面消失,无需额外处理状态。
模式 4:SSE(服务器推送,如 LLM 流式响应)
实现 LLM 的流式输出(如 ChatGPT 式的逐字显示),用 htmx 也很简单:
from fastapi import FastAPI, Response
from fastapi.responses import StreamingResponse
import asyncio
app = FastAPI()
@app.get("/stream")
async def stream_response():
# 模拟LLM流式输出(实际项目中替换为真实LLM调用)
async def event_generator():
async for chunk in llm_stream("你好,我是AI助手"):
yield f"data: {chunk}\n\n" # SSE格式
await asyncio.sleep(0.1) # 模拟流延迟
# 返回SSE响应
return StreamingResponse(event_generator(), media_type="text/event-stream")前端代码:
<!-- 启用SSE扩展,连接流接口,接收消息后追加内容 --> <div hx-ext="sse" sse-connect="/stream" <!-- 连接SSE接口 --> sse-swap="message" <!-- 监听message事件 --> hx-swap="beforeend"> <!-- 新内容追加到末尾 --> 正在接收响应... </div>
这个功能用 Streamlit 实现会非常麻烦,而 htmx 只需几行代码就能搞定。
模式 5:无限滚动(如加载更多对话)
实现滚动到底部自动加载更多内容:
<!-- 已加载的对话列表 --> <div id="conversations"> <!-- 现有对话项 --> </div> <!-- 滚动到该元素时,加载下一页 --> <div hx-get="/api/conversations?offset=20" <!-- 从第20条开始加载 --> hx-trigger="revealed" <!-- 元素进入视图时触发 --> hx-swap="afterend"> <!-- 加载的内容追加到后面 --> <span class="loading">加载中...</span> </div>
后端代码:
@app.get("/api/conversations")
async def get_conversations(request: Request, offset: int = 0, limit: int = 20):
conversations = db.get_conversations(offset, limit) # 分页获取
next_offset = offset + limit
return templates.TemplateResponse("conversations_partial.html", {
"request": request,
"conversations": conversations,
"next_offset": next_offset # 返回下一页偏移量
})用户滚动到 “加载中” 元素时,会自动请求下一页内容,实现无限滚动。
实际项目案例:对话系统仪表盘
我们公司在开发对话系统仪表盘时,就采用了 FastAPI + htmx 的组合。核心需求是实现 “对话聊天界面” 和 “对话历史管理仪表盘”,由于当时处于 PoC(概念验证)阶段,htmx 的轻量化特性完美适配需求。
最终技术栈如下:
FastAPI:负责后端 API 和 HTML 渲染
htmx:实现异步通信和页面局部更新
Tailwind CSS + DaisyUI:快速实现定制化设计(摆脱 Streamlit 的 “模板感”)
Jinja2:Python 模板引擎,处理前端动态内容
SQLModel:数据库 ORM,简化数据操作
AI 时代的原型开发流程:更快、更高效
传统的开发流程耗时过长,早已不适应 AI 初创公司的节奏:
需求定义 → 2. 后端 API 实现 → 3. 前端实现 → 4. 状态管理 / 异步处理 → 5. 设计调整 → 6. 完成
而借助 AI 工具和 htmx,流程可以大幅简化:
向 ChatGPT/Claude 提需求(例:“用 Tailwind 写一个对话系统仪表盘的 HTML”)
生成高完成度的 HTML 模板(AI 直接输出可复用的代码)
在 HTML 中添加 htmx 属性(如hx-get="/api/data" hx-trigger="load")
用 FastAPI 编写对应 API 接口
完成
设计交给 AI,功能实现交给 htmx—— 这才是 AI 时代最快的原型开发方式。
实际操作中,甚至可以把 Figma 设计图传给 ChatGPT 生成 HTML,再添上 htmx 属性,最后写几行 FastAPI 接口,一个能跑的原型就完成了。
从原型到生产:FastAPI + htmx 的平滑迁移
不同技术栈的 “原型→生产” 迁移成本差异巨大,这也是 FastAPI + htmx 的核心优势之一。
FastAPI + htmx 的迁移路径(成本低)
用 FastAPI + htmx 实现原型 → 2. 客户问 “能上线吗?” → 3. 回答 “可以,只需补充核心功能” → 4. 新增认证、计费等生产级功能 → 5. 生产上线(可保留 htmx,也可迁移到 React)
优势:原型阶段的 API 设计和核心逻辑可复用,迁移成本最小化 —— 相当于 “不浪费的原型”。
总结
对 AI 初创公司的原型开发而言,FastAPI + htmx 是效率极高的选择,核心优势可总结为五点:
配置简单:无需复杂的前后端环境搭建
Python 全栈:仅需 Python 知识,无需学 JavaScript
可复用性高:API 设计可直接沿用至生产环境,迁移成本低
部署便捷:一个服务器搞定所有,无需分开部署前后端
AI 适配性好:与 Python 生态的 LLM 库、深度学习框架无缝衔接
在 AI 初创公司的初期阶段,没必要为原型选择过度复杂的架构。“简单、快速、可复用” 才是核心 —— 与其纠结 “用 React 显得专业””,不如试试 FastAPI + htmx,用最低成本实现 “能落地、可扩展” 的原型。
上篇:
vLLM + FastAPI:一个高并发、低延迟的Qwen-7B量化服务搭建实录
下篇:
智能目标检测:用 Rust + dora-rs + yolo 构建“机器之眼”
1 人工智能 AI 在电商全链条的12个主要应用场景 2 地理空间AI应用:YOLO vs. SAM 3 AI应用快速原型开发:FastAPI + htmx ——无需React,为了快 4 开拍推出口播视频Agent,通过“AI口播助手”助力商家降本增效 5 AI应用快速原型开发:FastAPI + htmx ——无需React,为了快! 6 根据工作岗位要求, 写一份现场面试者工作自我介绍简述, 要求800字 7 爱了这个万能PPT制作方法,解决行业需求!一键生成只需3S搞定 8 大数据安全架构设计方案 9 一天做出短剧App:我的MCP极速流 10 链路聚合 vs 堆叠 vs 三层上联,到底啥场景该用谁 11 7大热门Agent框架盘点:助你轻松构建多智能体AI应用 12 红杉资本投资标准