我有一个脚本可以为在 Windows 中运行的 GraphRAG 应用程序构建 Chainlit UI。 GraphRAG 查询在终端中运行良好,尽管需要大约 120 秒(附有屏幕截图)。但是,当我运行此 Chainlit 脚本时,subprocess.run 中的 timeout=300 无法按预期工作。相反,我在大约 60 秒后收到“无法到达服务器”错误,尽管最终返回了结果(还附上了终端屏幕截图)。如何强制脚本等待收到响应?
import chainlit as cl
import subprocess
import shlex
@cl.on_chat_start
def start():
cl.user_session.set("history", [])
# cl.set_theme(cl.Theme(background="white"))
# cl.set_header("Duality Expert Chat")
@cl.on_message
async def main(message: cl.Message):
history = cl.user_session.get("history")
query = message.content
cmd = [
"python", "-m", "graphrag.query",
"--root", r"C:\Users\Lei Shang\Documents\Projects\LLM_RAG\GraphRAG_ollama_LMStudio_chainlit\graphRag\mistral-large\graphRag-mistral-large",
"--method", "global",
]
cmd.append(shlex.quote(query))
try:
print(cmd)
result = subprocess.run(cmd, capture_output=True, text=True, check=True, timeout=300)
print(result)
output = result.stdout
# extract content tailing "SUCCESS: Global Search Response:"
response = output.split("SUCCESS: Global Search Response:", 1)[-1].strip()
history.append((query, response))
cl.user_session.set("history", history)
await cl.Message(content=response).send()
except subprocess.CalledProcessError as e:
error_message = f"An error occurred: {e.stderr}"
await cl.Message(content=error_message).send()
if __name__ == "__main__":
cl.run()
遇到的问题似乎与
subprocess
中的超时参数无关,而是与 Chainlit 如何处理长时间运行的请求有关。 默认情况下,Chainlit 可能有一个比 60 秒短的超时时间,即使
subprocess.run
允许该进程运行 300 秒,也会导致“无法到达服务器”错误。
可以尝试以下几种解决方案:
1. 增加 Chainlit 超时:
不幸的是,Chainlit 目前没有提供直接增加超时时间的方法。 可以尝试以下方法:
- 使用自定义服务器: 可以使用像 Flask 或 FastAPI 这样的框架创建自己的 Chainlit 服务器,并在其中设置更长的超时时间。
- 联系 Chainlit 开发人员: 可以联系 Chainlit 开发人员,看看他们是否计划在未来版本中添加对自定义超时的支持。
2. 使用异步执行:
与其使用
subprocess.run
同步运行 GraphRAG 查询,不如尝试使用
asyncio
模块异步运行它。 这将允许 Chainlit 在等待响应时继续处理其他请求。
以下是如何使用
asyncio
运行 GraphRAG 查询的示例:
import asyncio
import chainlit as cl
import shlex
@cl.on_chat_start
def start():
cl.user_session.set("history", [])
@cl.on_message
async def main(message: cl.Message):
history = cl.user_session.get("history")
query = message.content
cmd = [
"python", "-m", "graphrag.query",
"--root", r"C:\Users\Lei Shang\Documents\Projects\LLM_RAG\GraphRAG_ollama_LMStudio_chainlit\graphRag\mistral-large\graphRag-mistral-large",
"--method", "global",
shlex.quote(query),
]
try:
print(cmd)
# 使用 asyncio 创建一个子进程
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
# 异步读取输出
stdout, stderr = await proc.communicate()
output = stdout.decode()
# ... 处理输出并发送回复 ...
except Exception as e:
error_message = f"An error occurred: {e}"
await cl.Message(content=error_message).send()
if __name__ == "__main__":
cl.run()
3. 将 GraphRAG 查询移至后台任务:
可以将 GraphRAG 查询移至单独的后台任务或工作队列中。 这将允许 Chainlit 立即返回响应,并在后台任务完成后更新 UI。 可以使用 Celery 或 Redis Queue 等工具来管理后台任务。
请注意,这些解决方案都需要对的代码进行更广泛的更改。 选择最适合的方法取决于的具体需求和应用程序的体系结构。
标签:python,chainlit,graphrag From: 78804834