CMDC

Production-grade AI Agent kernel for Elixir.

用 OTP 把 Agent 跑成生产服务 — Crash-safe · Observable · Multi-tenant by design.

[![Hex.pm](https://img.shields.io/hexpm/v/cmdc.svg)](https://hex.pm/packages/cmdc) [![Docs](https://img.shields.io/badge/docs-hexdocs-blue.svg)](https://hexdocs.pm/cmdc) [![License](https://img.shields.io/badge/License-Apache%202.0%20with%20Commons%20Clause-blue.svg)](LICENSE) [![Tests](https://img.shields.io/badge/tests-1219%20%2B%2021%20doctests-brightgreen.svg)]() [![Warnings](https://img.shields.io/badge/warnings-0-brightgreen.svg)]()

为什么是 CMDC

把 Agent 推到生产环境会立刻撞上三堵墙:一个子任务挂了整个会话陪葬 / LLM 在你看不见的地方烧 token / 想做前端断网重连或跨设备恢复但框架根本不支持

CMDC 把每个会话当作一棵 OTP Supervisor 树跑在 BEAM 上,从内核就把这些问题 解决了:


主要能力

按部署关注点分组:

Runtime — OTP 容错与并发

Observability — 可观测性

Safety — 安全与合规

Cost & Performance — 成本与性能

Memory & Recovery — 记忆与恢复

Plugin Pipeline — 13 hook × 8 action

13 个生命周期 hook(session / prompt / request / response / tool / compact / steering / turn)× 8 种 action(continue / intervene / abort / skip / block_tool / replace_args / replace_result / switch_model)。 16 个内置 Plugin 覆盖审批 / 安全 / 内容拦截 / 长会话记忆 / 模型路由 / 大结果 offload / 反思 / 规划等典型场景。


安装

def deps do
  [
    {:cmdc, "~> 0.4"}
  ]
end

可选生态库:

{:cmdc_gateway, "~> 0.4"},       # HTTP / SSE / WebSocket / A2A 网关
{:cmdc_orchestrator, "~> 0.3"},  # DAG / Debate / Hierarchy / Router-LLM
{:cmdc_skill_engine, "~> 0.2"}   # Skill 自进化引擎

30 秒上手

{:ok, session} = CMDC.create_agent(
  model: "anthropic:claude-sonnet-4-5",
  api_key: System.get_env("ANTHROPIC_API_KEY")
)

CMDC.prompt(session, "用一句话介绍 Elixir 的优势。")
{:ok, reply} = CMDC.collect_reply(session)
IO.puts(reply)

CMDC.stop(session)

完整指南:5 分钟上手 / 核心概念 / 10 个生产配方


生产部署模式

defmodule MyApp.SupportAgent do
  @behaviour CMDC.Blueprint

  def build(opts) do
    %CMDC.Options{
      model: "anthropic:claude-sonnet-4-5",
      working_dir: "/tmp/support/#{opts[:tenant_id]}",
      user_data: %{tenant_id: opts[:tenant_id], user_tier: opts[:user_tier]},

      # 多 backend 路由:sandbox + 长期记忆 + 短期 ETS
      backend: CMDC.Backend.Composite.new(
        default: CMDC.Backend.Filesystem.new(
          root_dir: "/tmp/support/#{opts[:tenant_id]}",
          virtual_mode: true              # 防 traversal
        ),
        routes: %{
          "/memories/" => MyApp.PgBackend.new(),
          "/conversation_history/" => CMDC.Backend.State.new()
        }
      ),

      tools: [MyApp.QueryDB, MyApp.RefundOrder, CMDC.Tool.AskUser],

      plugins: [
        # 安全
        {CMDC.Plugin.Builtin.HumanApproval, tools: ["refund_order"]},
        {CMDC.Plugin.Builtin.ContentPolicy, []},

        # 成本
        {CMDC.Plugin.Builtin.CostGuard, max_usd: 0.50},
        {CMDC.Plugin.Builtin.ModelRouter, [
          rules: [
            %{condition: {:user_tier, :free}, model: "openai:gpt-4o-mini"},
            %{condition: {:cost_gt, 0.10}, model: "openai:gpt-4o-mini"}
          ]
        ]},

        # 大结果落盘
        {CMDC.Plugin.Builtin.LargeResultOffload, [
          backend: opts[:backend],
          tool_token_limit_before_evict: 20_000
        ]}
      ],

      # 上下文压缩 + 重连补帧
      compactor: [trigger: {:tokens, 50_000}, keep: {:messages, 10}],
      event_buffer_size: 200
    }
  end
end

{:ok, session} = CMDC.create_agent(MyApp.SupportAgent,
  tenant_id: "acme",
  user_tier: :pro
)

# 接 Langfuse 可观测
:telemetry.attach_many("cmdc-langfuse",
  CMDC.Telemetry.all_events(),
  &MyApp.LangfuseSink.handle_event/4, [])

# 业务订阅事件流
CMDC.subscribe(session)
CMDC.monitor(session)

FAQ

为什么用 Elixir / BEAM 跑 Agent

LLM Agent 的本质是长期运行的并发状态机:每个会话独立、可崩可重启、需要 被持续观察、要能在多租户场景下互不干扰。这恰好是 BEAM 三十年来的本职工作—— WhatsApp 用 Erlang 单机扛 200 万并发连接,Discord 用 Elixir 处理千万级实时消息。 把 LLM Agent 跑在 BEAM 上不是花活,是让 Agent 享受电信级容错和并发的免费午餐

是否绑死 LLM 厂商

不。Provider 层基于 req_llm 封装,支持 Anthropic / OpenAI / Google / Mistral / Bedrock / 自建网关 / 任意 OpenAI 兼容 endpoint。switch_model/2 支持运行期热切(含 provider_opts 同步切换 base_url / api_key)。

生产可靠性证据

跟 Python Agent 框架的差别

不写对比表(写了也没意思),列三个只有 BEAM 才便宜实现的能力让你自己判断:

  1. 子代理 crash 不传染父代理——DynamicSupervisor 默认行为,零代码
  2. 跨进程跨节点会话恢复——CMDC.Checkpoint + 任意分布式 backend 即可
  3. 单机数万 Agent 进程并发——OTP 调度天然支持,无需额外协程框架

与 Langfuse / LangSmith 集成需要写多少代码

零侵入。CMDC 只发 :telemetry 标准事件,sink 由你按需挂:

:telemetry.attach_many("my-langfuse", CMDC.Telemetry.all_events(),
  &MyApp.LangfuseSink.handle_event/4, [])

3 份完整配方(Langfuse OTLP / LangSmith OTel / Grafana Tempo + Loki)见 常见配方


数字

指标 v0.4.1
Tests 1219 + 21 doctests, 0 failures
编译 warnings 0
Hex doc warnings 0
内置 Plugin 16
内置 Tool 11
Plugin Pipeline 13 hook × 8 action
生态 Hex 包 4(cmdc / cmdc_gateway / cmdc_orchestrator / cmdc_skill_engine)
主库代码 ~12K 行(不含测试)

文档


开发

mix deps.get
mix compile --warnings-as-errors
mix test
mix format --check-formatted
mix credo --strict
mix docs

跑真实 LLM 端到端示例(需 ANTHROPIC_API_KEY 等环境变量):

cd example && mix run example/simple_agent.exs

License

Apache 2.0 with Commons Clause。商用授权请联系 glggsai@qq.com