课程目标
- 学会用 FastAPI 把 LangChain 能力封装成 HTTP 接口
- 掌握接口基础写法、请求 / 响应格式
- 了解前端调用接口的基本方式,实现前后端联调
- 知晓简易部署与跨域基础配置
一、前置准备
1. 安装依赖
bash
运行
pip install langchain langchain-openai fastapi uvicorn python-multipart
fastapi:高性能接口框架,语法简洁、自动生成接口文档uvicorn:ASGI 服务运行器,用来启动接口服务
2. 基础说明
我们前面写的 LangChain 代码,默认只能本地运行; 封装成接口后,前端、其他服务都能通过网络请求调用 AI 能力,是项目落地的必经步骤。
二、实战 1:基础问答接口(最简示例)
完整后端代码
python
运行
# main.py
from fastapi import FastAPI
from langchain_openai import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
import os
# 配置密钥
os.environ["OPENAI_API_KEY"] = "你的API_KEY"
# 1. 初始化FastAPI应用
app = FastAPI(title="LangChain 接口服务")
# 2. 初始化LLM与链(复用之前的LangChain逻辑)
llm = OpenAI(temperature=0)
prompt = PromptTemplate(input_variables=["question"], template="请认真回答问题:{question}")
chain = LLMChain(llm=llm, prompt=prompt)
# 3. 定义接口路由:GET 请求
@app.get("/chat")
def chat(question: str):
"""问答接口:传入问题,返回AI回答"""
answer = chain.run(question)
return {
"code": 200,
"msg": "请求成功",
"data": {
"question": question,
"answer": answer
}
}
启动服务
在终端执行命令:
bash
运行
uvicorn main:app --reload
main:对应代码文件名main.pyapp:代码里初始化的 FastAPI 实例--reload:热更新,修改代码无需重启服务(开发专用)
访问 & 测试
服务默认地址:http://127.0.0.1:8000
- 自动接口文档:
http://127.0.0.1:8000/docs,可视化测试接口 - 直接浏览器访问示例:
http://127.0.0.1:8000/chat?question=解释一下什么是LangChain
三、实战 2:POST 接口(推荐业务用法)
GET 接口会把参数暴露在地址栏,复杂场景 / 传长文本优先用 POST,格式更规范。
python
运行
# main.py 续写/替换
from pydantic import BaseModel
# 定义请求体数据模型(规范入参)
class ChatRequest(BaseModel):
question: str # 前端需要传递的字段
# POST 接口
@app.post("/api/chat")
def api_chat(req: ChatRequest):
answer = chain.run(req.question)
return {
"code": 200,
"question": req.question,
"answer": answer
}
- 依然通过
http://127.0.0.1:8000/docs进入文档测试,选择POST接口填写参数调用。
四、关键问题:跨域(前端必遇)
前端页面(Vue/HTML)直接调用本地接口,会触发跨域请求异常,需要配置跨域中间件。
开启跨域支持(必加代码)
python
运行
from fastapi.middleware.cors import CORSMiddleware
# 在 app = FastAPI() 之后添加
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有域名访问(开发环境用)
allow_credentials=True,
allow_methods=["*"], # 允许所有请求方法
allow_headers=["*"], # 允许所有请求头
)
生产环境不要写
["*"],改为指定前端域名,提升安全性。
五、前端调用示例(原生 HTML,零基础看懂)
写一个简单页面,模拟前端请求后端接口,完成联调:
html
预览
<!DOCTYPE html>
<html>
<body>
<input type="text" id="inputText" placeholder="输入问题">
<button onclick="sendReq()">提问</button>
<div id="result"></div>
<script>
async function sendReq(){
const question = document.getElementById("inputText").value;
// 调用后端POST接口
const res = await fetch("http://127.0.0.1:8000/api/chat",{
method: "POST",
headers:{"Content-Type":"application/json"},
body: JSON.stringify({question: question})
})
const data = await res.json();
document.getElementById("result").innerText = data.answer;
}
</script>
</body>
</html>
运行逻辑:
- 保持后端接口服务启动
- 直接打开 HTML 文件
- 输入内容点击按钮,即可拿到 AI 返回结果
六、拓展:Agent 接口封装(结合上节课内容)
把 Agent 能力也封装成接口,完整串联前后知识点:
python
运行
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import Calculator, DuckDuckGoSearchRun
# 初始化工具、Agent
tools = [Calculator(), DuckDuckGoSearchRun()]
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)
# Agent 专属接口
@app.post("/api/agent")
def agent_chat(req: ChatRequest):
res = agent_executor.invoke({"input": req.question})
return {"answer": res["output"]}
七、核心知识点总结(考点 / 面试重点)
- 框架选择:本节课使用 FastAPI 封装接口,轻量易用,适合 AI 服务开发
- 请求方式
- GET:参数拼在 URL,适合简单查询
- POST:参数放请求体,适合长文本、复杂数据,业务首选
- 跨域 :前后端分离项目必须配置
CORSMiddleware,否则前端无法调用 - 流程链路 前端页面 → HTTP 请求 → FastAPI 接口 → LangChain 逻辑 → 返回结果给前端
八、课后作业
作业 3:简答题答案
问题:为什么前后端联调时会出现跨域问题?如何解决?
- 基于本节课代码,封装一个 RAG 问答接口(复用 Day3 RAG 代码)。
- 给接口配置跨域,用原生 HTML 页面调用接口,验证联调成功。
- 简述:为什么前后端联调时会出现跨域问题?如何解决?
作业 1:封装 RAG 问答接口(带跨域)
python
运行
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from langchain_openai import OpenAI, OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
import os
# 配置密钥
os.environ["OPENAI_API_KEY"] = "你的API_KEY"
# 1. 初始化 FastAPI
app = FastAPI()
# 2. 配置跨域(前后端联调必备)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 3. 构造简易向量库+RAG链路(复用RAG核心逻辑)
embeddings = OpenAIEmbeddings()
# 模拟文档数据
texts = ["LangChain 是一款用于构建大模型应用的开发框架",
"RAG 检索增强生成,通过检索外部文档提升问答准确性"]
db = FAISS.from_texts(texts, embeddings)
retriever = db.as_retriever()
llm = OpenAI(temperature=0)
rag_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever
)
# 4. 定义请求体模型
class ChatReq(BaseModel):
question: str
# 5. RAG 问答接口
@app.post("/api/rag_chat")
def rag_chat(req: ChatReq):
result = rag_chain.run(req.question)
return {
"code": 200,
"question": req.question,
"answer": result
}
启动命令:
bash
运行
uvicorn main:app --reload
作业 2:HTML 前端调用页面
html
预览
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>RAG接口调用</title>
</head>
<body>
<input type="text" id="ques" placeholder="请输入问题" style="width:300px;height:30px;">
<button onclick="sendRequest()" style="height:30px;">提问</button>
<div id="res" style="margin-top: 20px; color: #333;"></div>
<script>
async function sendRequest(){
const question = document.getElementById("ques").value;
const resDom = document.getElementById("res");
resDom.innerText = "请求中...";
try {
const response = await fetch("http://127.0.0.1:8000/api/rag_chat", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({question: question})
})
const data = await response.json();
resDom.innerText = `回答:${data.answer}`;
} catch (e) {
resDom.innerText = "请求失败";
}
}
</script>
</body>
</html>
使用步骤:
5. 保持后端服务正常运行
6. 直接打开该 HTML 文件
7. 输入问题点击按钮,即可获取返回结果
8. 跨域原因 浏览器出于安全同源策略 限制:网页只能请求同协议、同域名、同端口的资源。当前端页面地址 和 后端接口地址 协议 / 域名 / 端口任意一项不同,浏览器就会拦截请求,触发跨域报错。
- 解决办法(本课程方案) 在 FastAPI 后端引入
CORSMiddleware跨域中间件,配置允许访问的源、请求方法、请求头,后端主动声明允许跨域访问,浏览器就会放行请求。