操作系统内存管理习题精解:从分页置换到实战内核源码分析
2026/8/6 5:54:57
在当前的 AI 应用开发中,大语言模型(LLM)的集成已成为标配功能。本文基于一个真实的 FastAPI 项目,分享两个核心功能的实现与优化:
+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 # 新增多轮对话数据结构@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}@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")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"LLMMultiChat数据结构传递完整的消息列表# 优化前base_url="https://ws-d765zw587c5lpqzq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"# 优化后base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"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="包含角色和内容的完整对话历史")@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)}GET /resume_submission_detail/{id}路径id接收投递记录 IDJobService.resume_submission_detail处理业务逻辑json.loads()确保返回标准化的 JSON 数据# 原接口:查看我的投递记录列表@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)}# 核心实现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] {错误类型}: {错误信息}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:网络连接问题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// 前端 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();};}// 改进的错误处理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;// 不是错误信息}# .env 文件配置DASHSCOPE_API_KEY=your_dashscope_api_key_hereBASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1MODEL_NAME=qwen-plus# 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"]# 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; } }# 使用连接池管理 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]# 添加响应头优化@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"})通过本次代码优化,我们不仅提升了系统的稳定性和用户体验,还为未来的功能扩展奠定了良好的架构基础。这种渐进式的优化方式值得在大型项目中推广。