重构:清理废弃代码 + 优化 Agent 架构
All checks were successful
构建并部署 AI Agent 服务 / deploy (push) Successful in 5m24s
All checks were successful
构建并部署 AI Agent 服务 / deploy (push) Successful in 5m24s
主要变更: - 删除 deprecated 文件夹(intent/hybrid_router/rag_nodes 等) - 删除 intent_classifier.py(未使用) - 删除 subgraph_wrapper.py(死代码) - 重构 agent.py:简化工厂函数,支持动态模型切换 - 重构 prompts.py:添加信息获取优先级、思维链要求、工具调用约束 - 优化 tools:统一位置,rag_search 返回置信度评估 - 新增 RAG 置信度评估:embedding(25%) + rerank(25%) + LLM(50%) - 添加循环检测:防止工具无限重复调用 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
"""
|
||||
Agent Tools - 封装所有功能为 @tool 函数
|
||||
Agent Tools - 所有工具统一定义
|
||||
"""
|
||||
|
||||
from langchain_core.tools import tool
|
||||
from typing import Optional
|
||||
from backend.app.logger import info
|
||||
|
||||
# ========== RAG ==========
|
||||
|
||||
# ========== RAG Pipeline(复用现有)
|
||||
_rag_pipeline = None
|
||||
|
||||
|
||||
def _get_rag_pipeline():
|
||||
"""获取 RAG Pipeline 实例(复用 rag_nodes.py 的逻辑)"""
|
||||
global _rag_pipeline
|
||||
if _rag_pipeline is None:
|
||||
from backend.app.rag.pipeline import RAGPipeline
|
||||
@@ -28,161 +26,100 @@ def _get_rag_pipeline():
|
||||
@tool
|
||||
async def rag_search(query: str) -> str:
|
||||
"""
|
||||
检索知识库获取相关信息。
|
||||
|
||||
当用户询问关于系统、业务、文档相关的问题时使用此工具。
|
||||
|
||||
Args:
|
||||
query: 用户的问题或搜索关键词
|
||||
|
||||
检索知识库获取相关信息
|
||||
|
||||
Returns:
|
||||
检索到的相关文档内容
|
||||
包含检索结果和置信度的结构化回复,格式:
|
||||
- 内容:检索到的相关信息
|
||||
- 置信度评估:基于向量相似度、重排分数、LLM判断的综合评分
|
||||
"""
|
||||
info(f"[RAG Tool] 开始检索: {query[:50]}...")
|
||||
|
||||
info(f"[Tool] rag_search: {query[:30]}...")
|
||||
try:
|
||||
pipeline = _get_rag_pipeline()
|
||||
documents = await pipeline.aretrieve(query)
|
||||
rag_context = pipeline.format_context(documents)
|
||||
|
||||
info(f"[RAG Tool] 检索完成,得到 {len(documents)} 个文档")
|
||||
|
||||
if rag_context:
|
||||
return rag_context
|
||||
else:
|
||||
return "知识库中没有找到相关内容。"
|
||||
|
||||
except Exception as e:
|
||||
info(f"[RAG Tool] 检索失败: {e}")
|
||||
return f"知识库检索失败: {str(e)}"
|
||||
# 使用带置信度的检索
|
||||
result = await pipeline.aretrieve_with_confidence(query, original_query=query)
|
||||
|
||||
if not result.content:
|
||||
return "【RAG检索结果】\n未在知识库中找到相关内容。\n置信度:0.0\n建议:可尝试联网搜索获取信息。"
|
||||
|
||||
# 构建包含置信度的回复
|
||||
confidence_desc = "高"
|
||||
if result.confidence < 0.4:
|
||||
confidence_desc = "低"
|
||||
elif result.confidence < 0.6:
|
||||
confidence_desc = "中"
|
||||
|
||||
response = f"""【RAG检索结果】
|
||||
{result.content}
|
||||
|
||||
【置信度评估】
|
||||
- 综合置信度:{result.confidence:.2f}({confidence_desc})
|
||||
- 向量相似度:{result.scores['embedding']:.2f}
|
||||
- 重排分数:{result.scores['rerank']:.2f}
|
||||
- LLM评估:{result.scores['llm']:.2f}
|
||||
|
||||
{'✅ 检索结果可信,可直接使用' if result.is_useful else '⚠️ 检索结果置信度较低,可能需要联网搜索补充'}"""
|
||||
|
||||
info(f"[Tool] rag_search 完成: confidence={result.confidence:.3f}, is_useful={result.is_useful}")
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
info(f"[Tool] rag_search 失败: {e}")
|
||||
return f"【RAG检索失败】\n错误:{str(e)}\n建议:请稍后重试或使用联网搜索"
|
||||
|
||||
|
||||
# ========== 联网搜索 ==========
|
||||
|
||||
@tool
|
||||
def web_search(query: str) -> str:
|
||||
"""
|
||||
联网搜索获取最新信息。
|
||||
|
||||
当用户询问实时新闻、热点事件、最新资讯或知识库中没有的内容时使用此工具。
|
||||
|
||||
Args:
|
||||
query: 搜索关键词
|
||||
|
||||
Returns:
|
||||
搜索结果摘要
|
||||
"""
|
||||
info(f"[WebSearch Tool] 开始搜索: {query[:50]}...")
|
||||
|
||||
"""联网搜索获取最新信息"""
|
||||
info(f"[Tool] web_search: {query[:30]}...")
|
||||
try:
|
||||
from backend.app.core import web_search as core_web_search
|
||||
search_result = core_web_search(query, max_results=5)
|
||||
|
||||
info(f"[WebSearch Tool] 搜索完成")
|
||||
return search_result
|
||||
|
||||
from backend.app.core.web_search import web_search as search_fn
|
||||
return search_fn(query, max_results=5)
|
||||
except Exception as e:
|
||||
info(f"[WebSearch Tool] 搜索失败: {e}")
|
||||
info(f"[Tool] web_search 失败: {e}")
|
||||
return f"联网搜索失败: {str(e)}"
|
||||
|
||||
|
||||
# ====== 子图工具封装器
|
||||
async def _invoke_subgraph(subgraph_builder, query: str, state_class) -> str:
|
||||
"""
|
||||
通用子图调用函数
|
||||
|
||||
Args:
|
||||
subgraph_builder: 子图构建函数
|
||||
query: 用户查询
|
||||
state_class: 子图状态类
|
||||
|
||||
Returns:
|
||||
子图执行结果
|
||||
"""
|
||||
# ========== 子图工具 ==========
|
||||
|
||||
async def _call_subgraph(builder_fn, state_cls, query: str) -> str:
|
||||
"""通用子图调用"""
|
||||
try:
|
||||
graph = subgraph_builder()
|
||||
compiled_graph = graph.compile()
|
||||
|
||||
# 构造初始状态
|
||||
initial_state = state_class(user_query=query)
|
||||
|
||||
# 调用子图
|
||||
result = await compiled_graph.ainvoke(initial_state)
|
||||
|
||||
# 返回结果
|
||||
return result.get("final_result", "子图执行完成")
|
||||
|
||||
graph = builder_fn().compile()
|
||||
state = state_cls(user_query=query)
|
||||
result = await graph.ainvoke(state)
|
||||
return result.get("final_result", "执行完成")
|
||||
except Exception as e:
|
||||
info(f"[Subgraph Tool] 执行失败: {e}")
|
||||
info(f"[Tool] 子图调用失败: {e}")
|
||||
return f"执行失败: {str(e)}"
|
||||
|
||||
|
||||
@tool
|
||||
async def contact_lookup(query: str) -> str:
|
||||
"""
|
||||
查询通讯录信息。
|
||||
|
||||
当用户询问联系人、邮箱、联系方式、发送邮件时使用此工具。
|
||||
|
||||
Args:
|
||||
query: 用户查询,描述需要的操作
|
||||
|
||||
Returns:
|
||||
联系人信息或操作结果
|
||||
"""
|
||||
info(f"[Contact Tool] 查询: {query[:50]}...")
|
||||
|
||||
"""查询通讯录"""
|
||||
from backend.app.subgraphs.contact.graph import build_contact_subgraph
|
||||
from backend.app.subgraphs.contact.state import ContactState
|
||||
|
||||
return await _invoke_subgraph(build_contact_subgraph, query, ContactState)
|
||||
return await _call_subgraph(build_contact_subgraph, ContactState, query)
|
||||
|
||||
|
||||
@tool
|
||||
async def dictionary_lookup(word: str) -> str:
|
||||
"""
|
||||
查询词典,获取单词释义、翻译等。
|
||||
|
||||
当用户询问单词、翻译、生词时使用此工具。
|
||||
|
||||
Args:
|
||||
word: 需要查询的单词或短语
|
||||
|
||||
Returns:
|
||||
单词释义和翻译
|
||||
"""
|
||||
info(f"[Dictionary Tool] 查询: {word}")
|
||||
|
||||
"""查询词典/翻译"""
|
||||
from backend.app.subgraphs.dictionary.graph import build_dictionary_subgraph
|
||||
from backend.app.subgraphs.dictionary.state import DictionaryState
|
||||
|
||||
return await _invoke_subgraph(build_dictionary_subgraph, word, DictionaryState)
|
||||
return await _call_subgraph(build_dictionary_subgraph, DictionaryState, word)
|
||||
|
||||
|
||||
@tool
|
||||
async def news_analysis(topic: str) -> str:
|
||||
"""
|
||||
分析热点新闻和资讯。
|
||||
|
||||
当用户询问新闻分析、热点解读时使用此工具。
|
||||
|
||||
Args:
|
||||
topic: 新闻主题或关键词
|
||||
|
||||
Returns:
|
||||
新闻分析结果
|
||||
"""
|
||||
info(f"[NewsAnalysis Tool] 分析: {topic}")
|
||||
|
||||
"""分析新闻热点"""
|
||||
from backend.app.subgraphs.news_analysis.graph import build_news_analysis_subgraph
|
||||
from backend.app.subgraphs.news_analysis.state import NewsAnalysisState
|
||||
|
||||
return await _invoke_subgraph(build_news_analysis_subgraph, topic, NewsAnalysisState)
|
||||
return await _call_subgraph(build_news_analysis_subgraph, NewsAnalysisState, topic)
|
||||
|
||||
|
||||
# ====== 导出所有工具
|
||||
ALL_TOOLS = [
|
||||
rag_search,
|
||||
web_search,
|
||||
contact_lookup,
|
||||
dictionary_lookup,
|
||||
news_analysis,
|
||||
]
|
||||
# ========== 导出 ==========
|
||||
|
||||
ALL_TOOLS = [rag_search, web_search, contact_lookup, dictionary_lookup, news_analysis]
|
||||
|
||||
Reference in New Issue
Block a user