diff --git a/ruoyi-fastapi-backend/.gitignore b/ruoyi-fastapi-backend/.gitignore index 5686ba6..c3cfca7 100644 --- a/ruoyi-fastapi-backend/.gitignore +++ b/ruoyi-fastapi-backend/.gitignore @@ -143,3 +143,10 @@ cython_debug/ # VSCode .vscode/ +*.jpg +*.png +*.jpeg +*.gif +*.ico +*.svg + diff --git a/ruoyi-fastapi-backend/module_admin/controller/ragflow_controller.py b/ruoyi-fastapi-backend/module_admin/controller/ragflow_controller.py index 3de9439..01852b1 100644 --- a/ruoyi-fastapi-backend/module_admin/controller/ragflow_controller.py +++ b/ruoyi-fastapi-backend/module_admin/controller/ragflow_controller.py @@ -1,6 +1,6 @@ # from datetime import datetime from typing import List -from fastapi import APIRouter, Depends, Request, UploadFile, File, Form +from fastapi import APIRouter, Depends, Request, UploadFile, File, Form, StreamingResponse # from pydantic_validation_decorator import ValidateFields # from sqlalchemy.ext.asyncio import AsyncSession # from config.enums import BusinessType @@ -203,9 +203,21 @@ async def converse_with_chat_assistant( """ 与聊天助手进行对话 """ - result = await RAGFlowService.converse_with_chat_assistant_services(converse_params) - return parse_result(result) + + # 如果是流式响应,返回 StreamingResponse, result sse格式 + if converse_params.stream: + return StreamingResponse( + result, + media_type="text/event-stream", + headers={ + "Cache-Control": "no-cache", + "Connection": "keep-alive", + } + ) + else: + return parse_result(result) + diff --git a/ruoyi-fastapi-backend/module_admin/service/ragflow_service.py b/ruoyi-fastapi-backend/module_admin/service/ragflow_service.py index b687b13..6b1415a 100644 --- a/ruoyi-fastapi-backend/module_admin/service/ragflow_service.py +++ b/ruoyi-fastapi-backend/module_admin/service/ragflow_service.py @@ -4,8 +4,10 @@ from module_admin.entity.vo.ragflow_vo import RagflowListQueryModel, ListDocumen ,CreateSessionWithChatModel, ConverseWithChatAssistantModel from config.env import RAGFlowConfig from typing import List + import asyncio import string +import json import re class RAGFlowService: @@ -180,20 +182,29 @@ class RAGFlowService: @classmethod async def converse_with_chat_assistant_services(cls, converse_params: ConverseWithChatAssistantModel): if converse_params.stream: - async with AsyncRAGFlowClient(RAGFlowConfig.RAGFLOW_BASE_URL, RAGFlowConfig.RAGFLOW_API_KEY) as client: - result = await client.converse_with_chat_assistant(**(converse_params.model_dump())) - - i = 0 - async for t in result: - try: - answer = t["data"].get("answer", "") - answer = cls.clean_text(answer) - print(repr(answer[i:])) - i = len(answer) - except Exception as e: - print(e) - print(t) - await asyncio.sleep(0.2) + async def generate(): + async with AsyncRAGFlowClient(RAGFlowConfig.RAGFLOW_BASE_URL, RAGFlowConfig.RAGFLOW_API_KEY) as client: + result = await client.converse_with_chat_assistant(**(converse_params.model_dump())) + + i = 0 + async for t in result: + try: + answer = t["data"].get("answer", "") + answer = cls.clean_text(answer) + # 只发送新增的内容 + new_content = answer[i:] + if new_content: + # 以 SSE 格式发送 + yield f"data: {json.dumps({'content': new_content}, ensure_ascii=False)}\n\n" + i = len(answer) + except Exception as e: + yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n" + await asyncio.sleep(0.2) + + # 发送结束标记 + yield "data: [DONE]\n\n" + + return generate() else: async with AsyncRAGFlowClient(RAGFlowConfig.RAGFLOW_BASE_URL, RAGFlowConfig.RAGFLOW_API_KEY) as client: result = await client.converse_with_chat_assistant(**(converse_params.model_dump())) diff --git a/ruoyi-fastapi-backend/requirements.txt b/ruoyi-fastapi-backend/requirements.txt index 45ff472..216b184 100644 --- a/ruoyi-fastapi-backend/requirements.txt +++ b/ruoyi-fastapi-backend/requirements.txt @@ -1,18 +1,25 @@ +aiohttp==3.12.15 APScheduler==3.11.0 -asyncmy==0.2.10 -DateTime==5.5 -fastapi[all]==0.115.8 +compreface_sdk==0.6.0 +fastapi==0.119.0 +httpx==0.28.1 +Jinja2==3.1.6 loguru==0.7.3 openpyxl==3.1.5 -pandas==2.2.3 -passlib[bcrypt]==1.7.4 -Pillow==11.1.0 +pandas==2.3.3 +passlib==1.7.4 +Pillow==11.3.0 psutil==7.0.0 -pydantic-validation-decorator==0.1.4 -PyJWT[crypto]==2.10.1 -PyMySQL==1.1.1 +pydantic==2.12.0 +pydantic_settings==2.11.0 +pydantic_validation_decorator==0.1.4 +PyJWT==2.10.1 +python-dotenv==1.1.1 +python_dateutil==2.9.0.post0 redis==5.2.1 -requests==2.32.3 -SQLAlchemy[asyncio]==2.0.38 -sqlglot[rs]==26.6.0 -user-agents==2.2.0 +Requests==2.32.5 +SQLAlchemy==2.0.38 +sqlglot==26.6.0 +starlette==0.48.0 +user_agents==2.2.0 +uvicorn==0.37.0