CrewAI框架添加知识源

官方的文档如下

https://docs.crewai.com/concepts/knowledge

但是不知道为什么,可能是版本的问题(我用的是0.86.0),参考官方文档的配置我会报错,并且也导入不了数据库,也可能用的不是官方API。本文以常用的csvjsonpdf作为知识库进行举例

重点:下面的代码是基于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],
            # "embedder": {
            #     "provider": "openai",
            #     "api_base": openai_api_base,  # 移除了config层级
            #     "api_key": openai_api_key,
            #     "model": "text-embedding-3-small"
            # }
        }
    )

    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"},
            # "embedder_config": {
            #     "provider": "openai",
            #     "config": {"model": "text-embedding-3-small"}
            # }
        }
    )


    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层。借此博文,也希望抛砖引玉一下,求助怎么解决上述问题~
在这里插入图片描述

3.20 补充

更新到了最新的crewai 0.108.0版本
image-20250324104258312

使用如下的配置可以正常使用知识库和自定义embedder
划重点!!!!!!!正确的写法是knowledge_sources而不是knowledge_source,否则不会进行数据向量化,而且还不报错,智能体还调用不了这个知识库,这个卡了我一天!!!

from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.knowledge.source.json_knowledge_source import JSONKnowledgeSource
from dotenv import load_dotenv
import os

load_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_key": GEMINI_API_KEY,
                    "api_base": "http://localhost:11434",
                }
            }
            # embedder={
            #     "provider": "openai",
            #     "config": {
            #         "model": "text-embedding-3-small",
            #         "api_key": os.getenv("OPENAI_API_KEY"),
            #         "api_base": os.getenv("OPENAI_API_BASE"),
            #     }
            # }
        )

文件目录如下:

image-20250324104445601

效果如下:
image-20250324105257929

后台日志也显示用到了自己的embedder

image-20250324105340949

但是还有bug,不能使用命令清除knowledge,需要从本地自己删除(目录见上文)

image-20250324105037230
此外,传入的路径也可以使用相对路径,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)

image-20250324111706294

3.24 补充

数据集不支持中文

看GitHub的ISSUE #2454里应该是一个Bug,数据集的名称目前不支持中文,会生成knowledge但是不会查询到里面的信息

数据集里有中文内容不会影响

image-20250324175914218

Agent里面的Role内容也不能为中文

而goal和backstory可以为中文,不会影响程序正常运行

image-20250324181421337

附部分源码:

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)}")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Otto_1027

蟹蟹你,我会继续努力的~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值