CMDC.Provider (cmdc v0.5.1)

Copy Markdown View Source

req_llm 的薄封装层,负责发起流式 LLM 请求。

CMDC 不自建 Provider 体系,而是直接依赖 req_llm(18 个 Provider 开箱即用), 本模块只做:

  1. CMDC.Message 列表转为 req_llm Context 格式
  2. CMDC.Tool 模块列表转为 req_llm tool schema
  3. 调用 ReqLLM.stream_text/3 发起流式请求
  4. 启动 CMDC.Provider.StreamBridge 将流式 chunk 转为 gen_statem 消息

流式消息协议(StreamBridge → Agent)

消息含义
{:cmdc_stream_chunk, StreamChunk.t()}流式数据块(文本/推理/工具调用/元数据)
:cmdc_stream_done流正常结束
{:cmdc_stream_error, reason}流出错

使用示例

{:ok, %{bridge_pid: _pid}} = CMDC.Provider.stream(
  "anthropic:claude-sonnet-4-5",
  messages,
  tools,
  agent_pid: self(),
  api_key: "sk-...",
  system_prompt: "你是一个专业助手。"
)

已知约束

使用自定义 base_url 时,必须同时在 model map 和 opts 里传 base_url。 原因:req_llm 的 OpenAI provider 流式路径从 opts[:base_url] 读取, 而非从 model struct 读取。若只传 model map,会 fallback 到默认 OpenAI 地址。

Summary

Functions

将工具模块列表转为 req_llm tool schema 格式。

发起流式 LLM 请求,在独立进程中消费 StreamResponse 并推送给 Agent。

Types

model()

@type model() :: String.t() | map()

Functions

convert_messages(messages, provider \\ :openai)

@spec convert_messages([CMDC.Message.t()], atom()) :: [ReqLLM.Message.t()]

CMDC.Message 列表转为 ReqLLM.Message struct 列表。

根据 provider 类型自动切换消息格式。

convert_tools(tools)

@spec convert_tools([module()]) :: [map()]

将工具模块列表转为 req_llm tool schema 格式。

stream(model, messages, tools, opts \\ [])

@spec stream(model(), [CMDC.Message.t()], [module()], keyword()) ::
  {:ok, %{bridge_pid: pid()}} | {:error, term()}

发起流式 LLM 请求,在独立进程中消费 StreamResponse 并推送给 Agent。

参数

  • model — 模型标识("anthropic:claude-sonnet-4-5" 或 map)
  • messagesCMDC.Message.t() 列表
  • tools — 工具模块列表(实现 CMDC.Tool behaviour)
  • opts — 选项
    • :agent_pid(必需)— 接收流式消息的 gen_statem 进程
    • :system_prompt — 系统提示词
    • :temperature — 温度参数
    • :max_tokens — 最大生成 token 数
    • :api_key — API Key(覆盖环境变量)
    • :base_url — 自定义 API base URL
    • :receive_timeout — 接收超时毫秒数

返回

  • {:ok, %{bridge_pid: pid()}} — StreamBridge 进程已启动
  • {:error, reason} — 请求失败