Skip to content

[Bug]kb_names 传 UUID 时 get_kb_by_name() 返回 None 且 check_all_kb 静默跳过无日志 #9529

Description

@JiuGe1999

What happened / 发生了什么

其他配置正确,AI配置选择知识库后, 知识库获取为空

Reproduce / 如何复现?

配置语义错位——cmd_config.jsonkb_names 存入的是 kb_id(UUID),而检索代码按 kb_name(名称)匹配:

配置 kb_names = ["xxx"]   ← UUID (kb_id)
知识库实际   = kb_id: xxx  /  kb_name: "xxx"

get_kb_by_name("xxx") 遍历比对 kb_name == UUID
→ 知识库名称是"测试",不匹配 → 返回 None

核心 Bug 有两处:

  1. 配置侧kb_names 字段被填入了 kb_id(Dashboard 界面选择知识库时写入的可能是 ID,而非名称)
  2. 代码侧check_all_kb() 将"知识库未加载(None)"与"知识库为空"混为一谈——加载失败的 KB 被静默当作空库跳过,不产生任何 ERROR 日志;

这是deepseek给我的解决办法, 不确定是否正确;

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

AstrBot4.26.8

OS

Windows

Logs / 报错日志

一、问题现象(日志原文)

知识库中明明存在数据(1 个文档 / 2 个 chunk / faiss 索引 8298 B),但 astr_kb_search 始终返回 "No relevant knowledge found"。

场景 1 — 21:31:45,查询「测试查询 知识库连通性」:

[21:31:45.907] [Core] [INFO] [runners.tool_loop_agent_runner:1038]: Agent 使用工具: ['astr_kb_search']
[21:31:45.908] [Core] [INFO] [runners.tool_loop_agent_runner:1094]: 使用工具:astr_kb_search,参数:{'query': '测试查询 知识库连通性'}
[21:31:45.921] [Core] [INFO] [runners.tool_loop_agent_runner:1291]: Tool `astr_kb_search` Result: No relevant knowledge found.

场景 2 — 21:32:49,查询「测试内容」:

[21:32:49.602] [Core] [INFO] [runners.tool_loop_agent_runner:1038]: Agent 使用工具: ['astr_kb_search']
[21:32:49.602] [Core] [INFO] [runners.tool_loop_agent_runner:1094]: 使用工具:astr_kb_search,参数:{'query': '测试内容'}
[21:32:49.605] [Core] [INFO] [runners.tool_loop_agent_runner:1291]: Tool `astr_kb_search` Result: No relevant knowledge found.

注:两次查询时知识库数据均完好(kb.db 中 doc_count=1, chunk_count=2;index.faiss 8298 B 可正常被 faiss 加载检索,实测命中距离 0.687)。但日志中没有任何 WARNING / ERROR / Traceback。


二、静默失败链路(源码,取自后端实际加载的代码)

retrieve_knowledge_base() 中,知识库通过 kb_name(名称) 匹配:

# L31852
all_kbs = [await kb_mgr.get_kb_by_name(kb) for kb in kb_names]

# L31854
if check_all_kb(all_kbs):

check_all_kb 的实现存在缺陷 —— 当 get_kb_by_name() 返回 None(未匹配到知识库)时,kb and (...) 因 None 为 falsy 而将该元素视为「空知识库」:

# L31752-L31760
def check_all_kb(kb_list: list[KBHelper | None]) -> bool:

    '''检查是否所有的知识库都为空'''

    return not any(

        kb and (kb.kb.doc_count != 0 or kb.kb.chunk_count != 0) for kb in kb_list

    )

命中后仅输出一条 DEBUG 级日志并静默返回,无任何告警:

# L31854-L31858
    all_kbs = [await kb_mgr.get_kb_by_name(kb) for kb in kb_names]
    if check_all_kb(all_kbs):
        logger.debug("所配置的所有知识库全为空,跳过检索过程")
        return None

三、根因:配置项 kb_names 存的是 UUID 而非名称

cmd_config.jsonkb_names 原始值为 kb_id(UUID)

{"kb_names": ["bb47bf6f-3315-49bd-9c9a-7cc4aa9abbac"]}

kb_mgr.get_kb_by_name() 只按 kb_name("测试") 匹配(kb_mgr.py 源码):

def get_kb_by_name(self, kb_name: str) -> KBHelper | None:
    """通过名称获取知识库实例"""
    for kb_helper in self.kb_insts.values():
        if kb_helper.kb.kb_name == kb_name:
            return kb_helper
    return None

UUID ≠ 名称 → 返回 Nonecheck_all_kb([None]) 误判「所有知识库为空」→ 跳过检索 → 返回 "No relevant knowledge found"。全程零 WARNING、零 ERROR,仅 DEBUG 级别一条日志。


四、数据非空佐证

knowledge_base/kb.db(SQLite):

  • knowledge_bases 表:kb_id=bb47bf6f-3315-49bd-9c9a-7cc4aa9abbackb_name=测试doc_count=1chunk_count=2
  • kb_documents 表:1 条文档(测试.md,509 字节)
  • index.faiss:8298 B,可正常加载并检索

五、修复验证

cmd_config.jsonkb_names 改为名称后:

{"kb_names": ["测试"]}

检索立即恢复,astr_kb_search 正常返回知识内容并注入 LLM 上下文(不再出现 "No relevant knowledge found")。


六、建议修复(供开发者参考)

  1. check_all_kb 应区分 None(知识库未加载/未匹配)空库(doc_count=0):出现 None 时应输出 WARNING 并列出未命中的 kb_names,而非静默跳过;
  2. get_kb_by_name() 匹配失败时应显式告警,或回退按 kb_id 查询(get_kb(kb_id));
  3. 建议在配置层校验 kb_names 是否为合法名称(或兼容 UUID)。

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:coreThe bug / feature is about astrbot's core, backendbugSomething isn't workingfeature:knowledge-baseThe bug / feature is about knowledge base

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions