AI 电子伴侣
创建时间: 2026-03-24最后更新: 2026-07-29

1. 为什么需要单独选择后端框架

上一篇文章确定了边缘部署的方向,并选择 CloudFlare Workers 作为基础设施。接下来还要解决一个具体问题:使用什么框架组织 API、中间件和服务调用。

我们曾经在两个候选框架之间做过比较,一个是 Python 生态的 FastAPI,另一个是 TypeScript 生态的 Hono.js。它们都很轻量,也都重视性能和开发体验,但在运行时、部署方式和生态定位上有明显差异。

当部署平台确定为 CloudFlare Workers 后,框架选择的范围其实已经很小。不过,仍然有必要把判断过程说明清楚:FastAPI 的优势是否足以让我们放弃边缘部署,以及 Hono.js 为什么更符合当前项目的约束。

2. 两个框架的定位

我们先通过最简单的接口看看两者的代码风格。

FastAPI:Python 生态的 API 框架

app.py
01
from fastapi import FastAPI
02
from pydantic import BaseModel
03
04
app = FastAPI()
05
06
class Message(BaseModel):
07
content: str
08
user_id: str
09
10
@app.post("/chat")
11
async def chat(msg: Message):
12
# 调用 LLM、检索记忆、组装回复...
13
return {"reply": f"收到: {msg.content}"}

Hono.js:TypeScript 生态的轻量级 Web 框架

index.ts
01
import { Hono } from 'hono'
02
03
const app = new Hono()
04
05
app.post('/chat', async (c) => {
06
const { content, user_id } = await c.req.json()
07
// 调用 LLM、检索记忆、组装回复...
08
return c.json({ reply: `收到: ${content}` })
09
})
10
11
export default app

单看接口定义,两者都足够简洁。真正影响选型的不是语法差异,而是它们依赖的运行时、能够使用的部署平台,以及各自擅长的应用场景。

维度FastAPIHono.js
语言PythonTypeScript / JavaScript
运行时CPython / uvicorn任意 JS 运行时(Node、Deno、Bun、Workers)
定位全功能 API 框架超轻量 Web 框架
包体积~30MB(含依赖)~14KB(无依赖)
首个 stable 版本2018 年2022 年

3. 从五个维度进行比较

3.1 边缘运行时兼容性

运行时兼容性是这次选型中最先考虑的条件,因为它会直接限制部署平台。

FastAPI 需要完整的 Python 运行时。除了 CPython 解释器,它通常还会依赖 uvicorn ASGI 服务器,以及 pydantic v2 的 Rust 编译后端等扩展。这套运行方式适合 AWS EC2、Docker 和 Lambda 等传统服务器或容器环境,却无法直接迁移到 CloudFlare Workers。

Workers 已经通过 Pyodide,也就是编译为 WASM 的 CPython,提供了实验性的 Python 支持,但目前仍处于早期阶段。FastAPI 依赖的 ASGI 服务器和 C 扩展生态,包括 uvicorn、pydantic v2 的 Rust 后端等,仍然无法完整运行。因此,在当前条件下,FastAPI 不能直接部署到边缘运行时。

Hono.js 在设计时就考虑了不同 JavaScript 运行时之间的兼容性:

index.ts
01
// CloudFlare Workers
02
export default app
03
04
// Node.js
05
import { serve } from '@hono/node-server'
06
serve(app)
07
08
// Deno
09
Deno.serve(app.fetch)
10
11
// Bun
12
export default app

同一套应用代码不需要修改业务逻辑,就可以运行在 CloudFlare Workers、Node.js、Deno 和 Bun 上。它带来的不只是迁移方便,更重要的是保留了部署方式的选择空间。

结合上一篇文章的结论,如果选择 FastAPI,就要同时放弃 CloudFlare Workers 提供的边缘部署能力。而实时对话需要尽可能缩短网络延迟,因此这个限制会直接影响 AI 伴侣的响应体验。

3.2 冷启动与运行时开销

即使暂时不考虑全球边缘部署,只比较 AWS Lambda、Vercel Functions 等 Serverless 场景,两套运行时的冷启动开销也有明显差异。

指标FastAPI(Lambda)Hono.js(Workers)
冷启动时间300-3000ms< 5ms
运行时开销~50MB 内存起步< 1MB
并发模型单进程异步(GIL 限制 CPU 密集任务)V8 Isolate(轻量隔离)
NOTE

这里的冷启动差距主要来自 Lambda 和 Workers 的运行时平台,不能完全归因于框架本身。不过,框架与运行时并不是彼此独立的选择:FastAPI 对应 Python 运行时,而 Hono.js 可以直接使用 Workers 的 V8 Isolate。

FastAPI 冷启动时需要加载 Python 解释器、依赖包以及所有被导入的模块。如果 Lambda 函数还依赖 numpy、pydantic v2 的 Rust 编译模块等库,冷启动时间很容易超过 2 秒。

Hono.js 在 Workers 上没有这部分开销。V8 Isolate 的启动成本很低,框架本身约为 14KB,也没有额外依赖需要逐项加载,因此冷启动通常可以忽略。

这个差异会直接出现在对话过程中。用户沉默几分钟后,Lambda 实例可能已经被回收;下一次发送消息时,首字节时间需要同时包含冷启动、请求处理和 LLM 推理。仅冷启动就占用 2 秒,会明显拖慢这次回复。

3.3 前后端技术栈统一

AI 伴侣的前端使用 React、Next.js 和 TypeScript。如果服务端继续使用 TypeScript,前后端可以共享类型定义,也能沿用同一套工具链。

最直接的收益是共享接口类型。请求和响应不需要分别维护,也不必先生成 OpenAPI schema,再根据 schema 生成客户端代码。

types.ts
01
// 这个类型定义,前端和后端直接 import 同一份文件
02
export interface ChatRequest {
03
content: string
04
user_id: string
05
session_id: string
06
}
07
08
export interface ChatResponse {
09
reply: string
10
emotion: string
11
memories_used: number
12
}

项目的工具链也可以保持一致,包括 ESLint、Prettier / Biome、tsconfig 和包管理器 yarn。团队不需要同时维护 Python 与 TypeScript 两套开发、检查和构建配置。

对于以 API 编排为主的服务端,统一语言还能减少上下文切换。AI 伴侣后端的大部分工作是调用 LLM、查询数据库和组装 Prompt,并不依赖 Python 在数据科学领域的能力,前端开发者也不必为了这些工作额外切换语言。

Hono.js 还提供 RPC 客户端,可以根据服务端路由自动推断请求参数和响应类型。

server.ts
01
// 后端:定义路由
02
const route = app.post('/chat',
03
zValidator('json', chatSchema),
04
async (c) => {
05
const body = c.req.valid('json')
06
return c.json({ reply: '...', emotion: 'happy' })
07
}
08
)
09
10
export type AppType = typeof route
client.ts
1
// 前端:自动推断请求和响应类型,无需任何手动定义
2
import { hc } from 'hono/client'
3
import type { AppType } from '../server'
4
5
const client = hc<AppType>('/api')
6
7
// res 的类型自动推断为 { reply: string, emotion: string }
8
const res = await client.chat.$post({ json: { content: '你好' } })

这样一来,前端调用接口时能够获得与本地函数相近的类型检查体验。请求参数写错后,TypeScript 编译器会直接报错,不需要再手动维护一组完全对应的 interface

FastAPI 本身同样具有完善的类型和校验能力,但 Python 类型无法直接与 TypeScript 互通。项目需要额外维护 Python 运行时、pip 或 poetry 依赖、类型生成流程,以及一套独立的部署流水线。

3.4 CloudFlare 生态集成

确定使用 CloudFlare Workers 后,框架能否直接使用平台提供的服务,会影响后续接口实现的复杂度。

Hono.js 原生支持 Workers Bindings:

index.ts
01
import { Hono } from 'hono'
02
03
type Bindings = {
04
KV: KVNamespace // 键值存储
05
DB: D1Database // SQL 数据库
06
VECTORIZE: VectorizeIndex // 向量数据库
07
AI: Ai // Workers AI 推理
08
}
09
10
const app = new Hono<{ Bindings: Bindings }>()
11
12
app.post('/chat', async (c) => {
13
// 直接通过 c.env 访问所有 CloudFlare 服务,完整的类型提示
14
const emotion = await c.env.KV.get(`emotion:${userId}`, 'json')
15
const memories = await c.env.DB.prepare('SELECT ...').all()
16
const embedding = await c.env.AI.run('@cf/baai/bge-base-en-v1.5', { text: query })
17
const similar = await c.env.VECTORIZE.query(embedding.data[0], { topK: 5 })
18
19
return c.json({ /* ... */ })
20
})

前面几篇文章使用的 KV、D1、Vectorize 和 Workers AI,都可以通过 c.env 直接访问,并且保留完整的 TypeScript 类型提示。

FastAPI 无法直接使用这些 Bindings。如果仍然希望从外部 Python 服务访问 CloudFlare 的相关能力,就需要改为调用 REST API,这会增加网络请求和集成代码。

3.5 中间件与 API 编排

AI 伴侣后端不以复杂的业务逻辑为主,但请求处理过程仍然需要精细编排。一条消息通常要依次经过安全检查、身份验证、记忆检索、Prompt 组装、LLM 调用、记忆写回和响应返回。

Hono.js 的中间件模型可以把这些步骤拆成清晰的处理层:

index.ts
01
import { Hono } from 'hono'
02
import { cors } from 'hono/cors'
03
import { logger } from 'hono/logger'
04
import { timing } from 'hono/timing'
05
06
const app = new Hono()
07
08
// 内置中间件
09
app.use('*', cors())
10
app.use('*', logger())
11
app.use('*', timing())
12
13
// 自定义中间件:安全检查
14
app.use('/chat/*', async (c, next) => {
15
const content = await c.req.text()
16
if (containsUnsafeContent(content)) {
17
return c.json({ error: '内容不合规' }, 403)
18
}
19
await next()
20
})
21
22
// 自定义中间件:身份验证
23
app.use('/chat/*', async (c, next) => {
24
const token = c.req.header('Authorization')
25
const user = await verifyToken(token)
26
c.set('user', user)
27
await next()
28
})
29
30
// 路由处理
31
app.post('/chat/message', async (c) => {
32
const user = c.get('user')
33
// 已经通过了安全检查和身份验证
34
// ...
35
})

FastAPI 同样提供中间件和依赖注入,而且它的依赖注入系统在复杂场景中更强。对于当前这种以顺序编排为主的接口,Hono.js 的洋葱模型已经可以清楚地组织处理过程,代码也更容易沿着请求路径阅读。

4. FastAPI 更适合哪些场景

这次选择 Hono.js,并不意味着 FastAPI 的能力不足。下面这些场景中,FastAPI 仍然可能是更合适的框架。

数据科学与机器学习。 如果服务端需要使用 pandas、numpy 处理数据,或者通过 PyTorch、transformers 完成模型训练与推理,Python 生态仍然很难替代。当前 AI 伴侣的服务端只负责编排,不直接执行这些任务。

自动生成 API 文档。 FastAPI 可以基于 OpenAPI 规范自动生成 Swagger UI 和 ReDoc 交互式文档。API 需要提供给第三方开发者时,这项能力很有价值。Hono.js 也可以通过 zod-openapi 支持 OpenAPI,但成熟度不如 FastAPI。

复杂的依赖注入。 FastAPI 的 Depends() 可以构建依赖树,并自动完成解析和注入。大型单体应用需要组织复杂依赖关系时,这套机制会更有优势。

以 Python 为主的团队。 如果团队成员都熟悉 Python,强行改用 TypeScript 开发后端反而会增加沟通和维护成本。框架选择还要结合团队已有的工程能力,不能只比较框架功能。

5. 总结

把 AI 伴侣当前的需求放在一起,可以得到下面这张选型表:

需求FastAPI 能否满足Hono.js 能否满足
部署在 CloudFlare Workers不能原生支持
冷启动 < 10ms不能< 5ms
前后端 TypeScript 类型共享不能天然支持
直接访问 KV / D1 / Vectorize需要外部 API 调用通过 Bindings 原生访问
流式 SSE 响应(LLM 输出)支持(需配置)原生支持
轻量级 API 编排支持(偏重)完美匹配
数据科学 / ML 推理强项不适用
自动 API 文档内置(强)社区方案(中)

FastAPI 是一个成熟且能力完整的 API 框架,只是它不符合这个项目已经确定的部署条件。当前后端不负责模型推理和数据处理,因此用不到 Python 生态最有优势的部分。项目真正需要的是边缘运行能力、较低的冷启动开销、CloudFlare 服务的直接集成,以及与前端共享 TypeScript 类型。

按照这些硬性条件逐项判断,Hono.js 是两个候选中唯一能够全部满足要求的框架。这个结论来自部署平台和业务需求,而不是对框架本身做简单的优劣排序。

后续文章会基于 Hono.js 和 CloudFlare Workers 搭建服务端,从路由设计、中间件编排到与 LLM 的流式通信,逐步实现完整的对话处理管线。