LangServe + FastAPI 搭建的大模型统一 API 服务,同时支持 OpenAI 模型、本地 Ollama 模型双路由
from fastapi import FastAPI # ✅ 新版标准导入 from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langserve import add_routes import uvicorn import os from langchain_community.llms import Ollama from dotenv import load_dotenv from fastapi.middleware.cors import CORSMiddleware load_dotenv() os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY") app = FastAPI( title="Langchain Server", version="1.0", description="A simple API Server" ) # 增加跨域,方便前端/Streamlit调用 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 原生OpenAI模型路由 add_routes( app, ChatOpenAI( model="qwen-turbo", base_url=os.getenv("OPENAI_API_BASE") ), path="/openai" ) openai_model = ChatOpenAI( model="qwen-turbo", base_url=os.getenv("OPENAI_API_BASE") ) # 替换为你常用的本地模型 ollama_llm = Ollama(model="qwen2.5:7b") prompt_essay = ChatPromptTemplate.from_template("Write me an essay about {topic} with 100 words") prompt_poem = ChatPromptTemplate.from_template("Write me an poem about {topic} for a 5 years child with 100 words") add_routes( app, prompt_essay | openai_model, path="/essay" ) add_routes( app, prompt_poem | ollama_llm, path="/poem" ) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)代码完整逐行解读
这是一套FastAPI + LangServe搭建的大模型 API 服务程序。 作用:把 LangChain LCEL 链路封装成标准 REST API,前端 / 其它程序可以 HTTP 调用,
同时兼容:
- 通义千问(兼容 OpenAI 接口的远程大模型,qwen-turbo)
- Ollama 本地开源模型(qwen2.5:7b) 对外暴露多条可直接调用的流式 / 非流式对话接口。
一、整体架构概述
plaintext
客户端(前端/Streamlit/脚本) → FastAPI服务 ├─ /openai → 原始ChatOpenAI模型裸接口 ├─ /essay → Prompt模板 + 通义千问,生成短文 └─ /poem → Prompt模板 + Ollama本地模型,生成儿童诗歌add_routes()是 LangServe 核心能力:自动把 LangChain Runnables 封装成 RESTful API,自带 OpenAPI 文档、流式输出、请求校验。
二、逐段代码详细解析
1. 依赖导入
python
运行
from fastapi import FastAPI # langchain 新版规范:所有核心抽象放入 langchain_core from langchain_core.prompts import ChatPromptTemplate # OpenAI兼容接口封装(阿里云/DeepSeek/通义千问都用这个) from langchain_openai import ChatOpenAI # LangServe:自动将runnable挂载为FastAPI路由 from langserve import add_routes import uvicorn import os # Ollama本地模型集成 from langchain_community.llms import Ollama # .env环境变量读取 from dotenv import load_dotenv # 跨域中间件,解决前端浏览器跨域报错 from fastapi.middleware.cors import CORSMiddleware重点知识点: LangChain v0.1+ 规范拆分包:
langchain_core:基础组件(Prompt、Runnable)langchain_openai:官方维护 OpenAI 封装langchain_community:社区第三方集成(Ollama、各类小众工具)
2. 加载环境变量
python
运行
load_dotenv() os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")load_dotenv()读取项目根目录.env文件- 需要在.env 中配置两条关键变量:
env
OPENAI_API_KEY=sk-xxxx OPENAI_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1因为调用阿里云通义千问兼容 OpenAI 协议,必须配置
base_url。
3. 创建 FastAPI 实例
python
运行
app = FastAPI( title="Langchain Server", version="1.0", description="A simple API Server" )FastAPI Web 服务主对象,自动生成接口文档:
- 文档地址:
http://127.0.0.1:8000/docs - 替代文档:
http://127.0.0.1:8000/redoc
4. CORS 跨域中间件
python
运行
app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )作用:浏览器前端(Streamlit/Vue/React)访问后端接口不会报跨域错误。
⚠️生产环境不要写
["*"],需要指定固定域名提升安全。
5. 路由 1:裸模型接口/openai
python
运行
add_routes( app, ChatOpenAI( model="qwen-turbo", base_url=os.getenv("OPENAI_API_BASE") ), path="/openai" )- 直接挂载原始大模型 Runnable
- 客户端可以自由传入系统提示词、用户消息,无固定 Prompt 模板
- 请求格式遵循 LangServe 标准消息格式
6. 初始化两个模型实例
python
运行
openai_model = ChatOpenAI( model="qwen-turbo", base_url=os.getenv("OPENAI_API_BASE") ) # 本地Ollama模型,需要提前在本地执行 ollama pull qwen2.5:7b ollama_llm = Ollama(model="qwen2.5:7b")openai_model:远程通义千问 qwen-turbo(云端)ollama_llm:本地运行 qwen2.5:7b,不需要 API Key,依赖 Ollama 服务启动(默认localhost:11434)
7. 定义 Prompt 模板
python
运行
prompt_essay = ChatPromptTemplate.from_template("Write me an essay about {topic} with 100 words") prompt_poem = ChatPromptTemplate.from_template("Write me an poem about {topic} for a 5 years child with 100 words"){topic}是变量占位符,调用接口时传入 topic 参数动态填充。ChatPromptTemplate.from_template构建可链式调用的 Prompt Runnable。
8. LangChain 管道链式语法|
LangChain 重载|运算符,等价于RunnableSequence
python
运行
prompt_essay | openai_model执行流程:输入参数 → 填充Prompt模板 → 传给LLM → 返回模型输出
挂载成接口:
python
运行
add_routes( app, prompt_essay | openai_model, path="/essay" ) add_routes( app, prompt_poem | ollama_llm, path="/poem" )/essay:云端 qwen-turbo 写短文,入参只有topic/poem:本地 Ollama qwen2.5:7b 写儿童诗歌
9. 服务启动入口
python
运行
if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)host="0.0.0.0":允许局域网其他设备访问(如果写 127.0.0.1 只能本机调用)- 端口 8000
三、如何调用接口示例
启动服务后访问http://localhost:8000/docs可以在线调试
调用 /essay
POSThttp://localhost:8000/essay/invoke
json
{ "input": {"topic": "summer"} }调用 /poem
POSThttp://localhost:8000/poem/invoke
json
{ "input": {"topic": "cat"} }同时支持流式接口:/essay/stream、/poem/stream实现打字机流式输出。
四、代码存在的问题 & 优化建议
1. 重复实例化 ChatOpenAI
python
运行
# 一处add_routes内部新建 add_routes(app, ChatOpenAI(...), path="/openai") # 另一处又新建 openai_model = ChatOpenAI(...)优化:复用同一个实例,节省资源
python
运行
openai_model = ChatOpenAI( model="qwen-turbo", base_url=os.getenv("OPENAI_API_BASE") ) add_routes(app, openai_model, path="/openai")2. Ollama 默认地址硬编码风险
Ollama 默认http://localhost:11434,如需局域网访问需要显式指定:
python
运行
ollama_llm = Ollama( model="qwen2.5:7b", base_url="http://0.0.0.0:11434" )3. 缺少异常捕获、日志、超时配置
生产环境建议增加:
- LLM 调用 timeout 超时
- 请求日志
- 全局异常处理器
4. CORSallow_origins=["*"]不安全
正式部署改成指定域名:
python
运行
allow_origins=["http://localhost:8501"] # streamlit地址5. Prompt 中英文混杂
如果你面向中文使用,建议把 prompt 改成中文,模型输出效果更好。
6. 没有限制最大并发、缺少鉴权
当前所有接口公开访问,公网部署务必增加 API 密钥鉴权中间件。
五、配套 .env 文件示例
新建.env和代码放在同一目录
env
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxx OPENAI_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1六、运行前置条件
- 安装依赖
bash
运行
pip install fastapi uvicorn langchain langchain-core langchain-openai langchain-community langserve python-dotenv ollama- 本地安装 Ollama,执行
ollama pull qwen2.5:7b - 配置.env 里阿里云通义千问 key
- 启动:
python main.py
