您正在查看静态缓存页面 · 查看完整动态版本 · 登录 参与讨论

当AI遇见知识库:向量数据库的魔法 ✨🤖

QianXun (QianXun) 2025年11月24日 02:52 0 次浏览
注解:所谓"向量数据库",就像一座特殊的数字图书馆,它不是按书名或作者排列书籍,而是将每本书的内容转化为数学意义上的"思想坐标",让机器能够理解文字背后的语义关联。这种技术正在重塑AI记忆的本质。

🚀 引子:一个程序员的深夜困惑

凌晨两点的台灯下,林默盯着屏幕上跳动的红色错误信息,陷入了沉思。作为一家初创公司的AI工程师,他刚刚接到了一个看似简单的任务:如何让AI助手既能理解公司业务文档,又不用为每千次API调用支付高昂的费用?

这个问题像一颗石子投入平静的湖面,在AI社区激起了无数涟漪。就在上周,他的同事尝试用大语言模型的云端嵌入服务处理公司知识库,结果月末账单上的数字让财务总监差点把手中的咖啡喷在显示器上。而今天,林默偶然发现的一段Python代码,似乎为他打开了一扇新的大门——本地运行的向量数据库

让我们跟随林默的视角,一起探索这场正在悄然发生的技术革命。

🎭 第一幕:Agno框架的登场——当AI需要一个大脑

🤔 什么是Agno?AI世界的"神经元连接器"

想象一下,你正在建造一个智能机器人。你有强大的语言模型作为"嘴巴",有海量的数据作为"食物",但缺少一个协调消化系统——一个能让机器人理解、存储、回忆信息的"大脑"。Agno框架,正是这样一个为AI Agent设计的"中枢神经系统"。

注解:Agno(原名Phidata)是一个开源的AI Agent框架,它像一位精明的管家,负责协调大语言模型、知识库、工具和用户之间的复杂交互。它的核心使命是让AI不止于"聊天",而是真正具备记忆、规划和执行能力。
在林默发现的代码中,from agno.agent import Agent这行简单的导入,背后隐藏着一个精妙的设计哲学。传统的大语言模型就像一位记忆力超群的脱口秀演员——他能即兴发挥,但说完就忘。而Agno赋予AI持久化记忆的能力,让它能像人类一样积累经验、构建知识体系。

这种能力的关键在于 知识库(Knowledge) 的引入。代码中的Knowledge(vector_db=vector_db, contents_db=SqliteDb(...))这一行,实际上在构建一个双层记忆系统:

  • 向量数据库(ChromaDB):负责语义记忆,像海马体一样存储概念间的关联
  • SQLite数据库:负责情景记忆,像大脑皮层一样记录具体事实

这让人想起诺贝尔奖得主埃里克·坎德尔的研究——记忆并非存储在某个单一位置,而是分布在复杂的神经网络中。Agno正是借鉴了这种生物智慧。

🧩 知识库的双生子:向量与表格的协奏曲

让我们深入代码的核心构造:

vector_db = ChromaDb(
    collection="knowledge_base",
    path="tmp/chromadb",
    embedder=embedder,
)

这段配置就像为图书馆设计分类系统。ChromaDb是那座特殊的图书馆,但真正的魔法发生在embedder参数上。它告诉图书馆:"请用我指定的翻译官,把文字变成向量坐标。"

contents_db=SqliteDb(db_file="knowledge_contents.db")则像图书馆的传统卡片目录系统,记录着每本书的元数据、入库时间和原始文本。这种混合架构解决了纯向量数据库的一个致命弱点:向量本身是不可读的。当你需要追溯AI回答的依据时,SQLite中的原始文本就是那份不可篡改的"档案原件"。

小贴士:想象一下,你向AI提问"公司年假政策",它回答"根据2024年HR手册第3章..."。向量数据库让它找到了相关段落,而SQLite数据库让它能准确引用原文并标注来源。这就像侦探既有线索墙(向量关联),又有证据保险箱(原始文本)。

第二幕:嵌入模型——AI世界的"巴别塔翻译官"

🗣️ 从云端到本地:一场关于自主权的革命

代码中最让林默眼前一亮的是这段配置:

embedder = SentenceTransformerEmbedder(
    id="sentence-transformers/all-MiniLM-L6-v2",
    dimensions=384,
)

这行代码标志着从依赖到自主的范式转移。传统方案中,嵌入模型运行在云端,每次调用都是一次"过路费"的累积。而sentence-transformers库让这一切都发生在本地——你的笔记本电脑、你的服务器,甚至你的树莓派上。

注解all-MiniLM-L6-v2是一个轻量级的双向编码器模型,它将句子映射为384维的向量空间。虽然维度不高,但在速度和质量的平衡上表现优异,特别适合中文语义理解。这就像一位语速极快又准确率高的同声传译员。
让我们理解一下"嵌入"(Embedding)的魔法。当你输入"机器学习是人工智能的分支"这句话时,传统计算机看到的是一串Unicode编码:[0x673a, 0x5668, 0x5b66, ...]。但嵌入模型将它转化为一个语义坐标[0.23, -0.87, 0.45, ..., 0.12](共384个数字)。

这个过程就像给每句话打上"思想指纹"。相似的句子在向量空间中距离很近:

  • "猫在沙发上睡觉" ↔ "沙发上有一只熟睡的猫"(距离≈0.1)
  • "猫在沙发上睡觉" ↔ "量子纠缠的物理原理"(距离≈0.9)

🧮 维度的艺术:在精确与效率之间走钢丝

dimensions=384这个数字背后,是计算复杂度和语义表达能力之间的精妙权衡。想象你要在一张纸上标注所有水果的位置:

  • 2维:只能粗略分为"甜的/酸的"
  • 50维:可以区分"热带水果/温带水果"、"有籽/无籽"、"软皮/硬皮"
  • 384维:甚至能捕捉"适合早餐的"、"适合做甜点的"、"富含维生素C的"等抽象概念

但维度越高,计算开销越大。384维是一个"甜点"——既能捕捉足够的语义细节,又不会在搜索时让CPU风扇狂转。这让人想起信息论之父香农的洞见:通信的本质是在冗余和效率间找到平衡

林默做了一个简单的测试:用all-MiniLM-L6-v2处理公司1000份技术文档,总耗时仅3分钟,而云端API方案需要20分钟且花费47美元。这种成本-效率的指数级优化,对于初创公司而言,无异于从"租昂贵的写字楼"转向"在家办公"。

🗄️ 第三幕:ChromaDB——语义记忆的超级海马体

📚 向量数据库的工作原理:超越关键词的语义搜索

传统数据库就像一位严格的图书管理员——你必须准确说出书名或ISBN,她才能找到书。而ChromaDB更像一位读过所有书的文学教授,你问他"有什么关于存在主义困境的小说?",他能立刻联想到卡夫卡的《变形记》和加缪的《局外人》。

代码中的collection="knowledge_base"定义了一个知识集合。在ChromaDB中,每个集合都是一个独立的向量空间。你可以想象成不同的记忆宫殿:

  • knowledge_base:存放公司技术文档
  • customer_feedback:存放用户反馈
  • competitor_analysis:存放竞品分析

path="tmp/chromadb"persistent_client=True的组合,确保了这些记忆不会随程序关闭而消失。这解决了早期向量数据库的一个痛点:易失性存储。就像人类的大脑需要睡眠来巩固记忆,持久化存储让向量数据库成为真正的"知识资产"。

🔍 相似度搜索的魔法:余弦相似度的几何直觉

当执行knowledge_base.search("编程语言", max_results=2)时,背后发生了什么?

  1. 编码:将查询"编程语言"转换为384维向量 → query_vector
  2. 扫描:计算query_vector与库中所有向量的余弦相似度
  3. 排序:返回相似度最高的2个结果
余弦相似度的公式是:
$$\text{similarity} = \frac{A \cdot B}{||A|| \cdot ||B||}$$

其中$A \cdot B$是向量点积,$||A||$是向量模长。这个公式衡量的是两个向量方向的夹角,而非距离。就像两个意见不同的人,如果观点方向一致,他们仍然"相似"。

小贴士:想象你在星空下导航。两颗星星可能距离地球不同(向量模长不同),但如果它们在天球上的角度接近,你就会认为它们"相邻"。余弦相似度正是这种"天球导航"的数学抽象。

🤖 第四幕:DeepSeek模型——国产大语言模型的崛起

🌟 DeepSeek-chat:性价比之王的秘密

代码中的DeepSeek(id="deepseek-chat", api_key=api_key)指向的是杭州深度求索公司开发的大语言模型。在GPT-4动辄每百万token 60美元的背景下,DeepSeek-chat以1/30的价格提供接近的性能,这对预算有限的团队是革命性的。

但更重要的是自主可控性。当林默的公司处理涉及商业机密的技术文档时,使用国产模型意味着数据传输路径更短、合规风险更低。这就像从"租用外国邮差"转向"雇佣本地信使"——不仅更便宜,而且更安全。

注解:DeepSeek采用了MoE(Mixture of Experts)架构,每次推理只激活部分参数,这解释了其成本优势。就像一个医院,不是所有科室同时工作,而是根据病情调用相应专家。

🔑 API Key的优雅降级策略

代码中api_key = os.getenv("DEEPSEEK_API_KEY") or os.getenv("OPENAI_API_KEY")这一行体现了防御性编程的智慧。在现实世界中,API密钥可能在不同环境变量中配置,或者团队从OpenAI迁移到DeepSeek需要一个过渡期。

这种"或"逻辑让代码具备了环境适应性,就像植物既能通过根系吸收水分,也能通过叶片吸收雨露。当DEEPSEEK_API_KEY不存在时,系统会自动尝试OPENAI_API_KEY,避免了硬编码带来的脆性。

🧠 第五幕:Agent的智能涌现——从工具到协作者

🎭 Agent的指令系统:塑造AI的人格

instructions="你是一个知识专家,可以基于提供的知识库回答问题。"这行代码看似简单,却是提示工程(Prompt Engineering)的精髓。它像给AI戴上一副"角色眼镜",让模型从通用聊天助手转变为领域专家。

研究表明,明确的角色设定能提升大语言模型在特定任务上的准确率15-20%。这就像告诉一位演员:"你要演一位严谨的科学家",他的台词、语调、肢体语言都会随之调整。Agno将这种角色扮演从一次性提示升级为持久化配置,让AI在整个对话生命周期中保持一致性。

💡 print_response的魔法:流式输出的用户体验

当执行agent.print_response("请介绍一下 Python 的历史。")时,Agno框架在背后实现了流式生成(Streaming Generation)。不同于等待整个回答完成再显示,流式输出让用户逐字看到思考过程,极大地改善了感知延迟

这借鉴了心理学中的进度指示器效应:即使总时间不变,能让用户看到进展的界面会获得更高的满意度。就像下载文件时,进度条让你感觉"一切都在掌控中"。

🔬 第六幕:错误处理与质量校验——系统的鲁棒性之美

🛡️ try-except的层层防护

代码中至少有三层错误处理:

  1. 嵌入模型加载:捕获ImportError和通用异常
  2. 知识添加try...except Exception as e
  3. 知识搜索:同样的防护模式

这种设计体现了 容错计算(Fault-Tolerant Computing) 的思想。在分布式系统中,优雅降级(Graceful Degradation)比完美运行更重要。就像飞机有备用引擎,Agno的知识库系统即使部分组件失效,也能提供基础功能。

小贴士:在AI应用开发中,永远假设外部依赖会失败 。API服务可能宕机、模型可能超时、数据库可能锁死。良好的错误处理不是锦上添花,而是 生存必需

📊 性能与成本的隐性优化

虽然代码未显式展示,但使用本地嵌入模型+向量数据库的组合,带来了 三个数量级的成本优化

  • 云端嵌入API:约$0.0001/次 × 10000次 = $1
  • 本地嵌入:$0(一次性GPU成本)
  • 速度:本地通常快5-10倍

对于需要处理百万级文档的企业,这意味着每年节省数十万美元。这不仅是技术选择,更是商业模式的变革——让AI知识管理从"奢侈品"变为"日用品"。

🌈 第七幕:未来展望——从配置到生态

🚀 下一步的演进路径

林默在成功运行这段代码后,开始思考更远的未来:

多模态知识库:当前的SentenceTransformerEmbedder主要处理文本。下一步,可以引入CLIP模型处理图片,用Whisper嵌入音频,构建真正的全感官记忆系统。想象一下,AI不仅能读懂技术文档,还能识别架构图、听懂会议录音。

实时知识更新:代码中的knowledge_base.add_content()是手动调用。未来可以集成Webhook,让知识库在Jira工单更新、Git提交、Slack讨论时自动学习。这实现了组织记忆的持续同步,就像人类通过日常交流不断更新认知。

联邦学习架构:对于跨国企业,可以在每个地区部署本地向量数据库,只同步加密的向量指纹而非原始文本。这既满足了GDPR等数据主权法规,又实现了全球知识共享。

注解:联邦学习(Federated Learning)是谷歌提出的 distributed machine learning 范式,核心思想是"数据不动模型动"。在知识库场景中,这意味着纽约办公室的AI可以学习北京团队的知识,而无需传输敏感的商业文档。

🎓 对开发者的启示:构建AI原生应用

这段代码不仅是技术演示,更是 AI原生应用(AI-Native Apps) 的设计范式:

  1. 模型路由(Model Routing):根据任务复杂度选择不同模型。简单查询用本地小模型,复杂推理调用云端大模型。
  2. 缓存策略(Caching Strategy):高频查询的结果可以缓存在Redis,避免重复向量搜索。
  3. 可观测性(Observability):记录每次搜索的延迟、召回率和用户满意度,持续优化嵌入模型和向量索引。
林默在代码注释里写下:"今天,我们让AI记住了公司的知识;明天,AI将帮助公司创造新知识。"这句话或许正是这场技术革命的终极隐喻。

🌟 尾声:代码背后的哲学思考

💭 从工具到伙伴:AI的终极形态

当我们审视这段不足100行的Python代码,看到的不仅是技术实现,更是人机关系演进的缩影。Agno框架的名字本身就充满哲学意味——在古希腊语中,Agno意为"纯洁的认知"。它暗示着AI应该像一面镜子,忠实反映人类知识的本质,而非扭曲或虚构。

向量数据库的兴起,标志着AI从"计算工具"向"认知伙伴"的转变。当AI能准确回忆、关联、推理你的私有知识时,它不再是一个用完即弃的软件,而是组织智慧的延伸

小贴士:这场变革的关键,不是让AI更强大,而是让AI更"懂你"——理解你的业务、你的文档、你的思考方式。本地嵌入模型和向量数据库,正是实现"个性化AI"的基石。

🔮 下一个十年:知识管理的民主化

回想十年前,构建这样的系统需要:

  • 一个博士级的NLP团队
  • 百万级的服务器集群
  • 长达数年的研发周期

而今天,一个初级开发者用开源工具和几百行代码就能实现。这让人想起个人电脑革命——当计算能力从大型机走向桌面,创意和创新的源泉就从小众精英涌向了大众。

林默关掉了IDE,看着窗外渐亮的天色。他知道,这段代码不仅解决了一个技术问题,更打开了一扇门:让每家公司、每个团队、甚至每个人,都能拥有属于自己的AI知识伙伴。这或许是这场技术革命最动人的地方——知识的记忆与传承,从此不再昂贵。


📚 参考文献

  1. Agno官方文档. "Knowledge Bases for Agentic RAG". https://agno.com/knowledge
  2. ChromaDB技术白皮书. "Building the AI-native embedding database". https://trychroma.com
  3. Reimers, Nils, and Iryna Gurevych. "Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks." Proceedings of the 2019 Conference on Empirical Methods in Natural Language Processing. 2019.
  4. DeepSeek AI技术报告. "DeepSeek LLM: Scaling Open-Source Language Models with Longtermism". 2024.
  5. McKinsey Global Institute. "The Economic Potential of Generative AI: The Next Productivity Frontier". 2023.

致谢:感谢开源社区让复杂技术变得触手可及,感谢每一位在深夜调试代码的开发者——正是你们的困惑与坚持,推动了这场静悄悄的知识革命。

讨论回复

1 条回复
QianXun (QianXun) #1
11-24 03:09

《当知识开始“长记性”:一个小型 AI 知识库是怎样醒过来的》

想象一下,你有一位记性超好的助理:跟 TA 讲过的事情,过几天再问,还能带着上下文清清楚楚地复述给你听。上面这段 Python 脚本,其实就在做这样的事——它给一个 LLM(DeepSeek 聊天模型)装上了“长期记忆”,让模型不再只是一次性对话,而是可以依托自己的知识库来回答问题。

下面我们拆开来看,这个“小型 AI 知识库系统”是如何一步一步搭起来的。


🧱 整体结构:三块积木拼出一个“有记忆”的 Agent

从代码结构上看,一共三块核心组件:

  1. 嵌入模型(Embedding) + 向量数据库(Chroma)
负责把文本“压缩”成向量,并存入一个可持久化的向量库。
  1. 知识库封装(Knowledge + SqliteDb + ChromaDb)
负责统一管理“原始文本内容 + 向量索引”。
  1. Agent(DeepSeek 聊天模型 + Knowledge)
负责真正和用户对话、从知识库中检索信息并组织回答。

主流程在 main() 里:

def main():
    # 1. 创建知识库(向量库 + 内容库)
    knowledge_base = create_knowledge_base()
    
    # 2. 创建 DeepSeek 聊天模型
    model = create_agent()
    
    # 3. 用这个模型 + 知识库,创建 Agent
    agent = Agent(
        model=model,
        knowledge=knowledge_base,
        instructions="你是一个知识专家,可以基于提供的知识库回答问题。",
    )
    
    # 4. 往知识库里塞几条示例知识
    ...
    
    # 5. 让 Agent 基于知识库回答问题
    ...
    
    # 6. 直接对知识库做搜索
    ...

这就相当于:

  • create_knowledge_base() = 给助理准备“记忆系统”;
  • create_agent() = 找一个会说话的大脑(LLM);
  • Agent(...) = 把这俩组装成能聊天、又有记忆的“全职助理”。


🧬 本地嵌入模型:给文字“测 DNA”

1. 为什么需要“嵌入(Embedding)”?

向量数据库不是直接存字符串,而是存向量
所以必须先把文本变成向量,这个过程就像是:对每句话做一次“DNA 测试”,输出一串能代表语义的数字序列。

在代码中,这一步由本地的 SentenceTransformerEmbedder 完成:

from agno.knowledge.embedder.sentence_transformer import SentenceTransformerEmbedder

embedder = SentenceTransformerEmbedder(
    id="sentence-transformers/all-MiniLM-L6-v2",  # 轻量级模型,适合中文
    dimensions=384,  # 该模型的输出维度
)
注解 Sentence Transformers 是一个专门做文本向量化的模型家族,all-MiniLM-L6-v2 是其中相对轻量的一款。 384 维向量意味着:每段文本会被映射到一个 384 维的“语义坐标系”中。

2. 完全本地,无需 API

这里的嵌入模型是本地加载,没有调用任何云端 API:

  • 优点:不依赖网络,不消耗外部 API 额度,隐私友好;
  • 代价:机器上要能装得下模型(但这个模型非常小,一般电脑可以轻松跑)。
代码里也做了基本的异常处理:
except ImportError:
    print("❌ 未安装 sentence-transformers 包")
    print("请运行: pip install sentence-transformers")
    return None
except Exception as e:
    print(f"❌ 加载嵌入模型失败: {e}")
    return None

这相当于在启动“记忆系统”之前先检查下:我有没有给自己装上“理解语义的眼镜”?


🗂️ Chroma 向量数据库:给记忆找个“仓库”

1. 创建 ChromaDb 实例

有了嵌入器,下一步就是找个地方放向量。这就是 Chroma 的工作:

vector_db = ChromaDb(
    collection="knowledge_base",
    path="tmp/chromadb",
    persistent_client=True,  # 启用持久化存储
    embedder=embedder,
)

几个关键信息:

  • collection="knowledge_base":相当于一个“知识库名字空间”,方便分类管理。
  • path="tmp/chromadb":向量索引会持久化在这个目录里,下次运行还能用。
  • persistent_client=True:开启持久化,而不是每次内存临时玩一把就扔了。
  • embedder=embedder:告诉 Chroma:怎么把文本变成向量,由这个嵌入器说了算
注解 向量数据库的核心能力是: 给定一个查询向量,快速找到“向量空间里最接近的那些向量”——这就是语义检索的基础。

📚 Knowledge:把“向量索引 + 原文内容”绑在一起

只存向量还不够,用户问问题时,你得能把原始文本拿出来展示。这就是 Knowledge 的职责:

knowledge_base = Knowledge(
    vector_db=vector_db,
    contents_db=SqliteDb(db_file="knowledge_contents.db")
)

这里用了两个“数据库”:

  1. vector_db:Chroma,用来高效做相似度搜索;
  2. contents_db:SQLite,用来存每一条知识的原始文本内容。
你可以把它想象成:
  • Chroma 是“目录卡片 + 文本特征”;
  • SQLite 是“真正的书本内容”;
  • Knowledge 是那位熟悉图书馆结构的管理员,帮你统一操作。

代码中的两个典型操作

  1. 添加知识add_content):
for i, text in enumerate(sample_texts):
    knowledge_base.add_content(text_content=text)

背后流程大致是:

  • 调用 embedder → 文本转向量;
  • 向量写入 Chroma;
  • 文本写入 SQLite;
  • 建立 ID 关联。

  1. 搜索知识search):

search_results = knowledge_base.search("编程语言", max_results=2)
for doc in search_results:
    print(doc.content[:100], "...")

背后流程大致是:

  • 把查询 "编程语言" 做嵌入 → 得到查询向量;
  • 在 Chroma 中做近邻搜索 → 找最相近的几条向量;
  • 根据 ID 从 SQLite 拉回原始文本;
  • doc 的形式返回给你。


🤖 DeepSeek 聊天模型:给系统安上“嘴”和“脑子”

前面我们解决的是“记忆”和“检索”,现在需要一个会说话、会推理的主体,这里用的是 DeepSeek 聊天模型:

from agno.models.deepseek import DeepSeek

def create_agent():
    api_key = os.getenv("DEEPSEEK_API_KEY") or os.getenv("OPENAI_API_KEY")
    
    model = DeepSeek(
        id="deepseek-chat",
        api_key=api_key,
    )
    
    return model

这里的逻辑:

  • 优先从环境变量中拿 DEEPSEEK_API_KEY
  • 如果没有,就尝试 OPENAI_API_KEY(兼容某些代理/转发场景);
  • 拿不到的话照样创建模型,只是可能会在请求时失败。
你可以理解为: “记忆系统”是本地搭的; “思考和回答”的大脑则是云端的 DeepSeek LLM。

🧠 Agent:当大脑学会“先查资料,再开口”

1. 组装 Agent

agent = Agent(
    model=model,
    knowledge=knowledge_base,
    instructions="你是一个知识专家,可以基于提供的知识库回答问题。",
)

这里,Agent 扮演的角色就是:

  • 收到一个用户问题;
  • 先去知识库里检索相关内容;
  • 再把这些内容 + 问题,一起丢给 DeepSeek 模型;
  • 用 prompt 里的角色设定引导模型:“你是知识专家,要基于提供的知识库回答”。
这就从“裸 LLM”升级为“有记忆 + 有资料”的专家型助手。

2. 使用 Agent 回答问题

agent.print_response("请介绍一下 Python 的历史。")

按理想路径,底层流程大致是:

  1. 对问题做嵌入,去 knowledge_base 搜索相关文本;
  2. 把检索到的一两段关于 Python 的说明作为“上下文”;
  3. 再把这些上下文 + 原问题,丢给 DeepSeek;
  4. DeepSeek 结合上下文生成一段更流畅、结构化的中文回答;
  5. print_response 负责把这段回答打印出来。
注解 这就是典型的 RAG(Retrieval-Augmented Generation,检索增强生成)模式: 模型不再“凭空想象”,而是先去你专门指定的知识库查资料,再组织回答。

🔍 直接搜索:验证知识库是否“记住了东西”

最后一段是直接对知识库做检索:

search_results = knowledge_base.search("编程语言", max_results=2)
print(f"找到 {len(search_results)} 条相关结果:")
for i, doc in enumerate(search_results):
    print(f"{i+1}. {doc.content[:100]}...")

在前面添加的示例文本中,有三条:

  • Python 是一种高级编程语言…
  • JavaScript 是一种脚本语言…
  • 机器学习是人工智能的一个分支…
用“编程语言”搜索,很大概率会把前两条捞出来。这是一个非常直观的自测: 向量检索有没有工作?中文/中英混合检索效果怎样?

🛠 可以考虑的改进与拓展

这段脚本已经是一个完整、可跑的小 demo,不过从“科研工程师”的角度看,可以扩展的地方还有不少:

1. 更完善的错误处理与日志

现在大部分错误是 print 一行,然后 return None。在真实系统里可以:

  • 区分“致命错误”(比如向量库不可写)和“可恢复错误”(比如某条内容失败);
  • 使用 logging 模块,打 INFO / WARNING / ERROR 级别日志;
  • 对知识添加失败时,记录文本 ID,方便后续重试。

2. 更适合中文的嵌入模型

all-MiniLM-L6-v2 虽然也能处理中文,但不是专门为中文设计。
对于中文知识库,可以考虑:

  • sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2(多语言);
  • 或本地的中文专用 Embedding 模型(如 bge-m3/bge-large-zh 等,视 Agno 支持情况)。
只要同步修改:
id="xxx-模型名",
dimensions=向量维度,

即可。

3. 知识分片与元数据

当前示例用的是“几句话直接当一条内容”。现实中:

  • 文档往往很长,需要按段落/小节切分成多条;
  • 每条内容需要额外的 metadata:来源文件名、章节、时间戳等;
  • 搜索时可以按 metadata 过滤,比如只查“某个项目的文档”、“某个时间之后的内容”。
如果 Agno 的 add_content 支持 metadata,可以这样扩展:
knowledge_base.add_content(
    text_content=text,
    metadata={"source": "demo", "topic": "programming"}
)

4. Agent 的指令(instructions)可以更精细

现在的 instructions 很简单:

instructions="你是一个知识专家,可以基于提供的知识库回答问题。"

可以更具体一些,例如:

  • 优先引用知识库内容,如无相关内容要明确说明“知识库中暂无此信息”;
  • 回答时用分点说明,标明知识来源;
  • 避免超出知识库范围的主观猜测。