上周,我正面对一个让人头疼的问题。我有一大堆散落在不同文件夹里的项目文档——PDF、markdown 文件、各种随手记的文本笔记——我急需一个能真正和它们“对话”的办法。用 grep 或者系统自带的搜索根本行不通,因为我需要的是基于概念的理解和回答,而不是简单的关键词匹配。我之前听说过 Agno,一个用来构建 AI 智能体(Agent)的框架,特别是它能用极少的样板代码快速搭起一个具备知识库能力的 Agent。我决定试一把,说实话,从零开始到手头跑通一个能用的原型,速度之快连我自己都没想到。
这是我基于亲身实践整理的 Agno 入门指南,包括我踩过的一些坑。
环境准备:把场子先搭起来
首先,搞定环境配置。我用的是 Mac,现在管理 Python 环境我都改用 uv 了,因为它比标准的 venv 流程快得不是一星半点。
我建了一个新项目文件夹,然后跑了:
uv venv --python 3.12
source .venv/bin/activate
如果你用的是 Windows,激活命令得换成 .venv\Scripts\activate。
接下来安装依赖。这里我遇到了第一个小意外。Agno 是模块化设计的,所以你不需要一把梭全装上,只需安装核心框架,再加上你需要的特定集成就行。因为我想用 Google 的 Gemini 模型,外加 ChromaDB 作为向量数据库,所以我的安装命令长这样:
uv pip install -U agno chromadb google-genai
这一下就把需要的东西全拉下来了,干净利落。
最后一步设置是配置 Google API 密钥。如果你还没有,可以去 Google AI Studio 搞一个。
export GOOGLE_API_KEY=your-google-api-key
在 Windows PowerShell 里,对应的命令是 $env:GOOGLE_API_KEY = "your-google-api-key"。
构建知识库 Agent
接下来到了好玩的环节。我建了个叫 knowledge_agent.py 的文件。我的目标很简单:把文档加载到向量数据库里,把数据库挂到 Agent 上,然后向它提问。
我一开始写的代码是这样的:
from agno.agent import Agent
from agno.knowledge.embedder.google import GeminiEmbedder
from agno.knowledge.knowledge import Knowledge
from agno.models.google import Gemini
from agno.vectordb.chroma import ChromaDb
from agno.vectordb.search import SearchType
# Create a knowledge base with ChromaDB
knowledge = Knowledge(
vector_db=ChromaDb(
collection="docs",
path="tmp/chromadb",
persistent_client=True,
search_type=SearchType.hybrid,
embedder=GeminiEmbedder(id="gemini-embedding-001"),
),
)
# Load content into the knowledge base
knowledge.insert(
url="https://docs.agno.com/introduction.md",
skip_if_exists=True,
)
# Create an agent that searches the knowledge base
agent = Agent(
model=Gemini(id="gemini-2.0-flash"),
knowledge=knowledge,
search_knowledge=True,
markdown=True,
)
agent.print_response("What is Agno?", stream=True)
我来带你理一理这里面的逻辑,因为一旦你看懂了,就会发现它的架构设计其实相当优雅。
Knowledge 对象 就像是大脑的记忆区。它封装了一个向量数据库(在这个例子里是 ChromaDB)和一个嵌入器(embedder)。当我调用 knowledge.insert() 时,Agno 会把内容切分成小块,把这些小块送进 Gemini 嵌入器生成向量表示,然后存进 ChromaDB。
我设置了 persistent_client=True 并指定了路径(tmp/chromadb),这意味着向量数据会持久化保存在硬盘上。这是个令人惊喜的发现:我不用每次重启脚本都重新把文档做一次向量化了。插入调用时的 skip_if_exists=True 参数更是锦上添花——它会在重新处理前先检查这个 URL 的内容是不是已经在数据库里了。
SearchType.hybrid 这个设置值得单独拿出来说说。混合搜索(hybrid search)把关键词匹配和语义向量搜索结合在了一起,可以说是两全其美。你既能精准命中包含确切术语的内容,也能找到概念上相近的东西。我发现这对回答质量的影响是实打实的,尤其是当用户提问用的词跟文档里原本的表述不一样的时候。
Agent 对象 则是总指挥。我给它配了个 Gemini 模型,挂载了知识库,并设置了 search_knowledge=True。最后这个参数非常关键——它告诉 Agent 在回答问题时应该去查阅知识库,而不是只靠自己训练数据里的老本。我还开启了 markdown=True,这样返回的回答格式会很好看。
运行脚本:
python knowledge_agent.py
Agent 搜索了知识库,从 Agno 介绍文档里找到了相关的文本块,然后给了我一个扎实且有凭有据的回答,解释了 Agno 是什么。它还是一个 token 接着一个 token 流式输出的,体验非常丝滑、有互动感。
加载你自己的内容
上面的例子只加载了一个 URL,但真实项目可不止这点东西。这时候 Agno 的灵活性就体现出来了。knowledge.insert() 方法能自动处理多种内容类型:
# 加载 PDF 文件
knowledge.insert(path="docs/product-guide.pdf")
# 加载整个目录的文件
knowledge.insert(path="data/")
# 从 URL 加载 PDF
knowledge.insert(url="https://example.com/docs.pdf")
# 直接加载原始文本
knowledge.insert(text_content="Your content here...")
Agno 会自动检测文件类型,并在后台调用合适的读取器。PDF、DOCX、CSV、Markdown——它都能搞定,完全不需要你手动指定解析器或者配置提取逻辑。当我把一个混杂着各种文件类型的目录扔给它时,它直接就跑通了。这可给我省了大把时间,不然我得写一堆文件类型检测和解析的代码。
幕后到底发生了什么
搞懂背后的流程帮我后来省了不少调试的麻烦,所以这里给你讲个简化版:
- 插入阶段:内容被切分,通过 Gemini 生成向量,然后带着元数据一起存入 ChromaDB。
- 查询阶段:当你提问时,Agent 会决定是否要搜索知识库(因为设了
search_knowledge=True),接着把你的问题向量化,在 ChromaDB 里跑一次混合搜索,召回最相关的文本块,最后把这些块作为上下文喂给大模型,让它生成最终答案。
Agent 会自己判断要不要去搜索。如果你问“2+2等于几?”,它可能压根不去碰知识库;但如果你问“我们的退款政策是什么?”,它就会触发搜索。这可比无脑把上下文塞进每次调用里聪明多了。
我踩过的坑和学到的教训
坑 1:忘了配 API 密钥。 我写完整个脚本,兴奋地一跑,立马撞上认证错误。虽然有点丢人,但修起来很简单。一定要确保运行脚本的那个终端会话里已经 export 了密钥。
坑 2:一开始没用持久化存储。 我的初版没设 persistent_client=True,也没指定路径。结果每次运行都要从头把所有东西重新向量化一遍。如果只有一个 markdown 文件倒还好,但如果是 50 个 PDF 的目录,那纯粹是浪费时间费 API 调用额度。听我的,一开始就把持久化配好。
坑 3:用错了模型 ID。 我一开始照着某段示例代码用了 gemini-3.5-flash,但我的账号等级根本没开放这个模型。换成 gemini-2.0-flash 马上就好了。动手写代码前,先查查你的 API key 到底支持哪些模型。
实用建议与诚实的局限性
建议:
- 先拿一小批文档试试水,确认整个流水线跑通了,再往里灌几个 G 的数据。
- 把
skip_if_exists=True当成信仰。它能防止生成重复的向量,帮你省下宝贵的 API 额度。 - 对于文档问答场景,混合搜索(
SearchType.hybrid)几乎总是比纯向量搜索效果更好。直接把它当默认选项就行。 tmp/chromadb这个路径拿来实验没问题,但上生产环境时记得换成一个正规的数据目录。
局限性:
- ChromaDB 拿来做本地开发、跑中小型数据集很香,但要是应对大规模的生产环境部署,它就不是最佳选择了。Agno 也支持其他的向量数据库(比如 PgVector、Pinecone、Qdrant),所以规模上去后记得做迁移。
- 自动分块(chunking)对常规文档效果不错,但如果你有高度结构化的内容(比如表格或代码),可能就需要自定义分块策略才能达到最佳效果。
- Agent 关于什么时候去搜知识库的判断并不完美。有时候会多此一举地去搜,有时候又该查文档时试图用训练数据硬编。你可以调优这个行为,但需要反复试验。
Agno 让我在不到一小时内,就从“面对一堆文档发愁”变成了“跑通了一个能用的文档问答 Agent”,而且这大部分时间还是在看文档和改我自己手滑打错的字。这个框架帮你把向量化、向量存储和检索这些脏活累活都干得漂漂亮亮的,绝不碍事。如果你也想搞点基于知识库的工具,又不想在基础设施代码里淹死,Agno 绝对值得你花点时间试试。