Skip to content

第 6 章 · LLM 配置详解与三方模型接入

本章目标:吃透 CrewAI 的模型配置体系——provider/model 命名规则、OpenAI 兼容端点的完整参数、结构化输出 response_format、drop_params 兼容性技巧,以及"按角色混用不同模型"的成本控制策略。

6.1 模型命名:provider/model 规则

CrewAI 通过 LLM 类统一接入所有模型,model 参数遵循 provider/model-id 格式:

python
from crewai import LLM

# 常见 provider 前缀(走 LiteLLM 路由)
llm_openai = LLM(model="openai/gpt-4o")
llm_claude = LLM(model="anthropic/claude-sonnet-4-6")
llm_gemini = LLM(model="gemini/gemini-2.0-flash")       # Google Gemini API
llm_local  = LLM(model="ollama/llama3:70b",
                 base_url="http://localhost:11434")      # 本地 Ollama

每个 provider 需要对应的环境变量密钥(OPENAI_API_KEYANTHROPIC_API_KEYGEMINI_API_KEY 等)。官方将 OpenAI / Anthropic / Google / Azure / Bedrock 等主流厂商做成了原生 SDK 集成,其余长尾 provider 由 LiteLLM 适配。

本课程约定:所有示例统一使用 OpenAI 兼容的三方端点(DeepSeek),这也是国内生产环境最常见的形态。

6.2 三方 OpenAI 兼容端点完整配置

python
import os
from crewai import LLM

deepseek = LLM(
    # openai/ 前缀表示"说 OpenAI 协议",后面接服务商的模型 id
    model="openai/deepseek-chat",
    base_url="https://api.deepseek.com/v1",     # 必须带 /v1
    api_key=os.getenv("DEEPSEEK_API_KEY"),

    # ---- 采样控制 ----
    temperature=0.7,     # 随机性:0 最确定,1 更发散
    top_p=0.9,           # 核采样阈值
    max_tokens=2000,     # 输出长度上限
    seed=42,             # 固定随机种子,便于结果复现
    stop=["END"],        # 自定义停止序列

    # ---- 行为控制 ----
    stream=False,        # 流式输出
    timeout=120.0,       # 请求超时(秒)
    max_retries=2,       # 请求级自动重试次数
)

常见坑:base_url 少 /v1

绝大多数 OpenAI 兼容网关把 chat/completions 挂在 /v1 下。漏写会得到 404;写多成 /v1/chat/completions 同样错误——CrewAI 会自己拼路径。

如果三方网关要求非 openai 的模型名前缀,CrewAI 1.x 还提供显式声明"这就是一个 OpenAI 协议端点"的写法:

python
gateway_llm = LLM(
    model="anthropic/claude-sonnet-4-6",        # 网关暴露的模型名
    custom_openai=True,                          # 强制按 OpenAI 协议调用
    base_url="https://your-gateway.example.com/v1",
    api_key="your-gateway-api-key",
)

6.3 结构化输出:response_format

让 LLM 直接返回可解析的对象,而不是靠正则去抠文本:

python
import os
from pydantic import BaseModel
from crewai import LLM

class Sentiment(BaseModel):
    label: str      # positive / negative / neutral
    score: float
    reason: str

judge = LLM(
    model="openai/deepseek-chat",
    base_url="https://api.deepseek.com/v1",
    api_key=os.getenv("DEEPSEEK_API_KEY"),
)

result = judge.call(
    "分析这条评论的情感:'物流很快,但包装破损了。'",
    response_format=Sentiment,
)
print(type(result))   # <class 'Sentiment'>
print(result.label)   # mixed / negative 等结构化字段

response_format 接收一个 Pydantic 模型,CrewAI 自动完成 schema 注入与解析校验。在 Task 层面还有更常用的 output_pydantic(第 12 章对比两者)。

6.4 drop_params:兼容性救生圈

不同三方实现支持的参数集合不一:有的不支持 stop,有的不支持 frequency_penalty。直接传会报错。两个开关解决:

python
compatible_llm = LLM(
    model="openai/deepseek-chat",
    base_url="https://api.deepseek.com/v1",
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    drop_params=True,                    # 自动丢弃目标端点不支持的参数
    additional_drop_params=["stop"],     # 显式追加要丢弃的参数黑名单
)
  • drop_params=True:LiteLLM 层自动过滤端点不认的参数;
  • additional_drop_params=[...]:手动指定额外丢弃项,用于绕过个别网关的伪兼容行为。

接新供应商时先开 drop_params=True,跑通后再逐步收敛参数,是排障效率最高的路径。

6.5 按角色混用模型:成本工程

生产 crew 里所有角色共用旗舰模型是最大的成本浪费。推荐的三级配置:

python
import os
from crewai import Agent, LLM

cheap = LLM(          # 干粗活:分类、抽取、格式转换
    model="openai/deepseek-chat",
    base_url="https://api.deepseek.com/v1",
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    temperature=0.1,
)
smart = LLM(          # 干细活:推理、写作、复杂决策
    model="openai/deepseek-reasoner",       # 深度思考模型
    base_url="https://api.deepseek.com/v1",
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    temperature=0.7,
)

classifier = Agent(role="工单分类员",
                   goal="把工单归入唯一类别并给出置信度",
                   backstory="严格按类别表分类。",
                   llm=cheap, max_iter=5)          # 简单任务用便宜模型+低温度

strategist = Agent(role="解决方案设计师",
                   goal="为疑难工单设计处理方案",
                   backstory="十年客服专家。",
                   llm=smart)                      # 复杂任务用强模型

配套原则:

  • 温度匹配任务:抽取/分类用 0–0.2,创作用 0.7+;
  • max_iter 匹配复杂度:简单任务顺手调低,防止空转;
  • 用第 5 章的 crew.usage_metrics 分别跑两种配置对比账单,用数据决定分级策略。

6.6 本章小结

  • model 一律写成 provider/model-id;OpenAI 兼容端点 = openai/ 前缀 + base_url(带 /v1)+ api_key
  • 关键采样参数:temperature/top_p/max_tokens/seed/stop;网络层有 timeout 与 max_retries;
  • response_format=Pydantic模型 让 LLM 直接吐出可校验对象;
  • drop_params=True + additional_drop_params 是对接三方网关的兼容性利器;
  • 成本优化三板斧:模型分级(chat/reasoner)、温度匹配任务、usage_metrics 度量闭环。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. model="openai/deepseek-chat" 中 openai/ 前缀的含义是?

2. 调用三方端点报 404,最先检查什么?

3. 某个三方网关不支持 stop 参数导致报错,最快的解决办法是?

4. 关于成本控制策略,不推荐的做法是?

🛠️ 动手实践

  1. 把你前几章写的 crew 全部迁移到环境变量化的 DeepSeek 配置上,抽出一个公共的 get_llms() 工厂函数返回 cheap/smart 两档。
  2. response_format 写一个情感判断脚本:对 5 条评论批量输出 Sentiment 对象列表并统计分布。
  3. 打开 stream=True 观察 verbose 日志的变化;再用 crew.usage_metrics 对比 deepseek-chat 与 deepseek-reasoner 跑同一任务的 token 开销。

模型层搞定了。下一章进入工具体系:给 agent 装上搜索、抓取等真实能力。