在人工智能领域,知识库系统是构建智能代理的核心组件之一。
CrewAI 的记忆系统通过结合 RAG(Retrieval-Augmented Generation)技术和传统数据库存储,提供了一个全面且灵活的知识管理解决方案。
本文,带您一步一步探索使用 Crewai 进行知识库配置、向量数据库配置,进行文本、TXT、PDF 等多种文档知识库内容的驱动模式。
坐好了么?开车!
1、一些基础配置和特性
知识库的LLM 实例为了保证 输出和知识更加保守和一致,一般会把 temperature 设置为 0.
# 创建一个 LLM 实例,设置温度为 0 以确保输出的确定性
# temperature=0 意味着输出将更加保守和一致
llm = LLM(model="gpt-4o-mini", temperature=0)
在 Crew.ai 里配置知识库类型有以下几种:
StringKnowledgeSource
1-最简单的 StringKnowledgeSource,在指定的 string_content里配置对应的知识。相关代码如下:
from crewai import Agent, Task, Crew, Process, LLM
from crewai.knowledge.source.string\_knowledge\_source import StringKnowledgeSource
# 创建一个字符串类型的知识源
# StringKnowledgeSource 允许直接使用文本字符串作为知识库
content = "Users name is John. He is 30 years old and lives in San Francisco."
string\_source = StringKnowledgeSource(
content=content, # 传入知识内容
)
# 创建一个 LLM 实例,设置温度为 0 以确保输出的确定性
# temperature=0 意味着输出将更加保守和一致
llm = LLM(model="gpt-4o-mini", temperature=0)
测试一下,问题能正常回答了。但是,模型乱说话!John 住San Francisco,并不住纽约。先解决这个问题。
需要在 crew 配置哪里,增加embedding 模型。相关的配置如下:
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
knowledge\_sources=[string\_source,text\_source],
embedder={
"provider": "ollama",
"config": {
"model": "nomic-embed-text",
"host": "http://localhost:11434" # Ollama 默认地址
}
}
)
因为我用的是Ollama 本地化安装的 embedding 模型,配置的是本地的 host 地址。
如何在本地安装 embedding 模型,可以看这篇文章:
再测试一下:
可以的,知识库里配置的内容,已经能正常回答了。
2-如何解决胡说八道的问题?
问一问知识库里没有的其他问题,看一下效果。
开始胡说八道了(`へ´)!
如何约束和限制?在 Agent 的配置里直接增加约束。
agents.yaml 的修改
john:
role: >
用户信息专家
goal: >
准确回答关于用户的问题,仅基于已知信息。如果问题涉及未知信息,明确表示"这个信息在知识库中没有提供"。
backstory: >
你是一个严谨的信息专家,只依据知识库中明确提供的信息来回答问题。对于任何未在知识库中明确提供的信息,你会清楚地表示这些信息是未知的。
最后,看看效果,完美!
3-解决多次调整知识库内容的记忆错乱问题
当我多次调整知识库的内容,会发生什么变化呢?
我做了这些修改和调整:
1-把 John 的名字改成 Jerry;
2-职业和兴趣,都把 AI 改成了 IT。
3-居住地址、婚姻状态、宠物也都做了调整。
重新启动之后,再询问,发现了如下问题:
这个问题是因为 CrewAI 的向量数据库缓存导致。当我更新知识库文件时,之前的嵌入向量仍然保存在缓存中,没有自动更新。
怎么办?也很简单。
在向量数据库配置的代码后,添加 force_reload_knowledge=True 参数,这将强制 CrewAI 在每次运行时重新加载和嵌入知识库内容。这样可以确保每次运行都使用最新的知识库内容。
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
knowledge\_sources=[string\_source, file\_source],
embedder={
"provider": "ollama",
"config": {
"model": "nomic-embed-text",
"host": "http://localhost:11434"
}
},
force\_reload\_knowledge=True # 添加这行来强制重新加载知识库
)
哈哈哈哈,搞定了!
4-其他格式的知识库配置模式
Crew.AI 支持多种文件格式,包含TXT, PDF, DOCX, HTML等。相关的组件是 CrewDoclingSource,这是一个versatile的知识源。
这里分别把不同格式的知识库来源代码示例逐一贴出来:
导入txt 文件的知识
需要说明的是,我创建的 Crew 项目,单独为知识库文档创建了一个文件夹:
知识库内容配置如下:
对应的代码看这里:
from crewai.knowledge.source.text\_file\_knowledge\_source import TextFileKnowledgeSource #导入支持Txt格式的知识库配置
# 配置文件知识库
# 获取当前位置路径
current\_dir = Path(\_\_file\_\_).parent.parent.parent
# 指定到文件路径
file\_paths = current\_dir / "knowledge"/ "user\_preference.txt"
txt\_source = TextFileKnowledgeSource(
file\_paths =[file\_paths],
metadata={"preference": "personal"}
)
然后,在@Crew 里做如下修改,将原来的
knowledge_sources=[string_source] 改成 knowledge_sources=[txt_source]
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
knowledge\_sources=[txt\_source],
embedder={
"provider": "ollama",
"config": {
"model": "nomic-embed-text",
"host": "http://localhost:11434"
}
},
force\_reload\_knowledge=True
)
好滴,测试一下效果:
导入PDF 文件的知识
这个 PDF 文档的信息如下:
代码修改如下:
from crewai.knowledge.source.pdf\_knowledge\_source import PDFKnowledgeSource
# 配置文件知识库
# 指定到PDF文件路径
pdf\_file\_paths = current\_dir / "knowledge"/ "user\_preference\_lucy.pdf"
pdf\_source = PDFKnowledgeSource(
file\_paths=[pdf\_file\_paths],
metadata={"source": "personal"}
)
同样的@crew 也需要对应修改。
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
knowledge\_sources=[pdf\_source],
embedder={
"provider": "ollama",
"config": {
"model": "nomic-embed-text",
"host": "http://localhost:11434"
}
},
force\_reload\_knowledge=True
)
测试一下效果:
搞定了。
其他几种格式的知识库就不一一展开,大家可以修改对应的代码进行测试。代码如下:
导入 csv 格式的知识
# Create a CSV knowledge source
csv\_source = CSVKnowledgeSource(
file\_paths=["data.csv"]
# CSVKnowledgeSource 用于处理表格数据
# 适合处理结构化的数据集,如数据表、统计数据等
)
导入 excel 格式的知识
# Create an Excel knowledge source
excel\_source = ExcelKnowledgeSource(
file\_paths=["spreadsheet.xlsx"]
# ExcelKnowledgeSource 专门处理 Excel 文件
# 可以处理复杂的电子表格,包含多个工作表的文档
)
导入 json 格式的知识
# Create a JSON knowledge source
json\_source = JSONKnowledgeSource(
file\_paths=["data.json"]
# JSONKnowledgeSource 用于处理 JSON 格式的数据
# 适合处理结构化的配置文件或 API 响应数据
)
导入指定网页链接的知识
from crewai.knowledge.source.crew\_docling\_source import CrewDoclingSource
# 创建一个知识源,使用 CrewDoclingSource 来加载在线文档
# 这里加载了两篇关于 AI 的学术论文:reward hacking 和 hallucination
content\_source = CrewDoclingSource(
file\_paths=[
"https://lilianweng.github.io/posts/2024-11-28-reward-hacking",
"https://lilianweng.github.io/posts/2024-07-07-hallucination",
],
)