为什么 AI 编排层要选 FastAPI 而不是 Django?深度解析 + 适合场景

标签FastAPI LangChain AI Agent Python 后端架构

前言

在构建 AI Agent 系统(比如智能客服、RAG 问答、多工具编排)时,Python 后端框架的选择是绕不开的问题。很多有 Django 经验的开发者会下意识地问:

“我已经熟悉 Django 了,为什么要换 FastAPI?”

这个问题问得好。本文不是要否定 Django,而是从 AI 编排层的核心技术需求出发,系统解释为什么 FastAPI 在这个场景下是更合适的选择,并给出清晰的适用边界。


一、先搞清楚"AI 编排层"到底在做什么

在讨论框架选型之前,先明确 AI 编排层的职责:

用户消息
    ↓
[AI 编排层] ← 这一层负责:
    ├── 接收用户输入
    ├── 调用 LLM(思考)
    ├── 工具调用(查订单、搜知识库)
    ├── 多轮对话记忆管理
    └── 流式返回结果给前端
    ↓
业务层 API(Java / PHP / Go)
    ↓
数据库

这一层的核心特征是:

  • I/O 密集型:大量时间在等 LLM 返回、等工具 API 响应
  • 需要流式输出:LLM 边生成边推送给前端,用户体验更好
  • 并发工具调用:多个工具可以同时发起请求,不应串行等待
  • 轻量无状态:不需要操作数据库,不需要模板渲染

理解了这四点,框架选型的答案就已经呼之欲出了。


二、FastAPI 的四大核心优势

2.1 原生异步,天然匹配 LangChain

FastAPI 基于 asyncio 设计,每一个路由函数都可以是 async def,工具调用可以并发执行:

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from langchain.agents import AgentExecutor

app = FastAPI()

@app.post("/chat")
async def chat(request: ChatRequest):
    # async def 天然支持,不阻塞其他请求
    response = await agent_executor.ainvoke({"input": request.message})
    return {"output": response["output"]}

LangChain 的异步 API 全部以 a 开头:ainvokeastreamastream_events,与 FastAPI 的 async def 无缝配合。

对比 Django:

Django 虽然从 3.1 开始支持 ASGI,但其 ORM、中间件、Session 等核心组件大量是同步实现的。在同一个请求中混用同步和异步代码,必须使用 sync_to_async 包装,代码复杂且容易踩坑:

# Django 中调用同步 ORM 需要包装,繁琐且易出错
from asgiref.sync import sync_to_async

@async_to_sync
async def my_view(request):
    # 必须包装才能在异步上下文中调用同步 ORM
    orders = await sync_to_async(Order.objects.filter)(user_id=1)

结论:AI 编排层几乎全是 I/O 等待,异步是刚需,不是锦上添花。FastAPI 原生支持,Django 逆流而上。


2.2 流式输出(SSE)是一等公民

AI 应用的标志性体验是"打字机效果"——LLM 边生成边推送。这依赖 Server-Sent Events(SSE)WebSocket

FastAPI 用 StreamingResponse 三行搞定:

from fastapi.responses import StreamingResponse
from langchain.callbacks import AsyncIteratorCallbackHandler

@app.post("/chat/stream")
async def chat_stream(request: ChatRequest):
    handler = AsyncIteratorCallbackHandler()

    async def generate():
        async for chunk in agent.astream_events(
            {"input": request.message}, version="v2"
        ):
            if chunk["event"] == "on_chat_model_stream":
                token = chunk["data"]["chunk"].content
                yield f"data: {token}\n\n"  # SSE 格式

    return StreamingResponse(generate(), media_type="text/event-stream")

前端 Vue 3 接收:

const es = new EventSource('/chat/stream')
es.onmessage = (e) => {
  chatContent.value += e.data  // 字符逐个追加,打字机效果
}

Django 实现同等效果需要引入 Django Channels,配置 ASGI、Channel Layer、Consumer,代码量是 FastAPI 的 5 倍以上,且调试复杂度成倍增加。

结论:流式输出是 AI 应用的标配体验,FastAPI 原生支持,Django 需要大量额外配置。


2.3 极简轻量,专注 API

Django 的设计哲学是"batteries included"——内置 ORM、Admin、模板引擎、表单系统、Session 管理……这些对 Web 应用很有价值,但对 AI 编排层来说全是不需要的负重。

AI 编排层根本不需要:

Django 内置功能 AI 编排层是否需要
ORM / 数据库操作 ❌ 数据在 Java 业务层
Admin 后台
模板引擎 ❌ 纯 API 服务
Form 系统
Session 管理 ❌ 用 Redis 管对话记忆
用户认证系统 ❌ 由网关统一处理

FastAPI 只做一件事:快速构建高性能 API。它的核心依赖只有 starlettepydantic,启动速度快,内存占用低,部署简单。

# FastAPI 最小依赖
fastapi
uvicorn[standard]
pydantic

# 对比 Django 最小依赖
django
djangorestframework
django-cors-headers
gunicorn
... (还有一堆)

结论:AI 编排层是纯 API 服务,不需要 Django 的全家桶,轻量才是正确方向。


2.4 自动文档,联调效率翻倍

FastAPI 基于 Python 类型注解自动生成 OpenAPI / Swagger 文档,零额外配置:

from pydantic import BaseModel

class ChatRequest(BaseModel):
    message: str
    session_id: str
    user_id: int

class ChatResponse(BaseModel):
    output: str
    tool_calls: list[str]

@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
    ...

启动服务后访问 http://localhost:8000/docs,自动得到可交互的 Swagger 文档。Java 团队、前端团队直接看文档联调,不需要单独写接口文档。

Django REST Framework 虽然也能通过 drf-spectacular 生成文档,但需要额外安装配置,且与 DRF 的 Serializer 体系绑定,灵活度不如 FastAPI 的 Pydantic。

结论:类型即文档,减少团队沟通成本,尤其在多语言协作(Python + Java)场景下价值显著。


三、性能对比:数字说话

以下是主流 Python 框架在并发 API 场景下的基准性能参考(请求/秒,越高越好):

框架                  RPS(参考值)    异步支持    适合场景
─────────────────────────────────────────────────────
FastAPI (uvicorn)     ~30,000+        原生        AI 编排、微服务 API
Django (gunicorn)     ~3,000          受限        Web 应用、管理后台  
Flask (gunicorn)      ~5,000          受限        轻量 Web、简单 API
Django (uvicorn)      ~8,000          部分        折中方案,踩坑多

注:实际性能受业务逻辑影响,以上为空路由基准,仅供数量级参考。

对于 AI 编排层,瓶颈通常在 LLM 调用延迟(1-3 秒),而不在框架本身。但在高并发场景(百人同时对话),异步框架能用相同资源服务更多请求,差距会被放大。


四、适合场景完整梳理

✅ 强烈推荐 FastAPI 的场景

场景 原因
AI Agent 编排(LangChain / LangGraph) 异步工具调用、流式输出是刚需
RAG 知识库问答系统 向量检索 + LLM 生成全是 I/O 密集型
LLM 代理服务 / 模型网关 高并发转发,异步性能优势明显
微服务 API 网关 轻量、高性能、自动文档
实时流式推送服务 SSE / WebSocket 原生支持
多语言协作项目的 Python 服务 自动文档降低联调成本

✅ Django 更合适的场景

场景 原因
需要完整后台管理系统 Django Admin 开箱即用,节省大量时间
复杂数据库模型 + 多表关联 Django ORM 成熟,迁移管理完善
内容管理系统(CMS) 模板引擎 + Admin 是 Django 的主场
全栈 Python Web 应用 前后端都用 Python,Django 一把梭
团队全是 Django 背景,业务重于 AI 熟悉度优先,别为了技术先进性牺牲交付速度

⚠️ 别踩的坑

❌ 用 Django 强行做流式 SSE → 需要 Channels,配置复杂,得不偿失
❌ 在 FastAPI 里引入 Django ORM → 破坏异步上下文,大量 sync_to_async 包装
❌ 用 FastAPI 做全栈 Web 应用 → 没有模板引擎,Admin 要自己写,吃力不讨好
❌ AI 编排层直连业务数据库 → 应该通过 HTTP 调业务层 API,职责分离

五、实际项目的推荐架构

基于以上分析,一套可落地的 AI 客服系统技术选型如下:

┌─────────────────────────────────────────────┐
│              前端层                          │
│         Vue 3 + Pinia + Vite                │
│     SSE 流式接收 · 管理后台 · 聊天 UI        │
└──────────────┬──────────────────────────────┘
               │ SSE / REST
┌──────────────▼──────────────────────────────┐
│           AI 编排层  ← FastAPI 的主场        │
│      FastAPI + LangChain + Redis            │
│   ReAct Agent · 工具调用 · 流式输出 · 记忆   │
└──────────────┬──────────────────────────────┘
               │ HTTP 调用(工具函数内部)
┌──────────────▼──────────────────────────────┐
│           业务 API 层  ← Java 的主场         │
│         Spring Boot + MySQL                 │
│      订单 · 工单 · 用户 · 业务逻辑           │
└─────────────────────────────────────────────┘

核心原则:AI 编排层和业务层通过 HTTP 解耦,各自专注自己的优势领域。Java 团队感知不到 LangChain 的存在,FastAPI 感知不到业务数据库的存在。


六、FastAPI 快速上手代码

下面是一个完整的最小可运行 AI 编排服务,包含流式输出和工具调用:

# main.py
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain.memory import ConversationBufferWindowMemory
from langchain.tools import tool
from langchain import hub
import httpx, json

app = FastAPI(title="AI 客服编排服务")

# ── 工具定义 ──────────────────────────────────
@tool
async def query_order(order_id: str) -> str:
    """查询订单状态。当用户询问订单进度时调用。格式:ORD-XXXXX"""
    async with httpx.AsyncClient() as client:
        # 调 Java 业务层接口,不直连数据库
        resp = await client.get(
            f"http://java-service/api/orders/{order_id}",
            headers={"X-Internal-Token": "your-token"},
            timeout=5.0
        )
        return resp.json()

@tool
async def search_knowledge(query: str) -> str:
    """检索知识库回答产品和政策问题。"""
    async with httpx.AsyncClient() as client:
        resp = await client.post(
            "http://java-service/api/knowledge/search",
            json={"query": query, "top_k": 3},
            timeout=5.0
        )
        return resp.json()

# ── Agent 初始化 ───────────────────────────────
llm = ChatOpenAI(model="deepseek-chat", temperature=0,
                 base_url="https://api.deepseek.com/v1")
tools = [query_order, search_knowledge]
prompt = hub.pull("hwchase17/react-chat")
memory = ConversationBufferWindowMemory(
    k=10, memory_key="chat_history", return_messages=True
)
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(
    agent=agent, tools=tools, memory=memory,
    max_iterations=5, handle_parsing_errors=True
)

# ── 接口定义 ───────────────────────────────────
class ChatRequest(BaseModel):
    message: str
    session_id: str

@app.post("/chat")
async def chat(req: ChatRequest):
    """普通响应接口"""
    result = await executor.ainvoke({"input": req.message})
    return {"output": result["output"]}

@app.post("/chat/stream")
async def chat_stream(req: ChatRequest):
    """流式 SSE 接口"""
    async def generate():
        async for event in executor.astream_events(
            {"input": req.message}, version="v2"
        ):
            if event["event"] == "on_chat_model_stream":
                token = event["data"]["chunk"].content
                if token:
                    yield f"data: {json.dumps({'token': token})}\n\n"
        yield "data: [DONE]\n\n"

    return StreamingResponse(generate(), media_type="text/event-stream")

# uvicorn main:app --reload --port 8000

七、总结

维度 FastAPI Django
异步支持 ✅ 原生设计 ⚠️ 后期加入,踩坑多
流式 SSE ✅ 三行代码 ❌ 需要 Channels
轻量性 ✅ 极简依赖 ❌ 全家桶,AI 层用不上
自动文档 ✅ 零配置 ⚠️ 需额外插件
性能 ✅ 接近 Node.js 🔶 同步模型受限
ORM / Admin ❌ 无内置 ✅ 最成熟
适合 AI 编排 强烈推荐 ❌ 不推荐
适合 Web 应用 🔶 可以但麻烦 最佳选择

一句话总结:FastAPI 是为 API 服务设计的,Django 是为 Web 应用设计的。AI 编排层的核心需求——异步、流式、轻量——与 FastAPI 的设计哲学完全一致,与 Django 的设计方向相悖。选对工具,事半功倍。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐