CMDC
Production-grade AI Agent kernel for Elixir.
用 OTP 把 Agent 跑成生产服务 — Crash-safe · Observable · Multi-tenant by design.
[](https://hex.pm/packages/cmdc) [](https://hexdocs.pm/cmdc) [](LICENSE) []() []()为什么是 CMDC
把 Agent 推到生产环境会立刻撞上三堵墙:一个子任务挂了整个会话陪葬 / LLM 在你看不见的地方烧 token / 想做前端断网重连或跨设备恢复但框架根本不支持。
CMDC 把每个会话当作一棵 OTP Supervisor 树跑在 BEAM 上,从内核就把这些问题 解决了:
- 进程级容错 — 每个 Agent / SubAgent 各自一个 OTP 进程,crash 不传染。 Supervisor 决定重启策略,BEAM 调度天然亿级并发。
- 可观测性内建 — 6 个标准
:telemetry事件零侵入接 Langfuse / LangSmith / Tempo / Datadog;50+ 种业务事件经EventBus广播给业务侧订阅。 - 多租户透传 —
Options.user_data :: map()经 Plugin / Tool / SubAgent 全链路透传,按user_id/tenant_id隔离记忆、计费、审批白名单。 - 会话快照 —
CMDC.Checkpoint一等公民 + Backend behaviour,BEAM 重启 / Gateway 滚动升级 / 用户跨设备恢复同一对话。 - 大规模工具结果 — 200KB+ 工具返回 0 token 占用,Plugin 自动 offload 到
backend,Agent 用
read_file(offset, limit)分页消费。 - A2A 协议全栈 —
cmdc_gateway同时支持 sync / SSE / webhook(HMAC 签名 + 指数退避)/ Agent Card 四种交互机制,>5 分钟长任务也不丢回调。
主要能力
按部署关注点分组:
Runtime — OTP 容错与并发
gen_statem4 状态机:idle / running / streaming / executing_tools-
Supervisor 树管理父代理 + 子代理 + DynamicSupervisor,按需
:rest_for_one CMDC.steer/2中段软中断(killable tools brutal_kill + queue 合并注入)CMDC.abort/24 状态行为表 + 100ms 内:agent_abort事件保证- 内建循环检测:文件编辑频率 / 重复调用模式 / 连续失败 三路自动 intervene
Observability — 可观测性
CMDC.Telemetry— 6 个标准:telemetry事件契约(agent.turn / llm.request / tool.exec start/stop),schema_version 锁定向后兼容CMDC.EventBus— 50+ 业务事件经{:cmdc_event, sid, event}广播CMDC.monitor/1— 结构化崩溃 reason 表::max_turns_exceeded / :provider_timeout / {:plugin_aborted, name, why}等EventBus.subscribe(sid, since: idx, types: [...])— 重连补帧
Safety — 安全与合规
HumanApproval— HITL 审批,4 态权限(approve_once / approve_always / reject_once / reject_always),session-scoped 白名单 + ACP 协议透传SecurityGuard— 路径 / 命令 deny list(HTTP 层快过滤)ContentPolicy— LLM-as-Judge 4 大策略(越狱 / 有害 / 离题 / 品牌违规), judge 失败容错降级OutputFilter— 输出端 PII / 敏感词过滤Sandbox.virtual_mode— 拦../~traversal +O_NOFOLLOWsymlink 防护
Cost & Performance — 成本与性能
CMDC.TokenUsagestruct — 自动归一化 OpenAI / Anthropic / Google 三家 raw usage 字段CostGuard— token / cost 硬预算超限 abort + 80% 告警ModelRouter— 按 turn / cost / token_budget / task_complexity / time_of_day / user_tier / user_data 7 类规则动态切模型LargeResultOffload— 200KB+ 工具结果通过:replace_tool_resultaction 落 backend,message history 只留 head/tail preview + 文件路径PromptCache— Anthropic prompt caching 自动启用Compactor+ArgTruncator— 上下文压缩 + 预 truncate 大参数
Memory & Recovery — 记忆与恢复
MemoryLoader+MemoryFlush闭环 — 长会话不失忆(压缩前持久化关键事实, 下次会话由MemoryLoader自动加载)EpisodicMemory— 成功对话作 few-shot 复用,按 user_id 多租户隔离CMDC.Checkpoint— ETS / DETS 内置 backend,跨 BEAM 进程恢复CMDC.Backend.Composite— 一个会话同时挂 sandbox + PG memory + ETS history (prefix 路由)
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)生产部署模式
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)。
生产可靠性证据
- v0.4.1 主库:1219 tests + 21 doctests, 0 failures, 0 warnings
- v0.4.1 网关:125 tests,0 failures(含 12 个 webhook 测试)
- 4 个生态 hex 包同步发布:cmdc / cmdc_gateway / cmdc_orchestrator / cmdc_skill_engine
- A2A 协议 4 种交互机制全实现(sync / SSE / webhook / Agent Card)
-
所有公共 API 在 v0.3 起返回
{:ok, _} | {:error, _},无意外 raise
跟 Python Agent 框架的差别
不写对比表(写了也没意思),列三个只有 BEAM 才便宜实现的能力让你自己判断:
-
子代理 crash 不传染父代理——
DynamicSupervisor默认行为,零代码 -
跨进程跨节点会话恢复——
CMDC.Checkpoint+ 任意分布式 backend 即可 - 单机数万 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 行(不含测试) |
文档
- hexdocs.pm/cmdc — 完整 API 文档 + 7 篇入门指南
- GitHub Releases — 版本完整 changelog
- 升级指南 — v0.2 → v0.3 → v0.4 兼容边界
开发
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.exsLicense
Apache 2.0 with Commons Clause。商用授权请联系 glggsai@qq.com。