官方的文档如下
https://docs.crewai.com/concepts/knowledge
但是不知道为什么,可能是版本的问题(我用的是0.86.0),参考官方文档的配置我会报错,并且也导入不了数据库,也可能用的不是官方API。本文以常用的csv
,json
,pdf
作为知识库进行举例
重点:下面的代码是基于0.83.0版本的!!!最新版本(0.108.0)框架的配置可以移步文章底部
使用csv文件作为数据源 def csv_knowledge_source (): os.environ["CREWAI_STORAGE_DIR" ] = "vector_store_csv" current_dir = Path(__file__).parent csv_path = current_dir / "files/high_school_scores.csv" if not csv_path.exists(): raise FileNotFoundError(f"CSV file not found at {csv_path} " ) csv_source = CSVKnowledgeSource( file_path=csv_path, metadata={"preference" : "score" } ) openai_api_base = os.getenv("OPENAI_API_BASE" ) openai_api_key = os.getenv("OPENAI_API_KEY" ) if not openai_api_base or not openai_api_key: raise ValueError("OPENAI_API_BASE or OPENAI_API_KEY not set." ) agent = Agent( role="高中老师" , goal="你了解学生的所有成绩" , backstory="你经常关注学生的成绩" , verbose=True , ) task = Task( description="使用知识库中的信息回答有关学生成绩的问题: {question}" , expected_output="基于知识库数据的解答:" , agent=agent, ) crew = Crew( agents=[agent], tasks=[task], verbose=True , process=Process.sequential, knowledge={ "sources" : [csv_source], } ) try : result = crew.kickoff(inputs={"question" : "孙七的语文成绩是多少" }) print (result) except Exception as e: print (f"An error occurred: {e} " )
high_school_scores.csv
文件
学生姓名,语文成绩,数学成绩,英语成绩 张三,63,137,66 李四,82,98,83 王五,66,50,96 赵六,57,109,145 孙七,136,121,147
使用json
文件作为数据源 def json_knowledge_source (): os.environ["CREWAI_STORAGE_DIR" ] = "vector_store_json" current_dir = Path(__file__).parent json_path = current_dir / "files/high_school_scores.json" json_source = JSONKnowledgeSource( file_path=json_path, metadata={"preference" : "personal" } ) agent = Agent( role="高中老师" , goal="你了解学生的所有成绩" , backstory="""你经常关注学生的成绩""" , verbose=True , ) task = Task( description="使用知识库中的信息回答有关学生成绩的问题: {question}" , expected_output="基于知识库数据的解答:" , agent=agent, ) crew = Crew( agents=[agent], tasks=[task], verbose=True , process=Process.sequential, knowledge={ "sources" : [json_source], "metadata" : {"preference" : "personal" }, } ) crew.kickoff(inputs={"question" : "孙七的语文成绩是多少" })
high_school_scores.json
[ { "姓名": "张三", "语文": 63, "数学": 137, "英语": 66 }, { "姓名": "李四", "语文": 82, "数学": 98, "英语": 83 }, { "姓名": "王五", "语文": 66, "数学": 50, "英语": 96 }, { "姓名": "赵六", "语文": 57, "数学": 109, "英语": 145 }, { "姓名": "孙七", "语文": 136, "数学": 121, "英语": 147 } ]
使用pdf文件作为数据源 def pdf_knowledge_source (): os.environ["CREWAI_STORAGE_DIR" ] = "vector_store_pdf" current_dir = Path(__file__).parent pdf_path = current_dir / "files/人物介绍.pdf" pdf_source = PDFKnowledgeSource( file_path=pdf_path, metadata={"preference" : "personal" } ) agent = Agent( role="About User" , goal="你了解文档的一切。" , backstory="""你是一个回答文档内容的高手。""" , verbose=True ) task = Task( description="回答有关用户的问题: {question}" , expected_output="解答问题。" , agent=agent, ) crew = Crew( agents=[agent], tasks=[task], verbose=True , process=Process.sequential, knowledge={ "sources" : [pdf_source], "metadata" : {"preference" : "personal" }, } ) crew.kickoff(inputs={"question" : "张三的基本信息?" })
人物介绍.pdf
张三,35 岁,是一位在科技领域崭露头角的软件工程师。他毕业于国内顶尖学府的计算机科学专业,凭借扎实的专业知识和对技术的热爱,在行业内积累了丰富的经验。 张三性格沉稳且富有创造力,面对复杂的技术难题,总能冷静分析,找到创新的解决方案。工作之余,他还是个户外运动爱好者,经常参与登山、骑行活动,这不仅锻炼了他的体魄,也培养了他坚韧不拔的毅力。在团队合作中,张三善于倾听他人意见,凭借出色的沟通能力,总能高效地协调团队成员,推动项目顺利进行。无论是工作还是生活,他都以积极的态度影响着身边的人,是大家眼中的榜样。
参考资料:
https://www.bilibili.com/video/BV1jPBfYfE8C
2.20 补充 向量数据库的本地存储位置,Win系统的在这里
C:\Users\用户名\AppData\Local\CrewAI
快速浏览:
Win+R,然后粘贴
explorer.exe C:\Users\%USERNAME%\AppData\Local\CrewAI
如果使用的版本是0.86.0的,将会出现如下错误,暂时还不知道是什么原因。并且目前还不可以使用自定义的embedding
层。借此博文,也希望抛砖引玉一下,求助怎么解决上述问题~
看到一个Issue里是这么写的,备份一下
crew = Crew( tasks=[task], process=Process.sequential, verbose=True , knowledge_sources: [ PDFKnowledgeSource( file_paths=[local_path], chunk_size=1000 , chunk_overlap=100 , metadata={ 'source' : 'Informações sobre a clínica' , 'description' : 'Documento com processos e procedimentos da clínica' } ) ], embedder={ "provider" : "openai" , "config" : { "model" : "text-embedding-3-small" , "dimensions" : 256 } } )
3.20 补充 更新到了最新的crewai 0.108.0版本
使用如下的配置可以正常使用知识库和自定义embedder
划重点!!!!!!!正确的写法是knowledge_sources
而不是knowledge_source
,否则不会进行数据向量化,而且还不报错,智能体还调用不了这个知识库,这个卡了我一天!!!
from crewai import Agent, Crew, Process, Taskfrom crewai.project import CrewBase, agent, crew, taskfrom crewai.knowledge.source.json_knowledge_source import JSONKnowledgeSourcefrom dotenv import load_dotenvimport osload_dotenv() @CrewBase class SimpleKnowledgeExample : """SimpleKnowledgeExample crew""" agents_config = "config/agents.yaml" tasks_config = "config/tasks.yaml" json_knowledge_source = JSONKnowledgeSource( file_paths=["lorenze.json" , "random.json" ] ) @agent def researcher (self ) -> Agent: return Agent(config=self.agents_config["researcher" ], verbose=True ) @task def research_task (self ) -> Task: return Task( config=self.tasks_config["research_task" ], ) @crew def crew (self ) -> Crew: """Creates the SimpleKnowledgeExample crew""" return Crew( agents=self.agents, tasks=self.tasks, process=Process.sequential, verbose=True , knowledge_sources=[self.json_knowledge_source], embedder={ "provider" : "ollama" , "config" : { "model" : "nomic-embed-text:latest" , "api_base" : "http://localhost:11434" , } } )
文件目录如下:
效果如下:
后台日志也显示用到了自己的embedder
但是还有bug,不能使用命令清除knowledge,需要从本地自己删除(目录见上文)
此外,传入的路径也可以使用相对路径,knowledge也不用局限于图中的位置
current_dir = Path(__file__).parent parent_dir = current_dir.parent.parent random_path = parent_dir / "my_knowledge/random.json" lorenze_path = parent_dir / "my_knowledge/random.json" print (random_path, lorenze_path)json_knowledge_source = JSONKnowledgeSource( file_paths=[random_path, lorenze_path] )
可以把knowledge放在项目根目录,文件夹也不限于knowledge
这个名称(比如改成my_knowledge)
3.24 补充 数据集不支持中文 看GitHub的ISSUE #2454 里应该是一个Bug,数据集的名称目前不支持中文,会生成knowledge但是不会查询到里面的信息
数据集里有中文内容不会影响
Agent里面的Role内容也不能为中文 而goal和backstory可以为中文,不会影响程序正常运行
附部分源码:
def set_knowledge (self, crew_embedder: Optional [Dict [str , Any ]] = None ): try : if self.embedder is None and crew_embedder: self.embedder = crew_embedder if self.knowledge_sources: full_pattern = re.compile (r"[^a-zA-Z0-9\-_\r\n]|(\.\.)" ) knowledge_agent_name = f"{re.sub(full_pattern, '_' , self.role)} " if isinstance (self.knowledge_sources, list ) and all ( isinstance (k, BaseKnowledgeSource) for k in self.knowledge_sources ): self.knowledge = Knowledge( sources=self.knowledge_sources, embedder=self.embedder, collection_name=knowledge_agent_name, storage=self.knowledge_storage or None , ) except (TypeError, ValueError) as e: raise ValueError(f"Invalid Knowledge Configuration: {str (e)} " )