main
HuangHai 4 weeks ago
parent af847170b9
commit 4258f94fef

@ -1,4 +1,3 @@
import asyncio
import json
import logging
import os
@ -15,10 +14,10 @@ import uvicorn
from fastapi import FastAPI, HTTPException
from openai import AsyncOpenAI
from sse_starlette import EventSourceResponse
from starlette.responses import StreamingResponse
from starlette.staticfiles import StaticFiles
from Config import Config
from Util.ALiYunUtil import ALiYunUtil
from Util.SearchUtil import *
# 初始化日志
@ -45,9 +44,6 @@ logger.addHandler(console_handler)
async def lifespan(app: FastAPI):
# 初始化阿里云大模型工具
app.state.aliyun_util = ALiYunUtil()
# 抑制HTTPS相关警告
warnings.filterwarnings('ignore', message='Connecting to .* using TLS with verify_certs=False is insecure')
warnings.filterwarnings('ignore', message='Unverified HTTPS request is being made to host')
@ -115,29 +111,8 @@ async def rag(request: fastapi.Request):
data = await request.json()
query = data.get('query', '')
query_tags = data.get('tags', [])
# 调用es进行混合搜索
search_results = queryByEs(query, query_tags, logger)
# 调用大模型
markdown_content = callLLM(request, query, search_results, logger, False)
# 如果有正确的结果
if markdown_content:
return {"data": markdown_content, "format": "markdown"}
return {"data": "没有在知识库中找到相关的信息,无法回答此问题。"}
@app.post("/api/rag_stream", response_model=None)
async def rag_stream(request: fastapi.Request):
data = await request.json()
query = data.get('query', '')
query_tags = data.get('tags', [])
# 调用es进行混合搜索
search_results = queryByEs(query, query_tags, logger)
# 构建提示词
context = "\n".join([
f"结果{i + 1}: {res['tags']['full_content']}"
@ -172,7 +147,6 @@ async def rag_stream(request: fastapi.Request):
api_key=Config.MODEL_API_KEY,
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
async def generate_response_stream():
try:
# 流式调用大模型
@ -184,41 +158,6 @@ async def rag_stream(request: fastapi.Request):
max_tokens=8000,
stream=True # 启用流式模式
)
# 流式返回模型生成的回复
async for chunk in stream:
if chunk.choices[0].delta.content:
yield f"data: {json.dumps({'reply': chunk.choices[0].delta.content}, ensure_ascii=False)}\n\n"
except Exception as e:
yield f"data: {json.dumps({'error': str(e)})}\n\n"
return EventSourceResponse(generate_response_stream())
# 与用户交流聊天
@app.post("/api/helloWorld")
async def reply():
# 初始化异步 OpenAI 客户端
client = AsyncOpenAI(
api_key=Config.MODEL_API_KEY,
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
async def generate_response_stream():
try:
# 流式调用大模型
stream = await client.chat.completions.create(
model=Config.MODEL_NAME,
messages=[
{"role": "system",
"content": "你是聊天人的好朋友,你认识深刻,知识渊博,不要使用哎呀这样的语气词。聊天的回复内容不要超过150字。"},
{"role": "user", "content": "你是谁?"}
],
max_tokens=4000,
stream=True # 启用流式模式
)
# 流式返回模型生成的回复
async for chunk in stream:
if chunk.choices[0].delta.content:

@ -1,10 +0,0 @@
from Util.ALiYunUtil import ALiYunUtil
if __name__ == '__main__':
ali_util = ALiYunUtil()
while True:
prompt = input("请输入问题(输入q退出): ")
if prompt.lower() == 'q':
break
answer = ali_util.chat(prompt)
print("回答:", answer)

@ -1,49 +0,0 @@
from openai import OpenAI
from Config.Config import MODEL_API_KEY, MODEL_NAME
class ALiYunUtil:
def __init__(self):
self.client = OpenAI(
api_key=MODEL_API_KEY,
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
self.model_name = MODEL_NAME
def chat(self, prompt, model=None):
"""
与阿里云大模型对话
:param prompt: 用户输入的问题
:param model: 可选指定使用的模型默认使用Config中的MODEL_NAME
:return: 模型返回的答案
"""
try:
completion = self.client.chat.completions.create(
model=model or self.model_name,
messages=[
{'role': 'user', 'content': prompt}
]
)
return completion.choices[0].message.content
except Exception as e:
return f"发生错误: {str(e)}"
def chat_stream(self, prompt, model=None):
"""
与阿里云大模型流式对话
:param prompt: 用户输入的问题
:param model: 可选指定使用的模型
:return: 异步生成器返回模型流式响应
"""
try:
stream = self.client.chat.completions.create(
model=model or self.model_name,
messages=[
{'role': 'user', 'content': prompt}
],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
yield chunk.choices[0].delta.content
except Exception as e:
yield f"发生错误: {str(e)}"

@ -1,5 +1,3 @@
from starlette.responses import StreamingResponse
from Config.Config import ES_CONFIG
from Util.EsSearchUtil import EsSearchUtil
@ -124,57 +122,3 @@ def queryByEs(query, query_tags,logger):
finally:
es_search_util.es_pool.release_connection(es_conn)
def callLLM(request, query, search_results, logger,streamBack=False):
# 调用阿里云大模型整合结果
aliyun_util = request.app.state.aliyun_util
# 构建提示词
context = "\n".join([
f"结果{i + 1}: {res['tags']['full_content']}"
for i, res in enumerate(search_results['vector_results'] + search_results['text_results'])
])
# 添加图片识别提示
prompt = f"""
信息检索与回答助手
根据以下关于'{query}'的相关信息
基本信息
- 语言: 中文
- 描述: 根据提供的材料检索信息并回答问题
- 特点: 快速准确提取关键信息清晰简洁地回答
相关信息
{context}
回答要求
1. 严格保持原文中图片与上下文的顺序关系确保语义相关性
2. 图片引用使用Markdown格式: ![图片描述](图片路径)
3. 使用Markdown格式返回包含适当的标题列表和代码块
4. 对于提供Latex公式的内容尽量保留Latex公式
5. 直接返回Markdown内容不要包含额外解释或说明
6. 依托给定的资料快速准确地回答问题可以添加一些额外的信息但请勿重复内容
7. 如果未提供相关信息请不要回答
8. 如果发现相关信息与原来的问题契合度低也不要回答
9. 确保内容结构清晰便于前端展示
"""
# 调用阿里云大模型
if len(context) > 0:
# 调用大模型生成回答
logger.info("正在调用阿里云大模型生成回答...")
if streamBack:
# SSE流式返回
async def generate():
async for chunk in aliyun_util.chat_stream(prompt):
yield f"data: {chunk}\n\n"
# data: 发生错误: object Stream can't be used in 'await' expression
return StreamingResponse(generate(), media_type="text/event-stream")
else:
# 一次性返回
markdown_content = aliyun_util.chat(prompt)
logger.info(f"调用阿里云大模型生成回答成功完成!")
return markdown_content
return None

Loading…
Cancel
Save