# 5 分钟上手

把 CMDC 当作一个会话级 Agent 引擎：调一次 `create_agent/1` 拿到 pid，
之后所有交互都通过这个 pid 异步推进，事件经 `EventBus` 广播给订阅者。

---

## 安装

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

获取依赖：

```bash
mix deps.get
```

---

## Hello World

最少 4 个调用就能完成一次完整对话——创建 → 提问 → 收回复 → 关闭：

```elixir
{: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)
```

`prompt/2` 是非阻塞的——它返回后 LLM 调用才开始；`collect_reply/2` 同步等
拿到本轮所有 assistant 文本拼接的字符串。需要边收边渲染请改用 `subscribe/1`。

---

## 流式订阅

订阅当前进程接收 `{:cmdc_event, session_id, event}` 消息：

```elixir
{:ok, session} = CMDC.create_agent(model: "anthropic:claude-sonnet-4-5")

CMDC.subscribe(session)
CMDC.prompt(session, "数到 5。")

stream_loop = fn loop ->
  receive do
    {:cmdc_event, _sid, {:message_delta, %{delta: text}}} ->
      IO.write(text)
      loop.(loop)

    {:cmdc_event, _sid, {:agent_end, _msgs, _usage}} ->
      :done
  after
    30_000 -> {:error, :timeout}
  end
end

stream_loop.(stream_loop)
CMDC.stop(session)
```

完整事件清单见 [`CMDC.Event`](CMDC.Event.html)。订阅断网想补帧请用
`Options.event_buffer_size` 开启 ring buffer。

---

## 带工具的 Agent

CMDC 内置 11 个工具（读写文件 / shell / grep / glob / ls / 子代理派发 /
todo 跟踪 / 用户提问 / 上下文压缩 / 大结果分页）。声明 `:tools`
即可让 Agent 自主调用：

```elixir
{:ok, session} = CMDC.create_agent(
  model: "anthropic:claude-sonnet-4-5",
  tools: [
    CMDC.Tool.ReadFile,
    CMDC.Tool.WriteFile,
    CMDC.Tool.Shell,
    CMDC.Tool.Grep
  ],
  working_dir: "/tmp/agent-workspace"
)

CMDC.prompt(session, "读取 /tmp/agent-workspace/notes.md，把 TODO 抽出来写到 todos.md")
{:ok, reply} = CMDC.collect_reply(session)
```

Shell / WriteFile 默认走 `Sandbox.Local`，所有文件路径限制在 `working_dir`
内（见 [Sandbox](CMDC.Sandbox.html)）。生产环境强烈建议接 `Backend.Filesystem`
+ `virtual_mode: true`。

---

## 用 Plugin 加切面

Plugin 是把"切面逻辑"插入 Agent 13 个生命周期 hook 的标准方式：

```elixir
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

{:ok, session} = CMDC.create_agent(
  model: "anthropic:claude-sonnet-4-5",
  tools: [CMDC.Tool.Shell],
  plugins: [{MyApp.AuditPlugin, []}]
)
```

CMDC 自带 16 个内置 Plugin（见 [Plugins（安全与控制）](CMDC.Plugin.html)
和 Plugins（优化与记忆）分组），覆盖审批 / 安全 / 内容拦截 / 长会话记忆 /
模型路由 / 大结果 offload / 反思 / 规划等典型场景。

---

## 中段干预（Steering）

发现方向不对想换条路？不需要 abort 重来——直接 `steer/2` 软中断：

```elixir
{:ok, session} = CMDC.create_agent(
  model: "anthropic:claude-sonnet-4-5",
  tools: [CMDC.Tool.Shell]
)

CMDC.prompt(session, "帮我用 100 行 Python 实现快排。")

# 中途改主意
ref = make_ref()
CMDC.steer(session, ref, "停，改成用 Elixir 实现，别用 Python。")

{:ok, reply} = CMDC.collect_reply(session)
```

正在执行的不可中断工具会跑完，可中断的工具被 `brutal_kill`，下一轮
LLM 调用看到合并后的新 prompt。完整选项见 [`CMDC`](CMDC.html) 的 `steer/2` 与
[`CMDC.Agent`](CMDC.Agent.html) 的状态行为表。

---

## HITL 审批

让人类在 Agent 调危险工具前点头：

```elixir
{:ok, session} = CMDC.create_agent(
  model: "anthropic:claude-sonnet-4-5",
  tools: [CMDC.Tool.Shell],
  plugins: [
    {CMDC.Plugin.Builtin.HumanApproval, [tools: ["shell"]]}
  ]
)

CMDC.subscribe(session)
CMDC.prompt(session, "在 /tmp 下创建一个 hello.txt 文件。")

receive do
  {:cmdc_event, _sid, {:approval_required, %{id: id, tool: "shell", args: args}}} ->
    IO.inspect(args, label: "Agent 想跑")
    CMDC.approve(session, id)  # 或 CMDC.reject(session, id)
end

{:ok, reply} = CMDC.collect_reply(session)
```

`approve_always` 可把同类命令加入 session 白名单，详见
[`CMDC.Plugin.Builtin.HumanApproval`](CMDC.Plugin.Builtin.HumanApproval.html)。

---

## 下一步

跑通上面五段你已经覆盖了 80% 的日常用法。继续深挖请看：

- [核心概念](concepts.html) — Agent / Session / Plugin / Tool / Backend 七大概念
- [Agent 状态机与事件](agent-loop.html) — 4 状态流转 + 完整事件清单
- [写一个 Plugin](plugins.html) — 13 hook × 8 action 矩阵 + 5 个完整范例
- [写一个 Tool](tools.html) — Tool behaviour + Sandbox 代理 + 错误处理
- [常见配方](cookbook.html) — 端到端组合范例（流式 UI / 长会话不失忆 / 多 Agent / Checkpoint / Telemetry）
- [升级指南](upgrading.html) — v0.2 → v0.3 → v0.4 各版本兼容边界
