【学习记录】从零搭建 DeepSeek LLM API 服务:FastAPI + LlamaIndex 实践
国产大模型 DeepSeek(深度求索)凭借高性价比和强大的推理能力,成为许多开发者的首选。本文将展示如何通过 LlamaIndex 框架调用 DeepSeek Chat 模型,并基于 FastAPI 将其封装为标准的 HTTP API 服务。你可以轻松地将这个服务集成到自己的应用中,实现代码生成、问答、对话等功能。文章涵盖原理、环境配置、代码实现、测试方法以及生产环境注意事项。
📌 目录
- [DeepSeek 模型与 LlamaIndex 简介](#DeepSeek 模型与 LlamaIndex 简介)
- [环境配置与 API Key 获取](#环境配置与 API Key 获取)
- [基础调用:直接使用 DeepSeek 类](#基础调用:直接使用 DeepSeek 类)
- [封装为 FastAPI 服务](#封装为 FastAPI 服务)
- 接口测试
- 注意事项与生产优化
- 总结
一、DeepSeek 模型与 LlamaIndex 简介
1.1 DeepSeek
DeepSeek 是由深度求索公司推出的大语言模型系列,其中 deepseek-chat 模型在代码生成、逻辑推理、数学解题等任务上表现优异,并且 API 价格极为低廉(百万 tokens 仅需 1 元人民币左右),非常适合开发者集成到自己的应用中。
1.2 LlamaIndex 的 LLM 集成
LlamaIndex 是一个专为 RAG 应用设计的框架,它内置了对多种 LLM 的适配器,包括 OpenAI、DeepSeek、通义千问等。通过统一的 llm.chat() 接口,我们可以轻松切换不同的模型提供商,而无需修改业务逻辑。
本示例中使用的 llama_index.llms.deepseek.DeepSeek 类封装了 DeepSeek API 的调用细节,支持:
- 同步/异步调用
- 系统提示词(system prompt)
- 参数配置(temperature、max_tokens、timeout 等)
二、环境配置与 API Key 获取
2.1 安装依赖
创建虚拟环境(推荐 Python 3.9+)并安装以下包:
bash
pip install fastapi uvicorn llama-index-core llama-index-llms-deepseek pydantic
说明 :
llama-index-llms-deepseek是 LlamaIndex 针对 DeepSeek 的官方适配器。如果安装失败,也可以直接从 GitHub 安装最新版。
2.2 获取 DeepSeek API Key
- 访问 DeepSeek 开放平台 注册账号。
- 登录后进入控制台,创建 API Key。
- 将 API Key 保存,后续代码中需要填入。
⚠️ 重要:请勿将 API Key 硬编码到代码中并提交到公开仓库。建议使用环境变量或配置文件。
三、基础调用:直接使用 DeepSeek 类
我们先写一个简单的脚本验证 API 连通性。
python
import os
from llama_index.llms.deepseek import DeepSeek
# 设置 API Key(请替换为你的真实 Key)
DEEPSEEK_API_KEY = "sk-xxxxxxxxxxxxxxxx"
llm = DeepSeek(
model="deepseek-chat",
api_key=DEEPSEEK_API_KEY,
temperature=0.3,
max_tokens=2048
)
response = llm.complete("用Python写一个计算斐波那契数列的函数")
print(response)
输出示例(模型生成的代码):
python
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
print(a, end=' ')
a, b = b, a + b
print()
这段代码直接调用了 DeepSeek 的 complete 方法,适用于单轮问答。
支持多轮对话
如果需要支持多轮对话,可以使用 chat 方法:
python
from llama_index.core.llms import ChatMessage
messages = [
ChatMessage(role="system", content="你是一个Python专家,只输出代码,不要解释。"),
ChatMessage(role="user", content="写一个快速排序函数")
]
response = llm.chat(messages)
print(response.message.content)
四、封装为 FastAPI 服务
在实际应用中,我们通常需要将 LLM 能力以 HTTP API 的形式暴露给其他服务使用。下面使用 FastAPI 创建一个 /generate 端点。
4.1 完整代码(main.py)
python
import os
import logging
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from llama_index.llms.deepseek import DeepSeek
from llama_index.core.llms import ChatMessage
# 日志配置
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 配置 DeepSeek(强烈建议从环境变量读取 API Key)
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY", "your-key-here")
DEFAULT_MODEL = "deepseek-chat"
llm = DeepSeek(
model=DEFAULT_MODEL,
api_key=DEEPSEEK_API_KEY,
temperature=0.3,
max_tokens=2048,
timeout=60.0,
)
# 请求/响应模型
class GenerateRequest(BaseModel):
prompt: str = Field(..., description="用户输入的提示词")
system_prompt: str | None = Field(None, description="可选的系统提示词")
class GenerateResponse(BaseModel):
response: str
model: str
# FastAPI 应用
app = FastAPI(title="DeepSeek LLM API")
@app.get("/health")
async def health():
return {"status": "ok", "model": DEFAULT_MODEL}
@app.post("/generate", response_model=GenerateResponse)
async def generate_text(request: GenerateRequest):
try:
messages = []
if request.system_prompt:
messages.append(ChatMessage(role="system", content=request.system_prompt))
messages.append(ChatMessage(role="user", content=request.prompt))
response = llm.chat(messages)
answer = response.message.content
return GenerateResponse(response=answer, model=DEFAULT_MODEL)
except Exception as e:
logger.error(f"推理失败: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail=f"模型推理失败: {str(e)}")
4.2 运行服务
bash
export DEEPSEEK_API_KEY="sk-xxxxxx" # Linux/macOS
# 或 set DEEPSEEK_API_KEY=sk-xxxxxx # Windows
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
服务启动后,可以访问 http://localhost:8000/docs 查看自动生成的 API 文档。
五、接口测试
5.1 使用 curl 测试
bash
curl -X POST "http://localhost:8000/generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "用Python写斐波那契数列",
"system_prompt": "只输出代码,不要解释"
}'
响应示例:
json
{
"response": "def fibonacci(n):\n a, b = 0, 1\n for _ in range(n):\n print(a, end=' ')\n a, b = b, a + b\n\nfibonacci(10)",
"model": "deepseek-chat"
}
5.2 使用 Python requests 测试
python
import requests
resp = requests.post(
"http://localhost:8000/generate",
json={"prompt": "解释一下什么是RAG", "system_prompt": "用中文回答"}
)
print(resp.json()["response"])
六、注意事项与生产优化
6.1 安全相关
| 问题 | 建议 |
|---|---|
| API Key 泄露 | 使用环境变量 DEEPSEEK_API_KEY,不要硬编码。生产环境可使用密钥管理服务(如 AWS Secrets Manager)。 |
| 无认证机制 | 建议在网关层或 FastAPI 中添加 API Key 认证(例如 fastapi.security.APIKeyHeader)。 |
| 请求体过大 | 限制 prompt 的最大长度(如 4000 字符),防止恶意超长输入。 |
6.2 性能优化
| 方面 | 优化措施 |
|---|---|
| 并发处理 | FastAPI 本身支持异步,但 llm.chat 是同步调用,会阻塞事件循环。建议使用 asyncio.to_thread 或升级为异步客户端(如果 DeepSeek SDK 支持)。 |
| 超时控制 | 设置 timeout=60.0,避免某个请求长期占用资源。 |
| 缓存 | 对相同的 prompt 可以缓存结果(如使用 Redis),减少重复调用和费用。 |
| 流式响应 | 若需要流式输出,可以使用 StreamingResponse 配合 llm.stream() 方法。 |
6.3 错误处理
当前代码捕获了所有异常并返回 500,但可以细化:
- 网络超时 → 504
- 无效 API Key → 401
- 内容被过滤 → 400
可以这样做:
python
from llama_index.core.llms import LLMError
try:
response = llm.chat(messages)
except LLMError as e:
if "401" in str(e):
raise HTTPException(status_code=401, detail="API Key无效")
elif "timeout" in str(e).lower():
raise HTTPException(status_code=504, detail="模型响应超时")
else:
raise HTTPException(status_code=500, detail=str(e))
6.4 日志与监控
- 记录每次请求的
prompt长度、响应耗时、token 用量(DeepSeek API 返回的响应头或 body 中可能包含)。 - 使用 Prometheus + Grafana 监控 API 的 QPS、延迟、错误率。
七、总结
通过本文,你学会了:
- ✅ 如何使用 LlamaIndex 调用 DeepSeek 大模型。
- ✅ 如何将模型封装为 FastAPI 服务,提供 RESTful API。
- ✅ 如何测试接口,以及生产环境的安全与优化建议。
这个服务可以作为微服务架构中的"智能大脑",供其他业务调用。你可以在此基础上扩展:
- 支持多轮对话(通过传递
messages历史)。 - 集成 RAG 能力(加载本地文档,检索后增强提示词)。
- 接入其他国产模型(如通义千问、智谱 GLM),只需替换
llm实例。
希望本文能帮助你快速搭建自己的 LLM API 服务。如果有任何问题,欢迎在评论区交流讨论。