前言
随着 LLM 从实验 Demo 走向商业化落地,越来越多开发者开始搭建面向生产的大模型业务系统。很多 AI 工程师擅长 Prompt 调试、RAG、Agent 开发,但缺乏后端架构思维:系统简单堆砌接口、数据表杂乱无章、大量重复推理请求压垮模型服务、业务迭代后代码严重耦合,上线后出现查询缓慢、并发雪崩、难以扩展等各类问题。
一份真实企业 AI 后端岗位要求明确提出:熟练掌握 RESTful API 设计、数据库建模、缓存、消息队列、异步任务、系统拆分,具备良好接口设计与系统拆分能力。
本文结合企业级 LLM 智能体业务平台实战经验,围绕数据库建模、多级缓存架构、领域驱动系统拆分三大核心板块展开,完整讲解大模型业务场景下的后端工程落地方法论,配套 Python (FastAPI) 完整示例代码,覆盖对话管理、知识库管理、任务调度、用量统计等典型 LLM 业务场景,帮助 AI 工程师补齐后端架构短板,搭建可长期迭代、支撑高并发的大模型业务系统。
一、大模型业务系统业务特征与架构痛点
在开展设计之前,首先要认清 LLM 业务和传统 Web 业务的差异化特点:
请求耗时极不均衡:普通接口毫秒级,大模型流式推理往往数秒~几十秒,同步接口极易超时;
资源成本高昂:LLM 推理消耗大量 GPU 算力,相同 Query 重复推理会造成巨额资源浪费;
数据种类复杂:用户对话消息、知识库文档、Agent 任务记录、模型调用账单、权限配置多类数据并存;
任务形态多样化:即时对话、文档异步解析、长周期 Agent 任务、定时数据统计混合存在;
流量波动明显:营销活动、业务高峰会带来流量尖峰,若无缓存、队列削峰极易造成服务崩溃。
常见反面案例:
所有数据挤在一张对话表,不分库分表、缺少合理索引,历史对话查询越跑越慢;
用户相同问题每次都重复调用 LLM 推理,没有缓存策略;
全部逻辑写在单一 FastAPI 服务,知识库、对话、计费、Agent 任务耦合在一起,改动一处影响全系统;
同步执行文档向量化、长文本总结,高并发场景接口大面积超时。
针对以上痛点,下文从数据库建模→缓存分层设计→业务系统拆分逐层落地。
二、大模型业务系统数据库建模实战
2.1 建模设计原则(LLM 场景专属)
冷热数据分离:近期活跃对话、历史归档对话拆分为不同数据表;
大字段独立存储:对话完整 content、知识库原文等超大文本禁止和基础字段混表;
区分事务型数据与日志统计数据:业务核心数据使用 MySQL,海量审计日志、原始推理记录存入时序库 / 对象存储;
预留扩展字段:适配不同模型、不同 Agent 新增参数,避免频繁 DDL 改表;
适度冗余,减少多表 Join:大模型业务后台查询频繁,优先降低关联查询复杂度。
2.2 领域数据表结构设计(MySQL)
我们以「企业 LLM 对话 & 知识库 Agent 平台」为例,梳理核心实体:租户、用户、对话会话、对话消息、知识库文档、模型调用账单。
sql
– 1.租户表(多租户平台基础)
CREATE TABLE llm_tenant (
id bigint PRIMARY KEY AUTO_INCREMENT COMMENT ‘租户ID’,
tenant_name varchar(100) NOT NULL COMMENT ‘租户名称’,
contact_email varchar(100) COMMENT ‘联系人邮箱’,
status tinyint NOT NULL DEFAULT 1 COMMENT ‘状态:0禁用 1正常’,
daily_token_quota bigint DEFAULT 0 COMMENT ‘每日token配额’,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘租户信息表’;

– 2.会话主表(一次对话=一个session)
CREATE TABLE llm_chat_session (
id bigint PRIMARY KEY AUTO_INCREMENT,
session_id varchar(64) NOT NULL COMMENT ‘会话唯一标识’,
tenant_id bigint NOT NULL COMMENT ‘所属租户’,
user_id varchar(64) NOT NULL COMMENT ‘用户ID’,
agent_id varchar(64) COMMENT ‘绑定智能体ID’,
title varchar(255) COMMENT ‘对话标题’,
status tinyint DEFAULT 1 COMMENT ‘会话状态’,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_session_id (session_id),
KEY idx_tenant_user (tenant_id, user_id)
) COMMENT=‘对话会话表’;

– 3.对话消息表【核心】存储每一轮问答
CREATE TABLE llm_chat_message (
id bigint PRIMARY KEY AUTO_INCREMENT,
session_id varchar(64) NOT NULL COMMENT ‘关联会话ID’,
role varchar(20) NOT NULL COMMENT ‘user/assistant/system’,
message_short varchar(512) COMMENT ‘消息简短预览’,
message_content_id bigint COMMENT ‘大文本内容外键,关联消息内容附表’,
model_name varchar(64) COMMENT ‘本次调用模型’,
input_tokens int DEFAULT 0 COMMENT ‘输入token’,
output_tokens int DEFAULT 0 COMMENT ‘输出token’,
cost_ms int DEFAULT 0 COMMENT ‘推理耗时ms’,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
KEY idx_session (session_id)
) COMMENT=‘对话消息表’;

– 4.消息内容附表【冷热拆分,大文本独立存储】
CREATE TABLE llm_message_content (
id bigint PRIMARY KEY AUTO_INCREMENT,
full_content LONGTEXT NOT NULL COMMENT ‘完整对话内容’,
created_at datetime DEFAULT CURRENT_TIMESTAMP
) COMMENT=‘对话大文本附表’;

– 5.知识库文档主表
CREATE TABLE llm_knowledge_doc (
id bigint PRIMARY KEY AUTO_INCREMENT,
doc_id varchar(64) NOT NULL,
tenant_id bigint NOT NULL,
kb_id varchar(64) NOT NULL COMMENT ‘所属知识库ID’,
doc_name varchar(255) NOT NULL COMMENT ‘文档名称’,
source_type varchar(32) COMMENT ‘pdf/md/txt’,
status tinyint DEFAULT 0 COMMENT ‘0待解析 1解析完成 2失败’,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_doc_id(doc_id),
KEY idx_kb_status(kb_id, status)
) COMMENT=‘知识库文档’;

– 6.模型调用账单统计表
CREATE TABLE llm_usage_bill (
id bigint PRIMARY KEY AUTO_INCREMENT,
tenant_id bigint NOT NULL,
session_id varchar(64),
model_name varchar(64) NOT NULL,
total_input_tokens bigint DEFAULT 0,
total_output_tokens bigint DEFAULT 0,
stat_date date NOT NULL COMMENT ‘统计日期’,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_tenant_date(tenant_id, stat_date, model_name),
KEY idx_stat_date(stat_date)
) COMMENT=‘用量日统计表’;
2.3 建模重点总结
大文本拆分:将超长对话文本单独存入llm_message_content,日常列表查询只读取预览短文本,避免大量 IO;
** 避免 SELECT ***,生产严禁查询 LONGTEXT 字段做列表分页;
统计数据做预聚合,每日用量写入 bill 统计表,不要实时聚合原始消息表做账单查询;
超过 6 个月的历史对话,定时归档至归档表,保障活跃数据表体量可控。
三、多级缓存架构设计(LLM 系统降本核心)
大模型最大成本在于 GPU 推理算力,缓存不仅仅是加速接口,更是降低算力开销、节约成本最重要的手段。我们设计三级缓存体系:本地内存缓存 → Redis 分布式缓存 → 模型结果缓存。
3.1 缓存适用场景
✅ 适合缓存:
无上下文独立问答、高频重复通用问题;
知识库检索结果(短时间知识库未更新,检索结果不变);
租户配置、智能体提示词模板、静态参数;
每日 Token 用量统计数据。
❌ 不建议缓存:
多轮上下文依赖对话;
需要实时查询数据库 / 外部 API 的动态数据;
时效性要求极高、频繁变更的业务数据。
3.2 FastAPI + Redis 缓存完整代码实现
python
运行
import hashlib
import json
import redis
from fastapi import FastAPI
from functools import lru_cache
from pydantic import BaseModel
from typing import Optional

app = FastAPI(title=“LLM系统缓存示例”)

连接Redis

redis_client = redis.Redis(host=“127.0.0.1”, port=6379, db=0, decode_responses=True)

请求结构体

class ChatRequest(BaseModel):
session_id: str
query: str
model_name: str
temperature: float = 0.7
use_cache: bool = True

--------------------------工具函数--------------------------

def generate_cache_key(query: str, model: str, temperature: float) -> str:
“”“生成唯一缓存key,不同参数区分缓存结果”“”
raw_str = f"{query}|{model}|{temperature:.2f}"
md5_key = hashlib.md5(raw_str.encode(“utf-8”)).hexdigest()
return f"llm:cache:reply:{md5_key}"

@lru_cache(maxsize=2000)
def get_local_static_config(tenant_id: str):
“”“一级缓存:本地内存缓存,存放极少变更的租户配置、Prompt模板”“”
# 模拟数据库查询
print(“【未命中本地缓存,查询数据库】”)
return {
“prompt_template”: “你是企业智能客服,基于知识库回答用户问题”,
“max_context_len”: 8192
}

async def llm_infer(query: str, model_name: str, temp: float):
“”“模拟真实大模型推理(生产对接vLLM/OpenAI接口)”“”
print(f"执行真实LLM推理 query={query}“)
return f”【模型回复】针对问题:{query} 的标准回答内容"

--------------------------对话接口--------------------------

@app.post(“/api/chat/completion”)
async def chat_endpoint(req: ChatRequest):
# 多轮对话不启用结果缓存;单轮独立问答开启缓存
if req.use_cache and len(req.session_id) <= 12:
cache_key = generate_cache_key(req.query, req.model_name, req.temperature)
cache_data = redis_client.get(cache_key)
if cache_data:
print(“命中Redis模型结果缓存”)
return {“reply”: json.loads(cache_data), “cache_hit”: True}

# 缓存未命中,调用大模型推理
llm_result = await llm_infer(req.query, req.model_name, req.temperature)

# 写入缓存,过期时间30分钟,知识库更新时主动清理对应缓存
if req.use_cache:
    redis_client.setex(
        cache_key,
        1800,
        json.dumps(llm_result, ensure_ascii=False)
    )
return {"reply": llm_result, "cache_hit": False}

获取租户配置接口(使用本地内存缓存)

@app.get(“/api/tenant/config”)
async def get_tenant_config(tenant_id: str):
config = get_local_static_config(tenant_id)
return config

if name == “main”:
import uvicorn
uvicorn.run(app, host=“0.0.0.0”, port=8000)
3.3 缓存避坑策略
缓存一致性:知识库文档新增 / 修改 / 删除时,主动清理检索结果缓存与问答缓存,避免旧知识持续输出;
缓存雪崩:缓存过期时间增加随机偏移量,防止大量 key 同一时刻失效;
缓存穿透:高频不存在的 query 设置空值短期缓存;
冷热分离:动态推理结果缓存短 TTL,基础配置类缓存长期有效,变更主动删除。
四、领域驱动:大模型业务系统如何合理拆分
很多初期项目全部代码写在单一服务,随着迭代膨胀上万行代码,每次上线风险巨大。我们按照领域边界拆分服务,结合异步消息队列消解 LLM 长耗时任务。
4.1 推荐拆分方案(适合中大型 LLM 平台)
Gateway 网关服务
负责鉴权、路由、限流、日志审计、请求转发(对应多租户平台接入层);
对话业务服务(chat-service Python/FastAPI)
用户对话管理、会话 CRUD、多轮上下文组装、调用推理集群;
知识库服务(knowledge-service)
文档上传、文本切割、向量化入库、向量库管理、RAG 检索;
Agent 调度服务(agent-service)
任务规划、工具调用、长周期任务管理、智能体工作流执行;
用量 & 计费服务(bill-service Java/SpringBoot)
Token 用量统计、租户配额校验、账单生成、定时结算;
异步任务 Worker 集群
文档异步解析、批量向量化、模型评测任务、定时报表,基于 RabbitMQ/RocketMQ 解耦。
4.2 同步改造异步案例(消息队列实战示例)
原始问题:用户上传 PDF 文档,同步执行文档解析、文本分割、向量化入库。文档越大耗时越长,极易接口超时。
优化方案:接口仅接收文件,投递消息队列,由消费 Worker 异步处理。
python
运行

消息生产者:知识库上传接口

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(‘127.0.0.1’))
channel = connection.channel()
channel.queue_declare(queue=“doc_parse_queue”, durable=True)

@app.post(“/api/knowledge/upload_doc”)
async def upload_document(kb_id: str, doc_name: str):
“”“文档上传接口,只投递消息,不阻塞”“”
# 1.数据库创建文档记录,状态=待解析
doc_info = {
“kb_id”: kb_id,
“doc_name”: doc_name,
“doc_id”: “doc_xxxx123”
}
# db.insert(llm_knowledge_doc, data…)
# 2.投递异步任务
channel.basic_publish(
exchange=“”,
routing_key=“doc_parse_queue”,
body=json.dumps(doc_info),
properties=pika.BasicProperties(delivery_mode=2)
)
return {“code”:0, “msg”:“文档已接收,后台开始解析”}
消费者 Worker 独立进程执行耗时任务,不占用 Web 服务线程池,实现服务解耦。
4.3 系统拆分核心原则
以业务领域划分,不要按技术层拆分;
长耗时任务一律异步化,避免拖垮 Web 接口;
服务之间通过 HTTP / 消息队列通信,禁止直接跨服务访问数据库;
小团队初期不必过度微服务,可以先模块分层,预留拆分边界,避免过度微服务带来运维负担。
五、全链路落地问题复盘
5.1 数据库踩坑总结
不分冷热表,对话表持续膨胀 → 解决方案:冷热拆分 + 定时归档;
查询不分页,前端一次性拉取全部历史对话 → 强制分页、限制单次最大条数;
缺少索引,列表查询全表扫描 → 所有查询条件建立合适联合索引。
5.2 缓存踩坑总结
不分场景无脑缓存多轮对话,造成上下文错乱 → 多轮对话关闭结果缓存;
缓存永久有效,知识库更新后问答依然使用旧内容 → 设计主动失效机制。
5.3 系统拆分踩坑总结
初期追求微服务,拆分大量小服务,运维复杂度暴增;
同步接口执行向量化、文档解析,高峰期大量请求超时;
服务之间直接访问 MySQL,丧失数据权限管控,后续无法拆分。
六、总结
对于 AI 大模型工程师来说,仅仅掌握大模型调用、RAG、Agent 远远不足以独立负责商业化项目。数据库建模决定系统数据底座能否长期稳定扩展;多级缓存直接控制 GPU 算力成本;合理系统拆分决定项目迭代维护成本。
一套成熟 LLM 业务后端,应当做到:
数据分层存储、冷热分离;算力资源通过缓存节约;长短任务分离,同步异步合理搭配;按照业务领域清晰划分模块与服务。
当你能够完整从数据表设计、缓存策略、服务拆分独立完成整套 LLM 平台后端设计时,就完成了从「只会调用 API 的 AI 应用开发者」到「具备架构能力的 AI 后端工程师」的跨越。
后续进阶方向:可以继续研究分布式定时任务、链路追踪、服务监控告警、多租户数据隔离、灰度发布等云原生能力,持续完善大模型平台工程体系。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐