feat: 修复数据库持久化,完善服务降级机制
All checks were successful
构建并部署 AI Agent 服务 / deploy (push) Successful in 5m37s
All checks were successful
构建并部署 AI Agent 服务 / deploy (push) Successful in 5m37s
- 恢复使用 AsyncPostgresSaver 持久化短期记忆 - 添加 LLM 作为 Rerank 服务的最后降级方案 - 完善降级链:Local llama.cpp → Zhipu Rerank → LLM Fallback
This commit is contained in:
@@ -136,6 +136,92 @@ class ZhipuRerankService(BaseRerankService):
|
||||
raise
|
||||
|
||||
|
||||
class LLMFallbackRerankService(BaseRerankService):
|
||||
"""
|
||||
使用 LLM 作为最后的降级方案进行重排
|
||||
通过让 LLM 评估文档相关性并给出分数
|
||||
"""
|
||||
|
||||
def __init__(self, llm=None):
|
||||
from .chat_services import get_chat_service
|
||||
self.llm = llm or get_chat_service()
|
||||
|
||||
def compute_scores(self, query: str, documents: List[str]) -> List[float]:
|
||||
"""
|
||||
使用 LLM 评估文档相关性并打分
|
||||
"""
|
||||
if not documents:
|
||||
return []
|
||||
|
||||
scores = []
|
||||
for doc in documents:
|
||||
score = self._score_single_document(query, doc)
|
||||
scores.append(score)
|
||||
|
||||
return scores
|
||||
|
||||
def _score_single_document(self, query: str, document: str) -> float:
|
||||
"""
|
||||
让 LLM 为单个文档的相关性打分 (0.0-1.0)
|
||||
"""
|
||||
prompt = f"""你是一个文档相关性评分专家。请评估以下文档与查询的相关性,返回一个0到1之间的分数:
|
||||
- 1.0表示完全相关
|
||||
- 0.0表示完全不相关
|
||||
|
||||
查询: {query}
|
||||
|
||||
文档: {document}
|
||||
|
||||
请只返回一个数字,不要解释。"""
|
||||
|
||||
try:
|
||||
result = self.llm.invoke(prompt)
|
||||
content = result.content if hasattr(result, 'content') else str(result)
|
||||
# 尝试提取数字
|
||||
import re
|
||||
match = re.search(r'(\d+\.?\d*)', content)
|
||||
if match:
|
||||
score = float(match.group(1))
|
||||
# 确保在 0-1 之间
|
||||
return max(0.0, min(1.0, score))
|
||||
# 如果没有找到数字,返回0.5作为默认值
|
||||
return 0.5
|
||||
except Exception as e:
|
||||
logger.warning(f"LLM 打分失败,返回默认分数 0.5: {e}")
|
||||
return 0.5
|
||||
|
||||
|
||||
class LLMFallbackRerankProvider(BaseServiceProvider[BaseRerankService]):
|
||||
"""
|
||||
LLM 降级重排服务提供者
|
||||
"""
|
||||
|
||||
def __init__(self, llm=None):
|
||||
super().__init__("llm_fallback_rerank")
|
||||
self._llm = llm
|
||||
|
||||
def is_available(self) -> bool:
|
||||
"""
|
||||
LLM 降级方案总是可用(只要 LLM 服务可用)
|
||||
"""
|
||||
try:
|
||||
from .chat_services import get_chat_service
|
||||
get_chat_service()
|
||||
logger.info("LLM 降级重排服务可用")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"LLM 降级重排服务不可用: {e}")
|
||||
return False
|
||||
|
||||
def get_service(self) -> BaseRerankService:
|
||||
"""
|
||||
获取 LLM 降级重排服务
|
||||
"""
|
||||
if self._service_instance is None:
|
||||
self._service_instance = LLMFallbackRerankService(self._llm)
|
||||
return self._service_instance
|
||||
|
||||
|
||||
class LocalLlamaCppRerankProvider(BaseServiceProvider[BaseRerankService]):
|
||||
"""
|
||||
本地 llama.cpp 重排服务提供者
|
||||
@@ -221,13 +307,15 @@ def get_rerank_service() -> BaseRerankService:
|
||||
"""
|
||||
获取重排服务(带自动降级)- 纯服务层
|
||||
|
||||
降级链: Local llama.cpp -> Zhipu Rerank -> LLM Fallback
|
||||
|
||||
Returns:
|
||||
BaseRerankService: 重排服务实例
|
||||
"""
|
||||
def _create_chain():
|
||||
primary = LocalLlamaCppRerankProvider()
|
||||
fallback = ZhipuRerankProvider()
|
||||
return FallbackServiceChain(primary, [fallback])
|
||||
fallbacks = [ZhipuRerankProvider(), LLMFallbackRerankProvider()]
|
||||
return FallbackServiceChain(primary, fallbacks)
|
||||
|
||||
chain = SingletonServiceManager.get_or_create("rerank_service_chain", _create_chain)
|
||||
return chain.get_available_service()
|
||||
|
||||
Reference in New Issue
Block a user