CMDC
Elixir Agent Kernel — OTP gen_statem 驱动的 AI Agent 开发库,专为高并发、高可靠性的 AI Agent 场景设计。
功能亮点
| 维度 | DeepAgents (Python) | CMDC (Elixir) |
|---|---|---|
| 并发模型 | asyncio + Thread | OTP gen_statem + Supervisor — 原生容错、热更新、进程隔离 |
| SubAgent | 同步阻塞 | OTP 进程级隔离 + 真并发,子 Agent crash 不传染父 Agent |
| Plugin 系统 | Middleware 线性链 | Pipeline:11 个 hook × 7 种 action,更精细的拦截和控制力 |
| 安全 | 无内置 | SecurityGuard Plugin — 内置路径/命令安全防护 |
| 成本控制 | 无 | Agent.State 自动累加 token / cost_usd |
| 类型安全 | Python type hints |
TypedStruct + NimbleOptions + @spec 五层 AI-Friendly 防护 |
| 声明式定义 | 无等价物 | Blueprint 系统 — 可复用的 Agent 蓝图 |
安装
将 cmdc 添加到 mix.exs 依赖列表:
def deps do
[
{:cmdc, "~> 0.1"}
]
end然后获取依赖:
mix deps.get快速开始
最简 Agent
# 1. 在应用监控树中启动 Session
{:ok, pid} = CMDC.create_agent(
model: "anthropic/claude-3-5-sonnet-20241022",
api_key: System.get_env("ANTHROPIC_API_KEY")
)
# 2. 发送提示词(异步流式)
:ok = CMDC.prompt(pid, "你好,请介绍一下你自己")
# 3. 收集完整回复
{:ok, reply} = CMDC.collect_reply(pid)
IO.puts(reply)
# 4. 停止
CMDC.stop(pid)带工具的 Agent
{:ok, pid} = CMDC.create_agent(
model: "anthropic/claude-3-5-sonnet-20241022",
api_key: System.get_env("ANTHROPIC_API_KEY"),
tools: [CMDC.Tool.ReadFile, CMDC.Tool.WriteFile, CMDC.Tool.Shell],
working_dir: "/tmp/workspace"
)
CMDC.prompt(pid, "读取 README.md 并写一份中文摘要到 summary.md")
{:ok, reply} = CMDC.collect_reply(pid)订阅事件流
CMDC.subscribe(pid)
CMDC.prompt(pid, "写一段 Elixir 代码示例")
# 实时接收流式事件
receive do
{:cmdc_event, %CMDC.Event{type: :stream_delta, data: %{delta: text}}} ->
IO.write(text)
{:cmdc_event, %CMDC.Event{type: :stream_stop}} ->
IO.puts("\n[完成]")
end使用 Blueprint 声明式定义
defmodule MyApp.CodingAgent do
@behaviour CMDC.Blueprint
@impl true
def build(_opts) do
%CMDC.Options{
system_prompt: "你是一名资深 Elixir 工程师。",
tools: [CMDC.Tool.ReadFile, CMDC.Tool.WriteFile, CMDC.Tool.Shell],
plugins: [CMDC.Plugin.Builtin.SecurityGuard],
skills_dirs: ["priv/skills"]
}
end
end
{:ok, pid} = CMDC.create_agent(MyApp.CodingAgent,
model: "anthropic/claude-3-5-sonnet-20241022",
api_key: System.get_env("ANTHROPIC_API_KEY")
)自定义 Plugin
defmodule MyApp.AuditPlugin do
@behaviour CMDC.Plugin
@impl true
def init(_opts), do: {:ok, %{count: 0}}
@impl true
def priority, do: 100
@impl true
def handle_event({:before_tool, name, args}, state, _ctx) do
IO.puts("[审计] 调用工具: #{name}, 参数: #{inspect(args)}")
{:continue, %{state | count: state.count + 1}}
end
def handle_event(_event, state, _ctx), do: {:continue, state}
end架构
CMDC(公共 API 入口)
├── SessionServer(Supervisor Tree)
│ ├── Agent(gen_statem 状态机)
│ │ ├── State — 运行时状态 + token/cost 追踪
│ │ ├── Stream — 流式响应 delta 组装
│ │ ├── ToolRunner — 工具执行 + 循环检测
│ │ ├── Emitter — EventBus 事件广播
│ │ ├── SystemPrompt — 提示词组装(BasePrompt + Skills + Memory)
│ │ └── Compactor — 上下文压缩 + ArgTruncator
│ └── SubAgent.Supervisor(DynamicSupervisor)
│ └── 子 Agent 进程(并行、隔离)
│
├── Plugin Pipeline(11 hooks × 7 actions)
├── Tool(11 个内置工具)
├── Provider(req_llm 封装,支持多 LLM 提供商)
├── MCP(Bridge + Client + Supervisor)
├── Sandbox(可插拔文件系统抽象)
├── Blueprint(声明式 Agent 蓝图)
├── Skills(渐进式 SKILL.md 发现)
└── Memory.ETS(ETS 持久记忆)模块依赖层级
L0 基础类型 Options / Config / Context / Message / Event / EventBus / SubAgent
L1 核心抽象 Blueprint / Plugin / Tool / Sandbox / Skill / Provider
L2 Agent Agent (gen_statem) + State + Stream + ToolRunner + Compactor
L3 集成 SessionServer + MCP.* + Memory.ETS + SubAgent.Supervisor
L4 Facade CMDC(公共 API 入口)内置功能
Plugin(6 个)
| Plugin | 说明 |
|---|---|
SecurityGuard | 拦截危险路径和系统命令,防止越权操作 |
EventLogger | 记录所有 Agent 事件,便于调试和审计 |
HumanApproval | HITL 审批流,工具调用前等待人工确认 |
MemoryLoader | 加载 AGENTS.md 持久记忆并注入 System Prompt |
PatchToolCalls | 自动修复悬空 tool_call(无对应 ToolMessage 的响应) |
PromptCache | Anthropic 模型 prompt caching 支持,降低成本 |
Tool(11 个)
| Tool | 说明 |
|---|---|
ReadFile | 读取文件,支持 offset/limit 分页 |
WriteFile | 写入文件 |
EditFile | 精确字符串替换(str_replace 模式) |
Shell | 执行 shell 命令,大输出自动存文件 |
Grep | 正则搜索,支持 glob 文件过滤 |
ListDir | 列出目录内容 |
Glob | 模式匹配文件列表 |
Task | 启动 SubAgent 子进程(OTP 进程级并发) |
WriteTodos | 更新 Agent 的 Todo 列表 |
AskUser | 暂停执行,等待用户输入 |
CompactConversation | 手动触发上下文压缩 |
事件系统(22 种事件)
所有事件通过 CMDC.EventBus 广播,消费者通过 CMDC.subscribe/1 订阅:
session_start / session_end
stream_start / stream_delta / stream_stop
tool_start / tool_end / tool_batch_end
approval_required / approval_responded
todo_change
cost_update
compact_start / compact_end
subagent_start / subagent_end
memory_loaded
ask_user / user_responded
context_overflow
errorMCP(Model Context Protocol)支持
{:ok, pid} = CMDC.create_agent(
model: "anthropic/claude-3-5-sonnet-20241022",
api_key: System.get_env("ANTHROPIC_API_KEY"),
mcp_servers: [
%CMDC.MCP.Config{
name: "filesystem",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
]
)AI-Friendly 类型系统
CMDC 的核心差异化之一是「AI-Friendly 类型系统」,让 AI 生成的调用代码更准确:
# 精确的 NimbleOptions schema,每个字段含类型 + 默认值 + 中文说明
%CMDC.Options{
model: "anthropic/claude-3-5-sonnet-20241022", # 必填
system_prompt: "...", # 可选,nil 表示使用 BasePrompt
tools: [CMDC.Tool.ReadFile], # 可选,Tool 模块列表
plugins: [CMDC.Plugin.Builtin.SecurityGuard], # 可选,Plugin 模块列表
max_tokens: 8192, # 可选,默认 8192
max_turns: 10, # 可选,默认 10,nil 表示无限制
working_dir: "/tmp/workspace", # 可选,工具执行根目录
skills_dirs: ["priv/skills"], # 可选,Skills SKILL.md 搜索目录
memory_dir: "~/.cmdc/memory" # 可选,AGENTS.md 持久记忆目录
}开发
# 测试
mix test
# 格式化
mix format
# 静态分析
mix credo --strict
# 类型检查
mix dialyzer
# 一键质量检查
mix quality.check许可证
本项目采用 Apache 2.0 + Commons Clause 许可证。
- 允许:学习、修改、自由使用(包括内部商业用途)、基于 CMDC 构建自己的应用/产品
- 不允许:将 CMDC 本身作为托管服务、云服务或 SaaS 对外提供,或出售以 CMDC 功能为核心价值的产品
详见 LICENSE。商业授权合作请联系:glggsai@qq.com
文档
- HexDocs API 参考
llm.txt— AI 快速参考(~200 行,API 签名 + 类型 + 示例)llms-full.txt— AI 完整参考(~800 行,含事件协议、Plugin/Tool 开发、已知陷阱)