FastAPI 项目实战:LLM 流式对话接口优化与简历投递功能实现
2026/8/6 5:01:55 网站建设 项目流程

1. 项目背景与需求分析

在当前的 AI 应用开发中,大语言模型(LLM)的集成已成为标配功能。本文基于一个真实的 FastAPI 项目,分享两个核心功能的实现与优化:

  1. LLM 流式对话接口优化:从单轮对话升级为多轮对话,并改进错误处理机制
  2. 简历投递详情接口:为求职者提供详细的投递记录查询功能

2. 代码变更概览

2.1 文件结构变更

+37 -28 app/apis/llm/case1_api.py # LLM 流式对话接口优化 +1 -1 app/apis/llm/case2_api.py # API 端点基础 URL 更新 +16 -3 app/schemas/llm_case1.py # 新增多轮对话数据结构

2.2 核心优化点

  1. LLM 接口升级:单轮对话 → 多轮对话
  2. 错误处理优化:避免 SSE 流异常导致前端无响应
  3. API 端点统一:标准化阿里云 DashScope API 调用
  4. 新增简历投递详情接口:完善求职功能

3. LLM 流式对话接口优化

3.1 原单轮对话接口

@llm_day01_router.post("/case1",summary="LLM-DAY01-CASE1")asyncdefcase1_api(llmCase1Request:LLMCase1):client=OpenAI(api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://ws-d765zw587c5lpqzq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",)prompt=f""" #角色设定:{llmCase1Request.role}#用户问题:{llmCase1Request.question}"""completion=client.chat.completions.create(model="qwen-plus",messages=[{"role":"system","content":"你是一个智能助手"},{"role":"user","content":prompt},],stream=True,stream_options={"include_usage":True})return{"code":1,"message":"success","data":completion}

3.2 优化后的多轮对话接口

@llm_day01_router.post("/case2",summary="多轮对话流式输出")asyncdefcase2_api(req:LLMMultiChat):msgs=[{"role":m.role,"content":m.content}forminreq.messages]returnStreamingResponse(content=stream_chunk(msgs),media_type="text/event-stream")

3.3 改进的流式生成器

defstream_chunk(messages:list):"""多轮流式生成器:接收完整对话历史(system + 历史轮次 + 当前问题),逐块 yield SSE data 异常处理:OpenAI SDK 抛出的异常(如 AuthenticationError、RateLimitError) 不会再导致 StreamingResponse 返回 500 + 前端 SSE 响应体为空。 改为把错误信息作为特殊 SSE 块 yield 给前端,前端会展示明确错误。 """client=OpenAI(api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",)try:completion=client.chat.completions.create(model="qwen-plus",messages=messages,stream=True,stream_options={"include_usage":True})forchunkincompletion:ifchunk.choices:choice=chunk.choices[0]ifchoice.delta:delta=choice.deltaifdelta.content:yieldf"data:{delta.content}\n\n"yield"data: [done]\n\n"exceptExceptionase:# 把异常信息透传给前端,避免 SSE 流截断导致前端看不到具体原因err_type=type(e).__name__ err_msg=str(e).replace("\n"," ").strip()[:500]yieldf"data: [ERROR]{err_type}:{err_msg}\n\n"yield"data: [done]\n\n"

3.4 关键优化点解析

3.4.1 多轮对话支持
  • 原接口:仅支持单轮问答,每次请求都是独立的对话
  • 新接口:支持完整的对话历史,可以维护上下文连贯性
  • 实现方式:通过LLMMultiChat数据结构传递完整的消息列表
3.4.2 异常处理优化
  • 问题:原实现中,OpenAI SDK 异常会导致 StreamingResponse 返回 500 状态码,前端 SSE 连接中断
  • 解决方案:使用 try-except 包裹流式生成逻辑,将异常信息通过 SSE 通道透传给前端
  • 优势:前端可以正常接收错误信息并展示给用户,而不是连接突然中断
3.4.3 API 端点标准化
# 优化前base_url="https://ws-d765zw587c5lpqzq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"# 优化后base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
  • 统一使用阿里云 DashScope 的标准兼容模式端点
  • 提高代码的可维护性和可移植性

4. 数据结构定义优化

4.1 新增多轮对话数据结构

fromtypingimportListfrompydanticimportBaseModel,FieldclassLLMCase1(BaseModel):question:str=Field(...,title="问题",description="问题")classLLMCase2(BaseModel):user_id:int=Field(...,title="用户ID",description="用户ID")session_id:str=Field(...,title="会话ID",description="会话ID")message:str=Field(...,title="用户消息",description="用户消息")# 新增:多轮对话数据结构classLLMMultiChat(BaseModel):messages:List[dict]=Field(...,title="对话消息列表",description="包含角色和内容的完整对话历史")

4.2 数据结构设计思路

  1. LLMCase1:保持向后兼容,用于简单的单轮问答场景
  2. LLMCase2:支持用户会话管理,适合需要维护对话状态的场景
  3. LLMMultiChat:全新的多轮对话支持,可以传递完整的对话上下文

5. 简历投递详情接口实现

5.1 新增接口代码

@job_router.get("/resume_submission_detail/{id}",summary="简历投递详情")asyncdefresume_submission_detail(id:int):res=awaitJobService.resume_submission_detail(id)return{"code":1,"message":"ok","data":json.loads(res)}

5.2 接口设计要点

  1. RESTful 设计:使用GET /resume_submission_detail/{id}路径
  2. 参数验证:通过路径参数id接收投递记录 ID
  3. 服务层调用:委托给JobService.resume_submission_detail处理业务逻辑
  4. 数据格式化:使用json.loads()确保返回标准化的 JSON 数据

5.3 与原接口的对比

# 原接口:查看我的投递记录列表@job_router.get("/get_my_submissions",summary="查看我的投递记录")asyncdefget_my_submissions():"""求职者查看自己的投递记录,需候选人Token鉴权"""res=awaitJobService.getMySubmissions(job_seeker_id,page,page_size)return{"code":1,"message":"查询成功","data":res}# 新接口:查看单条投递记录详情@job_router.get("/resume_submission_detail/{id}",summary="简历投递详情")asyncdefresume_submission_detail(id:int):res=awaitJobService.resume_submission_detail(id)return{"code":1,"message":"ok","data":json.loads(res)}

6. 技术实现细节

6.1 SSE(Server-Sent Events)流式传输

# 核心实现defstream_chunk(messages:list):# ... 流式生成逻辑 ...forchunkincompletion:ifchunk.choices:choice=chunk.choices[0]ifchoice.delta:delta=choice.deltaifdelta.content:yieldf"data:{delta.content}\n\n"# SSE 格式yield"data: [done]\n\n"# 结束标记

SSE 格式要求

  • 每行以data:开头
  • 每段数据以两个换行符\n\n结束
  • 特殊标记[done]表示流结束
  • 错误信息格式:data: [ERROR] {错误类型}: {错误信息}

6.2 异常处理机制

try:# 正常的流式生成逻辑completion=client.chat.completions.create(...)# ... 处理正常流 ...exceptExceptionase:# 异常处理:将错误信息通过 SSE 通道返回err_type=type(e).__name__ err_msg=str(e).replace("\n"," ").strip()[:500]# 限制长度,避免过大yieldf"data: [ERROR]{err_type}:{err_msg}\n\n"yield"data: [done]\n\n"

异常类型处理

  • AuthenticationError:API 密钥错误
  • RateLimitError:请求频率超限
  • APIConnectionError:网络连接问题
  • 其他未知异常

6.3 依赖注入设计

fromfastapiimportDepends,APIRouter,Queryfromapp.core.dependsimportget_job_info,get_job_seeker_info,get_enterprise_info# 依赖注入示例asyncdefget_my_submissions(job_seeker_id:int=Depends(get_job_seeker_info),page:int=Query(1,ge=1),page_size:int=Query(10,ge=1,le=100)):# 业务逻辑pass

7. 前端集成建议

7.1 SSE 客户端实现

// 前端 SSE 客户端示例asyncfunctionstreamLLMResponse(messages){consteventSource=newEventSource(`/api/llm-day01/case2`);eventSource.onmessage=(event)=>{constdata=event.data;if(data==='[done]'){eventSource.close();console.log('流式传输完成');}elseif(data.startsWith('[ERROR]')){eventSource.close();consterrorMsg=data.substring(8);// 移除 "[ERROR] "console.error('流式传输错误:',errorMsg);// 显示错误信息给用户}else{// 正常的数据块,追加到界面appendToChat(data);}};eventSource.onerror=(error)=>{console.error('SSE 连接错误:',error);eventSource.close();};}

7.2 错误处理优化

// 改进的错误处理functionhandleSSEError(errorData){consterrorPrefix='[ERROR] ';if(errorData.startsWith(errorPrefix)){consterrorInfo=errorData.substring(errorPrefix.length);const[errorType,...errorMsgParts]=errorInfo.split(': ');consterrorMessage=errorMsgParts.join(': ');// 根据错误类型提供不同的用户提示switch(errorType){case'AuthenticationError':showToast('API 密钥错误,请检查配置');break;case'RateLimitError':showToast('请求频率超限,请稍后重试');break;default:showToast(`系统错误:${errorMessage}`);}returntrue;// 已处理错误}returnfalse;// 不是错误信息}

8. 部署与配置

8.1 环境变量配置

# .env 文件配置DASHSCOPE_API_KEY=your_dashscope_api_key_hereBASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1MODEL_NAME=qwen-plus

8.2 Docker 部署配置

# Dockerfile 示例 FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

8.3 Nginx 配置(SSE 支持)

# nginx.conf 片段 server { listen 80; server_name your-domain.com; location /api/ { proxy_pass http://backend:8000; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # SSE 相关配置 proxy_buffering off; proxy_cache off; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } }

9. 性能优化建议

9.1 连接池管理

# 使用连接池管理 OpenAI 客户端importhttpxfromopenaiimportOpenAIclassLLMClientPool:def__init__(self):self._clients={}defget_client(self,api_key:str)->OpenAI:ifapi_keynotinself._clients:http_client=httpx.AsyncClient(limits=httpx.Limits(max_connections=100,max_keepalive_connections=20),timeout=httpx.Timeout(30.0))self._clients[api_key]=OpenAI(api_key=api_key,base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",http_client=http_client)returnself._clients[api_key]

9.2 流式响应优化

# 添加响应头优化@llm_day01_router.post("/case2",summary="多轮对话流式输出")asyncdefcase2_api(req:LLMMultiChat):msgs=[{"role":m.role,"content":m.content}forminreq.messages]returnStreamingResponse(content=stream_chunk(msgs),media_type="text/event-stream",headers={"Cache-Control":"no-cache","X-Accel-Buffering":"no",# 禁用 Nginx 缓冲"Connection":"keep-alive"})

10. 总结与展望

10.1 本次优化的核心价值

  1. 用户体验提升:多轮对话支持让 AI 交互更加自然连贯
  2. 错误处理完善:SSE 流的异常处理机制提高了系统稳定性
  3. 代码可维护性:统一 API 端点和标准化的数据结构设计
  4. 功能完整性:简历投递详情接口完善了求职功能模块

10.2 未来优化方向

  1. 对话状态管理:引入 Redis 缓存对话历史,支持长期会话
  2. 流控与限流:基于用户或 IP 的请求频率限制
  3. 监控与日志:详细的性能监控和错误日志记录
  4. 多模型支持:扩展支持其他 LLM 提供商(OpenAI、Claude 等)

10.3 最佳实践建议

  1. 始终使用 try-except包裹外部 API 调用
  2. 为 SSE 流设置合理的超时时间
  3. 在前端实现优雅的重连机制
  4. 定期更新 API 客户端库以获取最新的功能和安全修复

通过本次代码优化,我们不仅提升了系统的稳定性和用户体验,还为未来的功能扩展奠定了良好的架构基础。这种渐进式的优化方式值得在大型项目中推广。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询