|
|
|
@ -1,9 +1,4 @@
|
|
|
|
|
import asyncio
|
|
|
|
|
import json
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
import os.path
|
|
|
|
|
>>>>>>> 66c0614648a1e8f5f7b9274bdb7218f082104b24
|
|
|
|
|
import subprocess
|
|
|
|
|
import tempfile
|
|
|
|
|
import urllib
|
|
|
|
@ -21,7 +16,6 @@ from starlette.staticfiles import StaticFiles
|
|
|
|
|
from Util.LightRagUtil import *
|
|
|
|
|
from Util.PostgreSQLUtil import init_postgres_pool
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
# 在程序开始时添加以下配置
|
|
|
|
|
logging.basicConfig(
|
|
|
|
|
level=logging.INFO, # 设置日志级别为INFO
|
|
|
|
@ -29,14 +23,8 @@ logging.basicConfig(
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 或者如果你想更详细地控制日志输出
|
|
|
|
|
=======
|
|
|
|
|
rag_instances = {}
|
|
|
|
|
rag_lock = asyncio.Lock()
|
|
|
|
|
|
|
|
|
|
# 想更详细地控制日志输出
|
|
|
|
|
>>>>>>> 66c0614648a1e8f5f7b9274bdb7218f082104b24
|
|
|
|
|
logger = logging.getLogger('lightrag')
|
|
|
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
|
handler = logging.StreamHandler()
|
|
|
|
|
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
|
|
|
|
logger.addHandler(handler)
|
|
|
|
@ -44,9 +32,6 @@ logger.addHandler(handler)
|
|
|
|
|
|
|
|
|
|
async def lifespan(app: FastAPI):
|
|
|
|
|
yield
|
|
|
|
|
# 在应用关闭时清理rag实例
|
|
|
|
|
for rag in rag_instances.values():
|
|
|
|
|
await rag.finalize_storages()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def print_stream(stream):
|
|
|
|
@ -70,7 +55,6 @@ async def rag(request: fastapi.Request):
|
|
|
|
|
WORKING_PATH = "./Topic/" + topic
|
|
|
|
|
# 查询的问题
|
|
|
|
|
query = data.get("query")
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
# 关闭参考资料
|
|
|
|
|
user_prompt = "\n 1、不要输出参考资料 或者 References !"
|
|
|
|
|
user_prompt = user_prompt + "\n 2、资料中提供化学反应方程式的,一定要严格按提供的Latex公式输出,绝对不允许对Latex公式进行修改 !"
|
|
|
|
@ -89,71 +73,10 @@ async def rag(request: fastapi.Request):
|
|
|
|
|
|
|
|
|
|
await rag.initialize_storages()
|
|
|
|
|
await initialize_pipeline_status()
|
|
|
|
|
=======
|
|
|
|
|
# 用户提示词
|
|
|
|
|
output_model = data.get("output_model", "txt")
|
|
|
|
|
|
|
|
|
|
if output_model == "txt":
|
|
|
|
|
user_prompt = "1、如果资料中提供了图片的,一定要严格按照原文提供图片输出,绝对不能省略或不输出!"
|
|
|
|
|
user_prompt = user_prompt + "\n 2、不要提供引用信息!"
|
|
|
|
|
user_prompt = user_prompt + "\n 3、依据提供的材料,判断是否与问题强相关,强相关的可以适当发挥!"
|
|
|
|
|
#user_prompt = user_prompt + "\n 3、提供给你的材料中,与问题完全相关的需要完整保留!"
|
|
|
|
|
#user_prompt = user_prompt + "\n 4、提供给你的材料中,与问题不完全相关的一定不要输出!"
|
|
|
|
|
user_prompt = user_prompt + "\n 5、资料中提供化学反应方程式的,一定要严格按提供的Latex公式输出,绝对不允许对Latex公式进行修改 !"
|
|
|
|
|
user_prompt = user_prompt + "\n 6、发现输出内容中包含Latex公式的,一定要检查是不是包含了$$或$的包含符号,不能让Latex无包含符号出现!"
|
|
|
|
|
elif output_model == 'html':
|
|
|
|
|
user_prompt = """
|
|
|
|
|
我需要一个专业的交互式数据可视化,数据资料我将提供,你也可以根据自己了解的信息进行补充,
|
|
|
|
|
注意:
|
|
|
|
|
(1)直接输出html代码,以```html 开头, ``` 结尾。
|
|
|
|
|
(2)不要与用户进行二次交互,直接生成即可。
|
|
|
|
|
(3)不要添加参考信息等内容
|
|
|
|
|
(4)请确保生成的JSON数据格式完全正确,特别注意字符串内部的引号必须使用反斜杠转义。
|
|
|
|
|
例如:"desc": "猛将,有\"人中吕布,马中赤兔\"之称"
|
|
|
|
|
(5)正面负面信息都要。
|
|
|
|
|
绘制可视化具体要求如下:
|
|
|
|
|
1. **技术要求**:
|
|
|
|
|
- 使用 D3.js v7 + SVG
|
|
|
|
|
- 实现可拖动节点和关系线分类着色
|
|
|
|
|
- 必须包含右侧信息面板和3D节点效果
|
|
|
|
|
|
|
|
|
|
2. **设计规范**:
|
|
|
|
|
- 主色调:深蓝色渐变背景
|
|
|
|
|
- 标题:在以醒目字体字号在界面顶部中间位置显示,最好有渐变效果
|
|
|
|
|
- 视觉特效:3D立体节点(非平面)+ 发光选中效果
|
|
|
|
|
- 文字要求:使用 dominant-baseline: central 和 text-anchor: middle 确保文字垂直和水平居中
|
|
|
|
|
- 布局响应式:支持窗口缩放
|
|
|
|
|
|
|
|
|
|
3. **数据要求**:
|
|
|
|
|
- 数据结构:网络关系图
|
|
|
|
|
- 关系分类:[至少3种关系类型]
|
|
|
|
|
- 节点属性:[如类型/描述/重要性]
|
|
|
|
|
- 关系线描述:需要有关系线的不同颜色描述的图例
|
|
|
|
|
|
|
|
|
|
4. **交互细节**:
|
|
|
|
|
- 悬停:显示人物简介弹窗
|
|
|
|
|
- 点击:右侧面板更新详细信息+关系列表,仔细检查,确保每个节点都可以点击
|
|
|
|
|
- 布局切换:力导向/辐射状/环形/网格
|
|
|
|
|
|
|
|
|
|
5. **拒绝内容**:
|
|
|
|
|
- 不要树状结构或平面2D节点
|
|
|
|
|
- 避免使用canvas代替SVG
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 使用PG库后,这个是没有用的,但目前的项目代码要求必传,就写一个吧。
|
|
|
|
|
WORKING_DIR = './output/'
|
|
|
|
|
async def generate_response_stream(query: str, workspace: str):
|
|
|
|
|
try:
|
|
|
|
|
logger.info("workspace=" + workspace)
|
|
|
|
|
# 使用锁确保线程安全
|
|
|
|
|
async with rag_lock:
|
|
|
|
|
if workspace not in rag_instances:
|
|
|
|
|
rag_instances[workspace] = await initialize_pg_rag(WORKING_DIR=WORKING_DIR, workspace=workspace)
|
|
|
|
|
rag = rag_instances[workspace]
|
|
|
|
|
>>>>>>> 66c0614648a1e8f5f7b9274bdb7218f082104b24
|
|
|
|
|
resp = await rag.aquery(
|
|
|
|
|
query=query,
|
|
|
|
|
param=QueryParam(mode=mode, stream=True, user_prompt=user_prompt))
|
|
|
|
|
# hybrid naive
|
|
|
|
|
|
|
|
|
|
async for chunk in resp:
|
|
|
|
|
if not chunk:
|
|
|
|
@ -163,15 +86,10 @@ async def rag(request: fastapi.Request):
|
|
|
|
|
except Exception as e:
|
|
|
|
|
yield f"data: {json.dumps({'error': str(e)})}\n\n"
|
|
|
|
|
finally:
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
# 清理资源
|
|
|
|
|
await rag.finalize_storages()
|
|
|
|
|
=======
|
|
|
|
|
# 发送流结束标记
|
|
|
|
|
yield "data: [DONE]\n\n"
|
|
|
|
|
>>>>>>> 66c0614648a1e8f5f7b9274bdb7218f082104b24
|
|
|
|
|
|
|
|
|
|
return EventSourceResponse(generate_response_stream(query=query, workspace=workspace))
|
|
|
|
|
return EventSourceResponse(generate_response_stream(query=query))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/api/save-word")
|
|
|
|
@ -326,5 +244,3 @@ async def update_knowledge(request: fastapi.Request):
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|