Files
group_xinghuo_jinrong/app/tool/kb_tools.py
T
zhanghongyu_0626 7dadec279d fix(memory): Address multi-turn dialogue defects and enhance context handling
- Implemented `_merged_items` and `_merged_memory_text` functions to consolidate consult and chitchat memories, improving context awareness in intent classification and response generation.
- Updated intent prompts to include recent dialogue history, aiding in the resolution of ambiguous user queries.
- Enhanced `search_knowledge` tool to utilize context window for better query understanding, addressing issues with omitted references in user inputs.
- Fixed existing test cases to reflect changes in intent constants and ensure accurate context handling during tests.

This update significantly improves the handling of multi-turn dialogues, ensuring a more coherent and contextually aware interaction for users.
2026-09-14 00:59:14 +08:00

78 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""知识库对话 Tool(T21-5 · FLOW §2「milvus_tool:产品规则 RAG + source_refs」)。
与 core_tools / risk.chat_tools 同构的 Tool 定义层:由 tool_service.run_tool
经统一注册表分发。search_knowledge 是公开知识检索(产品手册/交易规则)——
**不做客户归属校验**(ToolSpec.skip_access_check=True):
- 知识内容为公开产品信息,无客户数据,归属校验无对象;
- 开放范围(customer + advisor,用户拍板 2026-09-07)由意图层控制:
_INTENT_KEYWORDS 仅 customer/advisor 组配置 kb 关键词,risk/analyst
不命中 → Tool 不会被触发;即使被直接调用,返回的也只是公开知识。
func 签名对齐 runner 约定 ``func(customer_id, core_ro, risk_repo, **params)``;
query 为唯一业务参数(tool_node 从 user_message 构造 tool_input 注入,
一期不来自 LLM 输出)。RAG 异常(EmbeddingError 等)原样上抛 → run_tool
统一转 TOOL_ERROR 留痕,不静默降级空结果(防 LLM 编造回答)。
"""
from __future__ import annotations
from typing import Any, Callable
from app.service import rag_service
# 对话 Tool 检索条数(与 rag_service.DEFAULT_TOP_K 一致;独立常量便于对话口径单独调整)
KB_TOP_K = 3
def search_knowledge(
query: str = "",
customer_id: str = "",
core_ro=None,
risk_repo=None,
context_window: str = "",
) -> dict[str, Any]:
"""产品知识检索(TopK chunks + 溯源清单)。
customer_id/core_ro/risk_repo 为 runner 恒传参数,本 Tool 不使用
(公开知识,无归属语义);保留形参以满足统一签名。
context_window 为 tool_node 注入的近期对话,拼接进 query 使检索
感知历史(解决「那申购呢」类省略指代)。
"""
effective_query = query
if context_window and context_window.strip():
effective_query = f"{context_window.strip()}\n{query}"
out = rag_service.search_knowledge(effective_query, top_k=KB_TOP_K)
return {
"hit_count": len(out["results"]),
"results": out["results"],
"source_refs": out["source_refs"],
}
class KBToolSpec(dict):
"""知识库 Tool 注册表条目(与 core_tools.ToolSpec / RiskToolSpec 同构;
新增 skip_access_check:True → run_tool 跳过客户归属校验)。"""
KB_TOOL_REGISTRY: dict[str, KBToolSpec] = {
"search_knowledge": KBToolSpec(
func=search_knowledge,
description="检索产品知识库(基金产品手册、费率、申赎规则、风险说明;返回结果附溯源)",
requires_customer=False,
param_whitelist=("query",),
int_bounds={},
skip_access_check=True,
),
}
def get_kb_tool(name: str) -> KBToolSpec | None:
"""白名单查找(未知 Tool 返回 None)。"""
return KB_TOOL_REGISTRY.get(name)
def kb_tool_func(name: str) -> Callable[..., dict[str, Any]] | None:
spec = KB_TOOL_REGISTRY.get(name)
return spec["func"] if spec else None