CMDC

Elixir Agent Kernel — OTP gen_statem 驱动的 AI Agent 开发库,专为高并发、高可靠性的 AI Agent 场景设计。

Hex.pmDocsLicense


功能亮点

维度 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
error

MCP(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 许可证。

详见 LICENSE。商业授权合作请联系:glggsai@qq.com


文档