使用原生的Crewai框架

在自定义的工具llm_utils.py或是crew.py文件里如下配置(调用OpenAI)

from crewai import Agent, Crew, Process, Task, LLM
from crewai.project import CrewBase, agent, crew, task

llm = LLM(
base_url="https://xxxxxxx/v1",
api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
model="gpt-4o", # 本次使用的模型
# temperature=0.7, # 发散的程度
# timeout=None,# 服务请求超时
# max_retries=2,# 失败重试最大次数
)

@agent
def product_manager(self) -> agent:
return Agent(
config=self.agents_config["你配置的角色名(这不是重点)"],
llm=self.llm,
verbose=True,
)
# .................

main.py里做如下配置

os.environ["OPENAI_API_BASE"] = "https://xxxxxxx/v1"
os.environ["OPENAI_API_KEY"] = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
os.environ["OPENAI_MODEL_NAME"] = "gpt-4o"

因为litellm默认是调用OpenAI模型,若配置的是除OpenAI的其他模型(比如Claude),就要这样配置,在模型前面加上OpenAI,因为基本都兼容OpenAI的格式(注意,这是非官方的API,也包含国产大模型)

litellm支持的大语言模型如下

from crewai import Agent, Crew, Process, Task, LLM
from crewai.project import CrewBase, agent, crew, task

llm = LLM(
base_url="https://xxxxxxx/v1",
api_key="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
model="openai/claude-3-5-sonnet-20240620", # 一定在前面加上openai/
# temperature=0.7, # 发散的程度
# timeout=None,# 服务请求超时
# max_retries=2,# 失败重试最大次数
)

@agent
def product_manager(self) -> agent:
return Agent(
config=self.agents_config["你配置的角色名(这不是重点)"],
llm=self.llm,
verbose=True,
)
# .................

main.py里做如下配置

os.environ["ANTHROPIC_API_BASE"] = "https://xxxxxxx/v1"
os.environ["ANTHROPIC_API_KEY"] = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
os.environ["ANTHROPIC_API_MODEL"] = "openai/claude-3-5-sonnet-20240620"

分析原因

由于一开始看一个开源代码使用的是langchain+crewai结合的方法,我也模仿者作者编写我的项目,但是我没有发现一个问题,作者所用的是官方的key,所以自然不会出现什么问题。

而我使用的是一个国内中专api进行调用的方式,毕竟价格便宜好多,使用langchain配置大模型就出现了问题

# 错误配置,但是openai的可以正常使用
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
openai_api_key='sk-xxxxxxxxxxxxxxxxxxx'
base_url='https://xxxxxxxx/v1/',
model='gpt-4o-mini',
)

因为这样配置完以后,crewai是使用框架内自带的LiteLLM这个框架进行调用的,所以是兼容openai格式调用的,

所以chatGPT这系列是可以正常使用的。但是当调用其他模型(比如Claude)或者国产大模型的时候,就会出现报错了。因为langchain使用配置其他模型需要换成别的方式,而不是ChatOpenAI()方式,比如Claude(官方API)

from langchain_anthropic import ChatAnthropic
import getpass
import os

os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")
os.environ["LANGSMITH_TRACING"] = "true"

if "ANTHROPIC_API_KEY" not in os.environ:
os.environ["ANTHROPIC_API_KEY"] = getpass.getpass("Enter your Anthropic API key: ")


llm = ChatAnthropic(
model="claude-3-5-sonnet-20240620",
temperature=0,
max_tokens=1024,
timeout=None,
max_retries=2,
# other params...
)

而我继续使用ChatOpenAI()方式调用比如Claude,就会出现类似错误

litellm.exceptions.NotFoundError: litellm.NotFoundError: AnthropicException - {"error":{"message":"Invalid URL (POST /v1/v1/messages)","type":"invalid_request_error","param":"","code":""}}

或是调用国产大模型的时候

litellm.BadRequestError: LLM Provider NOT provided. Pass in the LLM provider you are trying to call

因为使用的是langchain框架的ChatOpenAI()方法去配置大模型,而crewai框架自带的LiteLLM框架就会使用OpenAI的方式去请求,而实际请求的缺不是OpenAI内的模型名称,可能导致litellm框架乱匹配其他模型的调用方法,而不采用OpenAI调用方法,就会出现各种奇奇怪怪的错误,所以要在模型前加上openai/这个字段

使用Langchain调用第三方大模型API

借鉴原生调用和上述分析,既然许多模型都支持OpenAI格式的调用,那么在模型前加上openai/便可以完成调用

from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://xxxxxxxxxxxx/v1", # 请求的API服务地址
api_key="sk-xxxxxxxxxxxxxxxxxxx", # API Key
model="openai/claude-3-5-sonnet-20240620",
# model="openai/doubao-lite-128k", 国产豆包模型
)

配置本地大模型

以Deepseek r1为例,不用配置key

from crewai import  LLM

llm = LLM(
base_url="http://localhost:11434/v1",
model="openai/deepseek-r1:8b" #模型名称必须和ollama中的模型名称一样
)

03ce076d-3e31-4075-8589-73b46cf09b7d

不知道为什么,按照官网文档,理论上应该写ollama/deepseek-r1:8b,但是就会报错,给我请求地址都变了,改为openai正没事了

image-20250205211704263

注:当前使用的版本

若版本不同可能会有出入

Framework Version
CrewAI 0.86.0
crewai-tools 0.25.8
LangChain 0.3.14

1.26 补充

可以把配置大模型的数据写在.env文件里(项目根目录),之后只修改这里面的文件就可以实现大模型配置的全局修改了

例如Claude的配置可以这样写

# Claude
ANTHROPIC_API_BASE="https://xxxxxxxx/v1"
ANTHROPIC_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ANTHROPIC_API_MODEL="openai/claude-3-5-sonnet-20240620"

之后如果要调用,可以这样

from crewai import  LLM
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()

# Claude3模型相关配置
ANTHROPIC_API_BASE = os.getenv("ANTHROPIC_API_BASE")
ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
ANTHROPIC_API_MODEL = os.getenv("ANTHROPIC_API_MODEL")

llm = LLM(
base_url=ANTHROPIC_API_BASE, # 请求的API服务地址
api_key=ANTHROPIC_API_KEY, # API Key
model=ANTHROPIC_API_MODEL,
# temperature=0.7,
# timeout=None,# 服务请求超时
# max_retries=2,# 失败重试最大次数
)