pwittchen/aictl
GitHub: pwittchen/aictl
一个以安全为默认设计理念的终端 AI 代理与 HTTP LLM 代理服务器,支持 11 个云端和本地模型提供商,提供沙箱执行、凭据脱敏、审计日志等企业级安全控制。
Stars: 2 | Forks: 0
# aictl 🤖
[](https://github.com/pwittchen/aictl/actions/workflows/ci.yml)
[](https://github.com/pwittchen/aictl/actions/workflows/release.yml)
[](https://github.com/pwittchen/aictl/actions/workflows/deploy-website.yml)
你的终端和桌面中的 AI 代理 + HTTP LLM 代理服务器 — 跨 8 个提供商内置 70 个云端模型,外加任何通过 Ollama 可用的模型、通过 llama.cpp 实现的原生 GGUF 推理,或在 Apple Silicon 上的原生 MLX 推理。默认安全优先。
项目网站:[aictl.app](https://aictl.app) — 源码位于 [`website/`](website/)。
用户指南:https://aictl.app/guides.html

## 安装
```
curl -sSf https://aictl.app/install.sh | sh
```
安装程序会从最新的 GitHub 发布版下载适用于您平台的预编译二进制文件,并将其放置在 `~/.local/bin/aictl` 中。如果 aictl 已经安装在 `~/.cargo/bin/aictl`(例如,通过之前的 `cargo install` 安装),安装程序会在该位置就地更新它,而不是默认的 `~/.local/bin/`。设置 `AICTL_INSTALL_DIR` 可以显式选择不同的安装位置。如果您的平台没有预编译二进制文件,安装程序会退回到使用 `cargo install` 从源代码构建。
### 支持的平台
预编译二进制文件发布于:
| 操作系统 | 架构 |
|---|---|
| Linux | `x86_64`, `aarch64` |
| macOS | `x86_64`, `aarch64` (Apple Silicon) |
不支持原生 Windows — aictl 依赖 POSIX shell (`sh`) 和 Unix 工具(`date`、`pbcopy` 等)进行其内置工具调用。Windows 用户可以在 [WSL](https://learn.microsoft.com/windows/wsl/) 中使用 Linux 二进制文件运行 aictl,这可以正常工作。
其他平台(FreeBSD、其他 BSD、不常见的 Linux 架构)仍然可以通过 `cargo install` 回退路径从源代码构建,前提是有可用的 Rust 工具链。
### 前置条件
安装预编译二进制文件除了 `curl` 之外没有其他前提条件。从源代码构建(通过安装程序回退或手动构建)需要 [Rust](https://www.rust-lang.org/tools/install)(2024 版本)。
### 从源代码构建
```
git clone git@github.com:pwittchen/aictl.git
cd aictl
cargo install --path crates/aictl-cli
```
要安装包含所有功能的版本,请运行:
```
cargo install --path crates/aictl-cli --features "gguf mlx redaction-ner"
```
这会将 `aictl` 二进制文件安装到 `~/.cargo/bin/`。
### 构建但不安装
```
cargo build --release
```
二进制文件将位于 `target/release/aictl`。
### 可选特性标志
原生本地模型推理受 cargo 特性限制,因此纯粹的 `cargo build` / `cargo install` 可保持轻量级默认设置(不需要 C++ 工具链或 Metal 工具链)。按后端选择启用:
| 特性 | 启用的内容 | 平台 | 额外的构建时要求 |
|---------|-----------------|----------|-------------------------------|
| `gguf` | 通过 `llama-cpp-2` 实现原生 GGUF 推理 | 所有 | `cmake` + 可用的 C/C++ 编译器(macOS 上为 Xcode Command Line Tools,Debian/Ubuntu 上为 `build-essential`) |
| `mlx` | 通过 `mlx-rs`(Apple 的 MLX 框架)实现原生 MLX 推理 | 仅限 macOS + Apple Silicon | 完整的 Xcode(不仅是 CLT)且安装了 Metal Toolchain |
| `redaction-ner` | 通过 `gline-rs` 实现用于脱敏管道的 Layer-C 命名实体识别(通过 `ort` crate 的 GLiNER ONNX 模型;捆绑的 ONNX Runtime 二进制文件,无需系统安装) | 所有 | 无 |
示例:
```
# 仅 GGUF
cargo build --release --features gguf
cargo install --path crates/aictl-cli --features gguf
# 仅 MLX (macOS Apple Silicon)
cargo build --release --features mlx
cargo install --path crates/aictl-cli --features mlx
# 仅 NER-backed redaction (redaction pipeline 的 Layer C)
cargo build --release --features redaction-ner
cargo install --path crates/aictl-cli --features redaction-ner
# 全部三种 (GGUF + MLX + NER-backed redaction)
cargo build --release --features "gguf mlx redaction-ner"
cargo install --path crates/aictl-cli --features "gguf mlx redaction-ner"
```
如果没有这些特性,相应的斜杠命令(`/gguf`、`/mlx`)和 CLI 标志(`--pull-gguf-model`、`--pull-mlx-model`、`--pull-ner-model` 等)在**模型管理**(下载/列表/移除)方面仍然有效;只是推理路径被禁用了,尝试运行本地模型或启用基于 NER 的脱敏会打印清晰的错误,告诉您需要使用哪个特性重新构建。
GitHub Releases 上发布的预编译二进制文件(由 `install.sh` 下载)在每个平台上都启用了 `--features gguf` 进行附带 — 因此一行命令安装即可在平台支持的情况下开箱即用原生 GGUF 推理。macOS Apple Silicon (`aarch64`) 版本还额外附带了 `--features mlx`,并在二进制文件旁边包含了一个同级 `mlx.metallib` 文件(MLX 在运行时需要 Metal 库);其他每个平台的版本只包含 `aictl` 二进制文件。
## HTTP 服务器 (`aictl-server`)
此工作区中的第二个二进制文件 `aictl-server`,通过兼容 OpenAI 的 HTTP 端点提供相同的提供商目录,并具有脱敏、提示注入阻止、审计和主密钥门控功能。纯粹的代理 — 没有代理循环,没有工具,没有代理/技能/会话。完整参考请参见 [SERVER.md](SERVER.md)。
```
curl -fsSL https://aictl.app/server/install.sh | sh
aictl-server # listens on 127.0.0.1:7878 by default; prints master key on first launch
aictl --serve # convenience shortcut from the CLI; forwards trailing args after `--`
```
### 使用 `aictl-server` 作为上游
CLI 也可以指向一个 `aictl-server` 实例,而不是直接与每个提供商对话。设置此项后,操作员只需在服务器上配置一次提供商密钥(`LLM_OPENAI_API_KEY`、`LLM_ANTHROPIC_API_KEY`、...),而每个 CLI 主机只需携带一个主密钥。
```
aictl --client-url http://127.0.0.1:7878 --client-master-key sk-aictl-…
```
或者持久化它:
```
# 在 ~/.aictl/config 中 — 注意 AICTL_CLIENT_* 前缀(CLI 的视图)。
# 服务器自身的 AICTL_SERVER_MASTER_KEY 是一个独立的密钥;同一台
# 机器可以同时承载这两个角色而不会产生歧义。
AICTL_CLIENT_HOST=http://127.0.0.1:7878
AICTL_CLIENT_MASTER_KEY=sk-aictl-…
```
`AICTL_CLIENT_MASTER_KEY` 参与与提供商密钥相同的 `/keys` 锁定/解锁/清除生命周期,因此它可以像任何其他密钥一样移入 OS 密钥环。本地提供商(`Ollama`、`GGUF`、`MLX`)无条件绕过服务器 — 代理跳转将毫无意义。
## 卸载
### 二进制发布版(通过 `install.sh` 安装)
安装脚本将二进制文件放置在 `~/.local/bin/aictl`(如果您设置了 `$AICTL_INSTALL_DIR`,则在该目录下)。使用以下命令移除它:
```
rm ~/.local/bin/aictl
```
### 从源代码(通过 `cargo install` 安装)
Cargo 会跟踪其自身的安装,因此最干净的方法是:
```
cargo uninstall aictl
```
这将移除 `~/.cargo/bin/aictl`。如果 `cargo uninstall` 找不到它(例如,在不同的 crate 名称下安装),请直接删除二进制文件:
```
rm ~/.cargo/bin/aictl
```
### 移除配置和数据(可选)
aictl 将所有状态存储在 `~/.aictl/` 下 — 配置文件、保存的代理、保存的会话。要彻底清除它:
```
rm -rf ~/.aictl
```
如果您计划重新安装并希望保留您的 API 密钥、代理和会话历史记录,请跳过此步骤。
## 用法
```
aictl [--version] [--update] [--uninstall] [--config] [--provider ] [--model ] [--message ] [--auto] [--quiet] [--audit-file ] [--cwd ] [--unrestricted] [--incognito] [--agent ] [--list-agents] [--pull-agent ] [--skill ] [--list-skills] [--pull-skill ] [--force] [--session ] [--list-sessions] [--clear-sessions] [--lock-keys] [--unlock-keys] [--clear-keys] [--pull-gguf-model ] [--list-gguf-models] [--remove-gguf-model ] [--clear-gguf-models] [--pull-mlx-model ] [--list-mlx-models] [--remove-mlx-model ] [--clear-mlx-models] [--balance] [--list-plugins] [--list-hooks] [--list-mcp] [--mcp-server ]
```
省略 `--message` 以进入带有持久对话历史的交互式 REPL 模式。
### REPL 命令
交互式 REPL 支持斜杠命令:
| 命令 | 描述 |
|---------|-------------|
| `/agent` | 管理代理(手动创建、使用 AI 创建、查看/加载/删除、卸载) |
| `/clear` | 清除对话上下文 |
| `/compact` | 将对话总结为紧凑的上下文 |
| `/retry` | 移除最后一次用户/助手交流并使用相同的提示重试(在响应偏离轨道时很有用) |
| `/undo` | 从对话中丢弃最后 N 轮而不重新运行(`/undo` = 1,`/undo 3` = 3);拒绝跨越 `/compact` 边界 |
| `/context` | 显示上下文使用情况(token 和消息计数与限制的对比) |
| `/copy` | 将最后一次响应复制到剪贴板 |
| `/help` | 显示可用命令 |
| `/history` | 查看内存中的对话;可选角色或关键字过滤器(例如 `/history user rust`) |
| `/info` | 显示设置信息(提供商、模型、行为、记忆、代理、版本、操作系统、二进制文件大小) |
| `/roadmap` | 获取并渲染项目路线图;可选章节过滤器(例如 `/roadmap desktop`) |
| `/gguf` | 管理原生 GGUF 模型(查看已下载、拉取、移除、清除全部) |
| `/mlx` | 管理原生 MLX 模型(Apple Silicon;查看已下载、拉取、移除、清除全部) |
| `/memory` | 切换记忆模式:长期(所有消息)或短期(滑动窗口) |
| `/security` | 显示当前安全策略(被阻止的命令、CWD 监狱、超时等) |
| `/session` | 管理会话(显示当前信息、设置名称、查看/加载/删除已保存的会话、清除全部) |
| `/skills` | 管理技能(手动创建、使用 AI 创建、查看/调用/删除) — 单轮 markdown playbook |
| `/stats` | 管理使用统计 — 查看今天/本月/总体(会话、调用、token、估计成本)或清除全部 |
| `/behavior` | 在会话期间切换自动和人机循环模式 |
| `/model` | 在会话期间切换模型和提供商(持久化到 `~/.aictl/config`) |
| `/ping` | 验证每个配置的 API 密钥并探测提供商连接性(云提供商 + Ollama 守护进程) |
| `/plugins` | 管理外部插件工具 — 列出已安装的插件、查看清单、切换主开关(`AICTL_PLUGINS_ENABLED`) |
| `/hooks` | 管理生命周期钩子 — 查看每个事件的所有已配置钩子、切换单个条目开/关、使用合成有效载荷测试触发钩子,或重新加载 `~/.aictl/hooks.json` |
| `/mcp` | 管理外部 MCP(模型上下文协议)服务器 — 列出已配置的服务器、查看带有输入 schema 的工具目录、切换主开关(`AICTL_MCP_ENABLED`) |
| `/balance` | 显示每个已配置云提供商的剩余信用额度/配额(来自 DeepSeek 和 Kimi 的实际数字;其他地方为“未知”并提供计费控制台提示) |
| `/tools` | 显示可用工具 |
| `/keys` | 管理 API 密钥存储 — 锁定(配置 → 密钥环)、解锁(密钥环 → 配置)或清除(两个存储) |
| `/config` | 重新运行交互式配置向导 |
| `/update` | 更新到最新版本 |
| `/uninstall` | 从 `~/.cargo/bin/` 和 `~/.local/bin/` 中移除 aictl 二进制文件(需确认) |
| `/version` | 对照最新可用版本检查当前版本 |
| `/exit` | 退出 REPL |
任何与已保存技能匹配的无法识别的 `/`(参见下文的[技能](#skills))将在下一轮运行该技能:`/` 使用默认触发器运行它,`/ ` 将 `` 作为用户消息路由。
在任何 LLM 调用或工具执行期间按 **Esc** 可中断操作并返回提示符。对话历史将被回滚,因此被中断的轮次不会产生任何影响。
### 参数
只有 `--version` (`-v`) 和 `--help` (`-h`) 有短标志。按照惯例,所有其他选项仅使用长格式。
| 标志 | 描述 |
|------|-------------|
| `--version`, `-v` | 打印版本信息 |
| `--help`, `-h` | 打印帮助 |
| `--update` | 更新到最新版本 |
| `--uninstall` | 从 `~/.cargo/bin/aictl`、`~/.local/bin/aictl` 和 `$AICTL_INSTALL_DIR/aictl`(如果已设置)中移除 aictl 二进制文件并退出。保持 `~/.aictl/` 不变 |
| `--config` | 交互式配置向导 — 逐步设置提供商、模型和 API 密钥 |
| `--provider` | LLM 提供商(`openai`、`anthropic`、`gemini`、`grok`、`mistral`、`deepseek`、`kimi`、`zai`、`ollama`、`gguf`、`mlx` 或 `aictl-server`)。回退 `~/.aictl/config` 中的 `AICTL_PROVIDER` |
| `--model` | 模型名称(例如 `gpt-4o`)。回退到 `~/.aictl/config` 中的 `AICTL_MODEL` |
| `--message` | 要发送的消息(省略则进入交互模式) |
| `--agent` | 按名称加载已保存的代理(在单次和交互模式下均可工作) |
| `--list-agents` | 打印 `~/.aictl/agents/` 中保存的代理并退出。结合 `--category ` 进行过滤 |
| `--pull-agent` | 从 aictl 仓库下载官方代理到 `~/.aictl/agents/`。结合 `--force` 跳过覆盖提示 |
| `--skill` | 按名称调用保存的技能进行单轮操作。在单次模式下,技能体仅作为 `--message` 调用的临时系统提示注入;在 REPL 模式下,它应用于第一个用户轮次,然后 REPL 恢复正常 |
| `--list-skills` | 打印 `~/.aictl/skills/` 中保存的技能并退出 |
| `--pull-skill` | 从 aictl 仓库下载官方技能到 `~/.aictl/skills//SKILL.md`。结合 `--force` 跳过覆盖提示 |
| `--auto` | 以自主模式运行(跳过工具确认提示) |
| `--quiet` | 抑制工具调用和推理,仅打印最终答案(需要 `--auto`) |
| `--audit-file` | 将每行的 JSON 审计日志写入显式路径。旨在用于单次(`--message`)运行,否则这些运行没有会话 ID 来键控默认的 `~/.aictl/audit/` 文件。即使 `AICTL_SECURITY_AUDIT_LOG=false` 也会强制启用审计日志。父目录会按需创建 |
| `--cwd` | 此运行的工作目录。CLI 在任何工具调度之前切换到此路径,并将其用作 CWD 监狱根目录,因此文件/shell 工具在此处解析相对路径并被限制在此子树中。接受绝对路径、相对路径和带有 `~` 前缀的路径。回退到 `~/.aictl/config` 中的 `AICTL_WORKING_DIR`;当两者都未设置时,使用启动目录 |
| `--unrestricted` | 禁用所有安全限制(谨慎使用) |
| `--incognito` | 启动交互式 REPL 而不保存任何会话(禁用 `/session`)。回退到 `~/.aictl/config` 中的 `AICTL_INCOGNITO` |
| `--session` | 启动时通过 uuid 或名称加载已保存的会话(仅限交互模式) |
| `--list-sessions` | 打印 `~/.aictl/sessions/` 中保存的会话并退出 |
| `--clear-sessions` | 移除所有保存的会话并退出 |
| `--lock-keys` | 将明文 API 密钥从 `~/.aictl/config` 迁移到系统密钥环并退出 |
| `--unlock-keys` | 将 API 密钥从系统密钥环迁移回 `~/.aictl/config` 并退出 |
| `--clear-keys` | 从 `~/.aictl/config` 和系统密钥环中移除 API 密钥并退出 |
| `--pull-gguf-model` | 下载原生 GGUF 模型(规格:`hf:owner/repo/file.gguf`、`owner/repo:file.gguf` 或 `https://…/file.gguf`)。保存在 `~/.aictl/models/gguf/` 下并退出 |
| `--list-gguf-models` | 打印所有已下载的原生 GGUF 模型并退出 |
| `--remove-gguf-model` | 按名称移除已下载的原生 GGUF 模型并退出 |
| `--clear-gguf-models` | 移除所有已下载的原生 GGUF 模型并退出 |
| `--pull-mlx-model` | 下载原生 MLX 模型(规格:`mlx:owner/repo` 或 `owner/repo`)。保存在 `~/.aictl/models/mlx//` 下并退出 |
| `--list-mlx-models` | 打印所有已下载的原生 MLX 模型并退出 |
| `--remove-mlx-model` | 按名称移除已下载的原生 MLX 模型并退出 |
| `--clear-mlx-models` | 移除所有已下载的原生 MLX 模型并退出 |
| `--pull-ner-model` | 下载脱敏 NER 模型(规格:`owner/repo` 或 `hf:owner/repo`;默认形状:`onnx-community/gliner_small-v2.1`)。保存在 `~/.aictl/models/ner//` 下并退出。推理需要 `redaction-ner` cargo 特性;管理功能在每次构建中均可工作 |
| `--list-ner-models` | 打印所有已下载的 NER 模型并退出 |
| `--remove-ner-model` | 按名称移除已下载的 NER 模型并退出 |
| `--clear-ner-models` | 移除所有已下载的 NER 模型并退出 |
| `--balance` / `--list-balances` | 显示每个已配置云提供商的剩余信用额度/配额并退出。来自 DeepSeek 和 Kimi 的实际数字(通过其官方 `/user/balance` 和 `/v1/users/me/balance` 端点);其他提供商报告“未知”并带有指向其计费控制台的提示。本地提供商(Ollama / GGUF / MLX)不在此范围内 |
| `--list-plugins` | 打印已安装的插件(名称、描述、位置)并退出。从 `~/.aictl/plugins/` 读取(可通过 `AICTL_PLUGINS_DIR` 覆盖)。当 `AICTL_PLUGINS_ENABLED=false` 时,列表为空并带有关于主开关的提示 |
| `--list-hooks` | 打印已配置的钩子(事件、匹配器、命令、状态)并退出。从 `~/.aictl/hooks.json` 读取(可通过 `AICTL_HOOKS_FILE` 覆盖) |
| `--list-mcp` | 打印已配置的 MCP 服务器(名称、状态、工具计数)并退出。从 `~/.aictl/mcp.json` 读取(可通过 `AICTL_MCP_CONFIG` 覆盖)。当 `AICTL_MCP_ENABLED=false` 时,列表为空并带有关于主开关的提示 |
| `--mcp-server` | 将此会话限制为仅命名的 MCP 服务器(其他所有已配置的服务器在该进程中被强制禁用)。仅在 `AICTL_MCP_ENABLED=true` 时有效 |
| `--client-url` | 在此调用中通过此 `aictl-server` URL 路由每个非本地 LLM 调用。覆盖 `AICTL_CLIENT_HOST`。空字符串(`""`)即使设置了 `AICTL_CLIENT_HOST` 也会禁用此运行的路由。不持久化 |
| `--client-master-key` | CLI 在此调用中向配置的 `aictl-server` 提供的主密钥。覆盖配置或密钥环中的 `AICTL_CLIENT_MASTER_KEY`。不持久化(在 shell 历史记录和 `ps` 中可见 — 持久化路径为 `/keys` 或 `--config`) |
| `--serve` | 启动捆绑的 `aictl-server` HTTP LLM 代理(如果已安装)。从 CLI 提供的便捷快捷方式;`--` 之后的后续参数将原样转发,例如 `aictl --serve -- --bind 0.0.0.0:7878 --quiet`。参见 [SERVER.md](SERVER.md) |
CLI 标志优先于配置文件中的值。
### 会话
在交互模式下,每次 REPL 运行都是一个会话。启动时会生成一个新的 uuid,并且在每次代理轮次和压缩后,对话将作为 JSON 持久化到 `~/.aictl/sessions/`。会话名称(可选,唯一)存储在 `~/.aictl/sessions/.names` 中。退出时,会打印会话的 uuid(以及名称,如果已设置)。
使用 `/session` 显示当前会话信息,分配易读的名称,浏览保存的会话(加载或删除并确认),或清除所有会话。传递 `--session ` 以在启动时恢复现有会话。隐身模式(`--incognito` 或 `AICTL_INCOGNITO=true`)运行 REPL 而不创建或保存任何会话文件;`/session` 被禁用并显示通知。
### 代理
代理是可重用的系统提示扩展,专门为 LLM 定制专用任务或行为。代理提示以纯文本文件形式存储在 `~/.aictl/agents/` 中。
使用 `/agent` 打开代理菜单:
- **手动创建代理** — 输入名称,然后直接输入或粘贴代理提示文本
- **使用 AI 创建代理** — 提供名称和简要描述;LLM 生成完整的代理提示
- **浏览官方代理** — 浏览 aictl 仓库中随附的精选代理实时目录(参见下文的“官方目录”),预览它们,并将您想要的拉取到 `~/.aictl/agents/`
- **查看所有代理** — 浏览已保存的代理,查看其提示,加载代理或删除它
- **卸载代理** — 移除当前加载的代理(仅在已加载时显示)
也可以使用 `--agent ` 从命令行加载代理,这在单次和交互模式下均可工作。
代理名称只能包含字母、数字、下划线和破折号。加载代理时,其提示会附加到系统提示中,并且代理名称会以品红色括号显示在输入提示之前(例如 `[my-agent] ❯`)。
#### 官方目录
aictl 附带了一组精选的官方代理(例如 `researcher`、`software-architect`、`critic`、`security-auditor`、`psychologist`),它们位于项目 GitHub 仓库的 [`.aictl/agents/`](./.aictl/agents/) 下 — **未**捆绑到二进制文件中。新的目录代理在合并到 `master` 分支的那一刻即可用,无需发布新版本。
通过两种方式从目录拉取代理:
- 从 REPL 中,`/agent` → **浏览官方代理**。代理按类别分组;每行显示 `[ ]`(未拉取)、`[✓]`(与上游匹配)或 `[↑]`(与上游不同)。按 `v` 在拉取前预览代理的提示,按 `p` / Enter 拉取。
- 从 shell 中,`aictl --pull-agent ` 下载单个代理。添加 `--force` 可在不提示的情况下覆盖现有本地文件。
目录代理在其 frontmatter 中带有 `source: aictl-official`;`/agent` 和 `--list-agents` 都会渲染一个 `[official]` 徽章,以便您一眼就能分辨出哪些代理来自目录,哪些是您自己编写的。用户可以自由编辑或删除拉取的代理 — 它们在磁盘上没有任何特殊之处。公共仓库读取未经身份验证(约 60 次请求/小时),这对于浏览然后拉取来说绰绰有余;错误会在 REPL 中报告,而不会导致会话崩溃。
### 技能
技能是按需调用的单轮 markdown playbook — 这与贯穿整个会话的代理不同。技能编码了一个可重复的过程(“运行提交工作流”、“审查待处理的 diff”),LLM 应该在这一个时间点遵循;轮次完成后,技能即消失。技能位于 `~/.aictl/skills//SKILL.md`(可通过 `AICTL_SKILLS_DIR` 覆盖)。
每个 `SKILL.md` 以 YAML frontmatter(`name`、`description`)开头,后跟 markdown 正文:
```
---
name: commit
description: Commit staged changes with a clear, project-style message.
---
When the user asks you to commit:
1. Run `git status` and `git diff --cached` to see what's staged.
2. ...
```
使用 `/skills` 打开技能菜单:
- **手动创建技能** — 输入名称和描述,然后输入或粘贴正文
- **使用 AI 创建技能** — 提供名称和一行描述;LLM 起草正文
- **浏览官方技能** — 浏览 aictl 仓库中随附的精选技能实时目录(参见下文的“官方目录”),预览它们,并将您想要的拉取到 `~/.aictl/skills//SKILL.md`
- **查看所有技能** — 浏览保存的技能,带有查看/调用/删除操作
在 REPL 提示符下直接输入 `/` 即可调用技能。`/` 使用默认触发器运行技能,因此单独的正文即可驱动该轮次;`/commit review the staged diff` 将尾随文本作为用户消息路由。`--skill ` 在单次和 REPL 模式下工作方式相同。`--list-skills` 打印已保存的技能并退出。
技能名称只能包含字母、数字、下划线和破折号,且不得与内置斜杠命令(例如 `help`、`exit`、`agent`)冲突 — 此类名称在保存时会被拒绝。技能正文在轮次中合并到基本系统提示中(而不是作为单独的系统消息发送),因此每个提供商(包括那些只接受单个顶级 `system` 字段的提供商)都能看到与工具目录并列的技能。
#### 官方目录
aictl 附带了一组精选的官方技能,它们位于项目 GitHub 仓库的 [`.aictl/skills/`](./.aictl/skills/) 下 — **未**捆绑到二进制文件中。新的目录技能在合并到 `master` 分支的那一刻即可用,无需发布新版本。
通过两种方式从目录拉取技能:
- 从 REPL 中,`/skills` → **浏览官方技能**。技能按类别分组;每行显示 `[ ]`(未拉取)、`[✓]`(与上游匹配)或 `[↑]`(与上游不同)。按 `v` 在拉取前预览技能的正文,按 `p` / Enter 拉取。
- 从 shell 中,`aictl --pull-skill ` 下载单个技能。添加 `--force` 可在不提示的情况下覆盖现有本地文件。
目录技能在其 frontmatter 中带有 `source: aictl-official`;`/skills` 和 `--list-skills` 都会渲染一个 `[official]` 徽章,以便您一眼就能分辨出哪些技能来自目录,哪些是您自己编写的。用户可以自由编辑或删除拉取的技能 — 它们在磁盘上没有任何特殊之处。公共仓库读取未经身份验证(约 60 次请求/小时),这对于浏览然后拉取来说绰绰有余;错误会在 REPL 中报告,而不会导致会话崩溃。
### 插件
插件是用户安装的外部工具,无需分叉仓库即可扩展代理。插件是 `~/.aictl/plugins//` 下的一个目录,包含一个 `plugin.toml` 清单和一个可执行入口点(任何语言 — shell 脚本、Python、编译的二进制文件,任何能读取 stdin 并写入 stdout 的东西)。
```
~/.aictl/plugins/
└── kubectl_query/
├── plugin.toml
└── run # executable; chmod +x
```
`plugin.toml`:
```
name = "kubectl_query"
version = "0.1.0"
description = "Query a Kubernetes cluster. Input: 'get|describe|logs [name]'."
entrypoint = "run" # relative path inside the plugin dir; default "run"
requires_confirmation = true # keep true unless the plugin is purely read-only
timeout_secs = 30 # optional; falls back to AICTL_SECURITY_SHELL_TIMEOUT
schema_hint = """
First line: subcommand (get|describe|logs)
Second line: resource type
Third line (optional): resource name
"""
```
通信协议:
- **stdin** — LLM 发出的原始 `… ` 正文,与其传递给内置工具的内容完全一致。没有 JSON 帧。
- **stdout** — 原样返回给 LLM 的结果字符串(经过 `` 标签转义后)。
- **退出码** — `0` 表示成功;非零值将作为 `[exit N] ` 报告给 LLM。成功时冗长的 stderr 将被抑制。
- **环境** — 与 `exec_shell` 使用的相同清理后的环境(去除了密钥 / `_KEY` / `_TOKEN` / `_PASSWORD`)。
- **工作目录** — 固定在安全 CWD 监狱中。
插件受 `AICTL_PLUGINS_ENABLED=true`(默认 `false`)门控 — 第三方代码不会自动加载。发现仅在启动时进行一次;重启 aictl 以识别新插件。格式错误的清单、缺失的入口点或逃离插件目录的符号链接会导致该单个插件被跳过并发出 stderr 警告,但绝不会导致启动失败。
CLI 接口:
- `aictl --list-plugins` — 非交互式列表(名称、描述、位置)。
- `/plugins`(REPL)— 列出清单,查看插件的 `plugin.toml`,切换主开关,显示插件目录。
标准安全门(`security::validate_tool`)在调度前运行,因此 `AICTL_SECURITY_DISABLED_TOOLS` 可以像禁用内置工具一样禁用插件名称,确认提示照常触发,并且 `--unrestricted` 会像绕过内置工具一样绕过验证。要在不触及清单的情况下静音某个插件,请将其添加到 `AICTL_PLUGINS_DISABLED=foo,bar` 中。
参考 `echo_back` 插件位于 [`examples/plugins/echo_back/`](./examples/plugins/echo_back/) — 将该目录复制到 `~/.aictl/plugins/echo_back/` 并设置 `AICTL_PLUGINS_ENABLED=true` 进行试用。
### 钩子
钩子是用户定义的 shell 命令,由运行框架在生命周期事件时运行。将它们用于不属于代理提示的框架级别自动化 — 在每次编辑后运行 `cargo fmt`,阻止特定的 shell 命令,在压缩前快照记录,或将桌面通知镜像到 webhook。
钩子位于 `~/.aictl/hooks.json` 中(使用 `AICTL_HOOKS_FILE` 覆盖路径):
```
{
"PreToolUse": [
{ "matcher": "exec_shell", "command": "echo seen", "timeout": 30 }
],
"PostToolUse": [
{ "matcher": "edit_file|write_file", "command": "cargo fmt --message-format short 2>&1 | head -c 2000" }
],
"Stop": [
{ "matcher": "*", "command": "date '+turn ended at %H:%M:%S' >> /tmp/aictl-hook.log" }
]
}
```
每个钩子为 `{ matcher, command, timeout, enabled }`。`matcher` 是对工具名称(`exec_shell`、`read_*`、`edit_file|write_file`、`mcp__*__*`)的 glob 匹配(用于工具事件),或对非工具事件使用 `*`。`command` 在安全工作目录中通过 `sh -c` 运行,带有清理后的环境。`timeout` 默认为 60 秒;`enabled` 默认为 `true`。
支持的事件:
| 事件 | 触发时机 |
|-------|-------|
| `SessionStart` | REPL 启动;单次运行开始 |
| `SessionEnd` | REPL 退出;单次运行完成 |
| `UserPromptSubmit` | 按下 Enter 后,在注入防护之前。可以重写或阻止提示 |
| `PreToolUse` | 工具运行之前(以及在用户 y/N 确认之前)。可以拒绝或预先批准 |
| `PostToolUse` | 工具结果加入历史记录后。可以为下一轮附加 `additionalContext` |
| `Stop` | 代理给出最终答案后(无工具调用) |
| `PreCompact` | 在 `/compact` 总结对话之前 |
| `Notification` | 在 `notify` 工具内部,在 OS 弹窗之前。可以抑制嘈杂的警报 |
每个钩子在 stdin 上接收一个 JSON 有效载荷(`event`、`session_id`、`cwd`,加上 `tool` / `prompt` / `notification` / `trigger`,具体取决于事件),并可能在 stdout 上返回 JSON 以影响运行框架:
| 标准输出 | 效果 |
|--------|--------|
| 空 | 静默继续 |
| `{"decision":"block","reason":"..."}` | 中止操作;原因会展示给 LLM |
| `{"decision":"approve","reason":"..."}` | 预先批准工具调用 — 跳过用户的 y/N 提示 |
| `{"additionalContext":"..."}` | 在下一次 LLM 调用之前,将 `` 用户轮次注入历史记录 |
| `{"rewrittenPrompt":"..."}` | 仅限 `UserPromptSubmit` — 在代理看到用户文本之前替换它 |
| 纯文本 | 视为 `additionalContext` |
退出码 `2` 是 `{"decision":"block","reason":""}` 的简写。失败(spawn 错误、超时、非 2 的非零退出)会记录到 stderr 并被视为“继续”,因此损坏的钩子不会阻塞代理循环。
钩子是*运行框架*行为,而不是 LLM 行为 — `--unrestricted` 不会绕过它们。像“在 `edit_file` 之后始终运行 `cargo fmt`”这样的自动化规则属于这里,而不是在代理提示或记忆中。
CLI 接口:
- `aictl --list-hooks` — 非交互式列表(事件、匹配器、命令、状态)。
- `/hooks`(REPL)— 查看按事件分组的所有钩子,切换单个条目,使用合成有效载荷测试触发钩子,或从磁盘重新加载文件。
一个参考 `hooks.json`,每个事件都有一个示例(全部为 `enabled: false`,因此在您翻转它们之前不会触发),位于 [`examples/hooks.json`](./examples/hooks.json)。
### MCP 服务器
aictl 可以连接到[模型上下文协议](https://modelcontextprotocol.io)服务器,并将其工具与内置工具和插件一起合并到代理循环中。这解锁了现有的 MCP 生态系统 — 文件系统、git、GitHub、Postgres、Slack 以及数十个其他工具 — 而 aictl 无需单独集成每一个。第一阶段支持 **stdio** 传输和 **tools** 功能;HTTP/SSE 传输、资源和提示在路线图上。
服务器在 `~/.aictl/mcp.json` 中声明(使用 `AICTL_MCP_CONFIG` 覆盖路径),其形状与 Claude Desktop 兼容:
```
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/Documents"],
"enabled": true,
"timeout_secs": 30
},
"github": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/github/github-mcp-server"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${keyring:GITHUB_TOKEN}" }
}
}
}
```
每个条目的字段:`command` + `args`(通过 `PATH` 解析,无 shell),可选的 `env`、`enabled`、`timeout_secs`。`env` 内部的值可以使用 `${keyring:NAME}` 从系统密钥环中提取机密,而不是将其写入文件。整个子系统受 `AICTL_MCP_ENABLED=true`(默认 `false`)门控 — 第三方服务器进程不会自动生成。
在启动时,每个已启用的服务器并行生成,完成 JSON-RPC `initialize` 握手,并且服务器的 `tools/list` 响应将合并到代理循环的目录中。每个工具都可以作为 `mcp____` 访问,模型像调用任何内置工具一样调用它:
```
{"path": "/Users/me/Documents/notes.md"}
```
正文是一个与工具输入 schema 匹配的 JSON 对象(schema 附加到系统提示中,以便模型正确格式化调用)。失败的服务器记录在 `ServerState::Failed` 中,并且永远不会中止启动 — 单个损坏的条目不会破坏目录的其余部分。
安全模型:
- 每个 MCP 调用都通过与内置工具相同的 `security::validate_tool` 门。`AICTL_SECURITY_DISABLED_TOOLS` 接受合格的 MCP 名称(`mcp__github__create_issue`)。
- `AICTL_MCP_DENY_SERVERS=github,slack` 阻止来自列出服务器的每个工具,即使主开关已打开。
- 出站脱敏在无论何种传输方式下都对整个消息流运行,因此检测到的机密永远不会到达服务器。
- CWD 监狱**不**适用 — MCP 服务器运行在它们自己的进程中,拥有自己的权限。希望严格隔离的用户应保持 `AICTL_MCP_ENABLED=false` 或积极管理服务器列表。
CLI / REPL 接口:
- `aictl --list-mcp` — 非交互式列表(服务器名称、状态、工具计数、命令)。
- `aictl --mcp-server ` — 将此会话限制为仅命名的服务器(其他所有配置的服务器在该进程中被强制禁用;不持久化)。
- `/mcp`(REPL)— 列出服务器,浏览带有输入 schema 的每个服务器的工具目录,切换主开关,显示配置路径。
- `/info` 和欢迎横幅在启用时显示 MCP 服务器/工具计数。
一个捆绑的 `tiny_add` 冒烟测试服务器(Python,约 70 行,公开一个 `add` 工具)位于 [`examples/mcp/tiny_add/server.py`](./examples/mcp/tiny_add/server.py),完整注释的示例配置位于 [`examples/mcp.json`](./examples/mcp.json)。
### 配置
配置从 `~/.aictl/config` 加载。这是一个单一的全局配置文件。
此外,aictl 从当前工作目录加载项目提示文件(默认:`AICTL.md`)。如果存在,其内容将附加到系统提示中,从而允许为代理提供特定于项目的指令。可以通过 `~/.aictl/config` 中的 `AICTL_PROMPT_FILE` 自定义文件名。当配置的/默认文件缺失时,aictl 会回退到 `CLAUDE.md`,然后是 `AGENTS.md`,以便自动重用其他工具的现有项目指令;可以使用 `AICTL_PROMPT_FALLBACK=false` 禁用回退链。
最快的入门方法是交互式向导:
```
aictl --config
```
它将引导您选择提供商、模型和输入 API 密钥。您也可以随时手动编辑 `~/.aictl/config`。
#### 基本配置
您需要为要使用的提供商和模型配置 API 密钥。`AICTL_MEMORY` 和 `AICTL_INCOGNITO` 参数是可选的。
| 键 | 描述 |
|-----|-------------|
| `AICTL_PROVIDER` | 默认提供商(`openai`、`anthropic`、`gemini`、`grok`、`mistral`、`deepseek`、`kimi`、`zai`、`ollama`、`gguf`、`mlx` 或 `aictl-server`) |
| `AICTL_MODEL` | 模型名称 |
| `AICTL_MEMORY` | 记忆模式:`long-term`(所有消息,默认)或 `short-term`(滑动窗口) |
| `AICTL_INCOGNITO` | 启动交互式 REPL 而不保存会话。接受 `true` 或 `false`(默认:`false`) |
| `AICTL_PROMPT_FILE` | 从当前目录加载的项目提示文件的文件名(默认:`AICTL.md`) |
| `AICTL_PROMPT_FALLBACK` | 当主提示文件缺失时,回退到 `CLAUDE.md` 然后是 `AGENTS.md`。接受 `true` 或 `false`(默认:`true`) |
| `AICTL_TOOLS_ENABLED` | 启用或禁用所有工具调用。当为 `false` 时,LLM 只能用纯文本回复(默认:`true`) |
| `AICTL_AUTO_COMPACT_THRESHOLD` | REPL 自动压缩对话的上下文使用百分比。接受 `1..=100` 之间的整数(默认:`80`) |
| `AICTL_LLM_TIMEOUT` | 每次 LLM 响应超时时间(秒)。适用于每个提供商(远程 API、Ollama、原生 GGUF/MLX)以及压缩和代理生成调用。`0` 禁用超时。默认:`30` |
| `AICTL_MAX_ITERATIONS` | 单个代理轮次中允许的最大 LLM 调用次数,超过后循环将中止。接受正整数(默认:`20`) |
| `AICTL_SKILLS_DIR` | 覆盖技能目录的位置(默认:`~/.aictl/skills`) |
| `AICTL_CLIENT_HOST` | 上游 `aictl-server` 的基本 URL(例如 `http://127.0.0.1:7878`)。仅在活动提供商为 `aictl-server` 时使用;否则无效。空/未设置 = 直接提供商(默认) |
| `AICTL_CLIENT_MASTER_KEY` | 提交给配置的 `aictl-server` 的 Bearer token。与提供商密钥具有相同的 `/keys` 锁定/解锁/清除生命周期。与服务器的 `AICTL_SERVER_MASTER_KEY` 不同,因此单个主机可以明确地同时运行这两个角色 |
#### API 密钥
`FIRECRAWL_API_KEY` 是可选的,仅当您想使用 `search_web` 工具时才需要。
并非所有 API 密钥都是必需的。您只需为您设置了 `AICTL_PROVIDER` 和 `AICTL_MODEL` 的提供商提供密钥。
如果您想使用多个 LLM 提供商,则需要提供相应的密钥。
| 键 | 描述 |
|-----|-------------|
| `LLM_OPENAI_API_KEY` | OpenAI 的 API 密钥 |
| `LLM_ANTHROPIC_API_KEY` | Anthropic 的 API 密钥 |
| `LLM_GEMINI_API_KEY` | Google Gemini 的 API 密钥 |
| `LLM_GROK_API_KEY` | xAI Grok 的 API 密钥 |
| `LLM_MISTRAL_API_KEY` | Mistral 的 API 密钥 |
| `LLM_DEEPSEEK_API_KEY` | DeepSeek 的 API 密钥 |
| `LLM_KIMI_API_KEY` | Kimi (Moonshot AI) 的 API 密钥 |
| `LLM_ZAI_API_KEY` | Z.ai 的 API 密钥 |
| `LLM_OLLAMA_HOST` | Ollama 服务器 URL(默认:`http://localhost:11434`) |
| `FIRECRAWL_API_KEY` | Firecrawl 的 API 密钥(`search_web` 工具) |
##### 在哪里获取 API 密钥
每个提供商通过自己的开发者控制台颁发 API 密钥。注册,创建密钥,然后将其粘贴到 `~/.aictl/config` 中(或运行 `aictl --config`)。
| 提供商 | 控制台 URL |
|----------|-------------|
| OpenAI | [platform.openai.com/api-keys](https://platform.openai.com/api-keys) |
| Anthropic | [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) |
| Google Gemini | [aistudio.google.com/app/apikey](https://aistudio.google.com/app/apikey) |
| xAI Grok | [console.x.ai](https://console.x.ai) |
| Mistral | [console.mistral.ai/api-keys](https://console.mistral.ai/api-keys) |
| DeepSeek | [platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys) |
| Kimi (Moonshot) | [platform.moonshot.ai/console/api-keys](https://platform.moonshot.ai/console/api-keys) |
| Z.ai | [z.ai/manage-apikey/apikey-list](https://z.ai/manage-apikey/apikey-list) |
| Firecrawl | [firecrawl.dev/app/api-keys](https://firecrawl.dev/app/api-keys) |
Ollama、原生 GGUF 和原生 MLX 在本地运行,不需要 API 密钥。
#### 安全密钥存储(系统密钥环)
默认情况下,API 密钥以纯文本形式存储在 `~/.aictl/config` 中。aictl 还可以将它们存储在操作系统原生的密钥环中 — macOS Keychain 或 Linux Secret Service(通过 D-Bus 的 gnome-keyring / KWallet) — 并从拥有它们的任何存储中透明地读取它们。
活动的后端显示在欢迎横幅中(`keys: Keychain (2 locked · 1 plain · 0 both)`),`/security` 显示每个密钥的位置。
迁移是通过 REPL 内部的 `/keys` 交互式菜单完成的:
- **锁定密钥** — 将在 `~/.aictl/config` 中找到的每个纯文本密钥复制到系统密钥环中,并移除纯文本副本
- **解锁密钥** — 将每个密钥环条目复制回 `~/.aictl/config`,并从密钥环中删除它
- **清除密钥** — 从两个存储中移除密钥(需确认)
相同的操作也可作为一次性 CLI 标志使用:`--lock-keys`、`--unlock-keys`、`--clear-keys`。
当密钥环后端不可用时(例如,没有 Secret Service 守护进程的无头 Linux),aictl 会自动回退到纯文本存储,并且横幅会以黄色显示 `keys: plain text`。
#### 安全配置(可选)
| 键 | 描述 |
|-----|-------------|
| `AICTL_SECURITY` | 主安全开关(默认:`true`) |
| `AICTL_SECURITY_INJECTION_GUARD` | 阻止看起来像提示注入尝试的用户提示(默认:`true`) |
| `AICTL_SECURITY_CWD_RESTRICT` | 将文件工具限制在工作目录内(默认:`true`) |
| `AICTL_SECURITY_SHELL_ALLOWED` | 逗号分隔的允许 shell 命令白名单(空 = 除被阻止的命令外的所有命令) |
| `AICTL_SECURITY_SHELL_BLOCKED` | 额外被阻止的 shell 命令(添加到内置默认值中) |
| `AICTL_SECURITY_BLOCK_SUBSHELL` | 阻止 `$()`、反引号和进程替换(默认:`true`) |
| `AICTL_SECURITY_BLOCKED_PATHS` | 额外被阻止的文件路径(添加到内置默认值中) |
| `AICTL_SECURITY_ALLOWED_PATHS` | 工作目录之外允许的路径 |
| `AICTL_SECURITY_SHELL_TIMEOUT` | shell 命令超时时间(秒)(默认:`30`) |
| `AICTL_SECURITY_MAX_WRITE` | 最大文件写入大小(字节)(默认:`1048576` = 1 MB) |
| `AICTL_SECURITY_DISABLED_TOOLS` | 要禁用的逗号分隔的工具名称(例如 `exec_shell,search_web`) |
| `AICTL_SECURITY_BLOCKED_ENV` | 从 shell 子进程中清除的额外环境变量 |
| `AICTL_SECURITY_AUDIT_LOG` | 每次工具调用向 `~/.aictl/audit/` 追加一行 JSON(默认:`true`) |
| `AICTL_SECURITY_REDACTION` | 出站消息脱敏模式:`off`(默认)、`redact` 或 `block`。在 `redact` 模式下,线路上的每个凭据/PII 匹配项都会替换为 `[REDACTED:]`;在 `block` 模式下,轮次将中止并附带经过清理的错误。 |
| `AICTL_SECURITY_REDACTION_LOCAL` | 在发送到本地提供商(Ollama / GGUF / MLX)时也进行脱敏。默认 `false` — 对于这些提供商,数据永远不会离开机器,因此没有隐私收益。 |
| `AICTL_REDACTION_DETECTORS` | 内置检测器的逗号分隔子集(空 = 所有):`api_key`、`aws`、`jwt`、`private_key`、`connection_string`、`credit_card`、`iban`、`email`、`phone`、`high_entropy`。 |
| `AICTL_REDACTION_EXTRA_PATTERNS` | 分号分隔的 `NAME=REGEX` 对。每个匹配项都替换为 `[REDACTED:NAME]`(例如 `CUSTOMER_ID=CUST-\d{8};TICKET=JIRA-\d{4,}`)。 |
| `AICTL_REDACTION_ALLOW` | 分号分隔的正则表达式;任何跨度被允许列表命中覆盖的检测项都将被丢弃。适用于文档示例或触发熵扫描器的内部 ID。 |
| `AICTL_REDACTION_NER` | 启用可选的 Layer-C NER 传递(人物/位置/组织)。需要 `redaction-ner` cargo 特性并拉取模型。默认 `false`。 |
| `AICTL_REDACTION_NER_MODEL` | NER 模型规格(`owner/repo` 或 `hf:owner/repo`)。默认:`onnx-community/gliner_small-v2.1`。 |
| `AICTL_PLUGINS_ENABLED` | 插件子系统的主开关(默认:`false`)。插件是第三方代码;在您选择启用之前,它们不会自动加载。 |
| `AICTL_PLUGINS_DIR` | 覆盖插件发现根目录(默认:`~/.aictl/plugins`)。主要由测试和隔离安装使用。 |
| `AICTL_PLUGINS_DISABLED` | 要在加载时跳过的逗号分隔的插件名称。适用于在不编辑清单的情况下静音单个第三方插件。 |
| `AICTL_HOOKS_FILE` | 覆盖钩子配置路径(默认:`~/.aictl/hooks.json`)。主要由测试和隔离安装使用。 |
| `AICTL_MCP_ENABLED` | MCP 子系统的主开关(默认:`false`)。MCP 服务器是第三方进程;在您选择启用之前,它们不会自动生成。 |
| `AICTL_MCP_CONFIG` | 覆盖 MCP 配置路径(默认:`~/.aictl/mcp.json`)。 |
| `AICTL_MCP_TIMEOUT` | `tools/call` 的默认每次调用 RPC 超时时间(秒)(默认:`30`)。`mcp.json` 中 `timeout_secs` 设置的按服务器覆盖优先。 |
| `AICTL_MCP_STARTUP_TIMEOUT` | 每个服务器的 `initialize` 握手超时时间,以秒为单位(默认:`10`)。挂起的服务器标记为 `Failed` 并被跳过 — 启动永远不会因坏服务器而阻塞。 |
| `AICTL_MCP_DISABLED` | 要在加载时跳过的逗号分隔的 MCP 服务器名称,即使它们的 `enabled` 标志为 `true`。 |
| `AICTL_MCP_DENY_SERVERS` | 逗号分隔的 MCP 服务器名称,其所有工具在安全门处都被阻止,即使主开关已打开。 |
创建 `~/.aictl/config`(有关参考,请参见本仓库中的 `.aictl/config`):
```
AICTL_PROVIDER=anthropic
AICTL_MODEL=claude-sonnet-4-20250514
LLM_ANTHROPIC_API_KEY=sk-ant-...
FIRECRAWL_API_KEY=fc-...
```
文件格式支持注释(`#`)、带引号的值和可选的 `export` 前缀。
### 提供商
aictl 支持十一个 LLM 提供商 — 八个远程 API 以及 Ollama、通过 llama.cpp 的原生 GGUF 推理,以及在 Apple Silicon 上的原生 MLX 推理:
#### OpenAI
需要 `LLM_OPENAI_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `gpt-4.1-nano` | $0.10 | $0.40 |
| `gpt-4.1-mini` | $0.40 | $1.60 |
| `gpt-4.1` | $2.00 | $8.00 |
| `gpt-4o-mini` | $0.15 | $0.60 |
| `gpt-4o` | $250 | $10.00 |
| `gpt-5-mini` | $0.25 | $2.00 |
| `gpt-5` | $1.25 | $10.00 |
| `gpt-5.2` | $1.75 | $14.00 |
| `gpt-5.2-pro` | $30.00 | $180.00 |
| `gpt-5.4-nano` | $0.20 | $1.25 |
| `gpt-5.4-mini` | $0.75 | $4.50 |
| `gpt-5.4` | $2.50 | $15.00 |
| `gpt-5.4-pro` | $60.00 | $270.00 |
| `o4-mini` | $1.10 | $4.40 |
| `o3` | $2.00 | $8.00 |
| `o1` | $15.00 | $60.00 |
GPT-5.2 和 GPT-5.4 采用双层定价,在超过 272K 上下文阈值后价格翻倍;表中显示的是短上下文费率。aictl 中的成本计量器始终报告短上下文价格。
#### Anthropic
需要 `LLM_ANTHROPIC_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `claude-haiku-*` (3.x) | $0.25 | $1.25 |
| `claude-haiku-4-*` | $1.00 | $5.00 |
| `claude-sonnet-*` | $3.00 | $15.00 |
| `claude-opus-4-5-*` / `claude-opus-4-6-*` / `claude-opus-4-7-*` | $5.00 | $25.00 |
| `claude-opus-4-*` (较旧) | $15.00 | $75.00 |
#### Google Gemini
需要 `LLM_GEMINI_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `gemini-3.1-pro-preview` | $2.00 | $12.00 |
| `gemini-3-flash-preview` | $0.50 | $3.00 |
| `gemini-3.1-flash-lite-preview` | $0.25 | $1.50 |
| `gemini-2.5-pro` | $1.25 | $10.00 |
| `gemini-2.5-flash` | $0.30 | $2.50 |
| `gemini-2.5-flash-lite` | $0.10 | $0.40 |
Gemini 3.1 Pro 采用双层定价,在超过 200K 上下文阈值后价格翻倍;表中显示的是短上下文费率。`gemini-2.0-flash` 已从模型列表中移除,因为 Google 将于 2026 年 6 月 1 日将其关闭。
#### xAI Grok
需要 `LLM_GROK_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `grok-4.20-0309-reasoning` / `grok-4.20-0309-non-reasoning` | $2.00 | $6.00 |
| `grok-4` | $3.00 | $15.00 |
| `grok-4-fast-reasoning` / `grok-4-fast-non-reasoning` | $0.20 | $0.50 |
| `grok-4-1-fast-reasoning` / `grok-4-1-fast-non-reasoning` | $0.20 | $0.50 |
| `grok-3` | $3.00 | $15.00 |
| `grok-3-mini` | $0.30 | $0.50 |
Grok 4 Fast 和 Grok 4.20 附带 2M token 的上下文窗口,这是前沿模型中可用的最大上下文。
#### Mistral
需要 `LLM_MISTRAL_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `mistral-large-latest` | $2.00 | $6.00 |
| `mistral-medium-latest` | $0.40 | $2.00 |
| `mistral-small-latest` | $0.10 | $0.30 |
| `codestral-latest` | $0.30 | $0.90 |
#### DeepSeek
需要 `LLM_DEEPSEEK_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `deepseek-chat` | $0.28 | $0.42 |
| `deepseek-reasoner` | $0.28 | $0.42 |
#### Kimi
需要 `LLM_KIMI_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `kimi-k2.6` | $0.95 | $4.00 |
| `kimi-k2.6-thinking` | $0.95 | $4.00 |
| `kimi-k2.5` | $0.60 | $3.00 |
| `kimi-k2-0905-preview` | $0.60 | $2.50 |
| `kimi-k2-0711-preview` | $0.60 | $2.50 |
| `kimi-k2-turbo-preview` | $1.15 | $8.00 |
| `kimi-k2-thinking` | $0.60 | $2.50 |
| `kimi-k2-thinking-turbo` | $1.15 | $8.00 |
| `moonshot-v1-128k` | $2.00 | $5.00 |
| `moonshot-v1-32k` | $1.00 | $3.00 |
| `moonshot-v1-8k` | $0.20 | $2.00 |
#### Z.ai
需要 `LLM_ZAI_API_KEY`。支持的模型及成本估算(每 1M token 的输入/输出):
| 模型 | 输入 | 输出 |
|-------|-------|--------|
| `glm-5.1` | $1.40 | $4.40 |
| `glm-5-turbo` | $1.20 | $4.00 |
| `glm-5` | $0.72 | $2.30 |
| `glm-4.7` | $0.60 | $2.20 |
| `glm-4.7-flashx` | $0.07 | $0.40 |
| `glm-4.7-flash` | 免费 | 免费 |
| `glm-4.6` | $0.60 | $2.20 |
| `glm-4.5` | $0.60 | $2.20 |
| `glm-4.5-x` | $2.20 | $8.90 |
| `glm-4.5-airx` | $1.10 | $4.50 |
| `glm-4.5-air` | $0.20 | $1.10 |
| `glm-4.5-flash` | 免费 | 免费 |
| `glm-4-32b-0414-128k` | $0.10 | $0.10 |
#### Ollama
Ollama 在本地运行模型 — 不需要 API 密钥。从 [ollama.com](https://ollama.com) 安装 Ollama,拉取模型,并启动服务器:
```
ollama pull llama3.2
ollama serve
```
然后配置 aictl 以使用它:
```
AICTL_PROVIDER=ollama
AICTL_MODEL=llama3.2:latest
```
可用模型会通过 REST API 从您本地的 Ollama 实例中自动检测。`/model` 命令仅显示您在本地拉取的模型。如果 Ollama 未运行,它将不会出现在模型菜单中。
默认情况下,aictl 连接到 `http://localhost:11434`。要使用不同的地址,请在 `~/.aictl/config` 中设置 `LLM_OLLAMA_HOST`。
所有 Ollama 模型都是免费的(自托管),因此成本估算显示 $0.00。
任何模型字符串都可以通过 `--model` 传递;成本估算使用模型名称上的模式匹配,如果无法识别则回退到零。
#### 原生 GGUF (llama.cpp) — 实验性
aictl 可以通过 [`llama-cpp-2`](https://crates.io/crates/llama-cpp-2) 进程内运行 GGUF 模型 — 无需 Ollama 服务器。默认情况下,没有可用的本地模型;用户必须显式地逐一将它们下载到 `~/.aictl/models/gguf/` 中。
原生推理受 `gguf` cargo 特性门控。**在 GitHub Releases 上发布的预编译二进制文件(`install.sh` 下载的那些)附带了启用的 `--features gguf`**,因此通过一行命令安装的用户开箱即可获得原生 GGUF 推理 — 无需额外步骤。
从源代码构建时,`gguf` 特性**默认关闭**,以保持纯粹的 `cargo install aictl` / `cargo build` 在没有 C/C++ 工具链的情况下也能工作。显式选择启用:
```
cargo install --path crates/aictl-cli --features gguf
# 或
cargo build --release --features gguf
```
使用 `--features gguf` 构建需要 `cmake` 和可用的 C/C++ 编译器(macOS 上为 Xcode Command Line Tools,Debian/Ubuntu 上为 `build-essential`)。安装脚本回退路径(`cargo install --git ...`,在您的平台没有预编译二进制文件时触发)**不会**传递 `--features gguf`,因此会生成没有原生推理功能的二进制文件 — 在这种情况下,请使用上述命令手动重新构建。
**模型管理**(在每次构建中均可工作,即使没有 `--features gguf`):
```
# 从 Hugging Face 拉取 GGUF 模型
aictl --pull-gguf-model hf:bartowski/Llama-3.2-3B-Instruct-GGUF/Llama-3.2-3B-Instruct-Q4_K_M.gguf
# 简写形式
aictl --pull-gguf-model bartowski/Llama-3.2-3B-Instruct-GGUF:Llama-3.2-3B-Instruct-Q4_K_M.gguf
# 直接 URL
aictl --pull-gguf-model https://example.com/path/model.gguf
# 列出、移除、清除
aictl --list-gguf-models
aictl --remove-gguf-model Llama-3.2-3B-Instruct-Q4_K_M
aictl --clear-gguf-models
```
在 REPL 中,`/gguf` 会打开一个包含相同操作(查看已下载/拉取/移除/清除全部)的交互式菜单。下载通过进度条以流方式传输到 `~/.aictl/models/gguf/.gguf.part`,并在完成后进行原子重命名,因此中断的下载绝不会留下写了一半的模型。
一旦模型被下载,它就会出现在 `/model` 选择器中的 **原生 GGUF** 标题下,与 Ollama 模型并列。将其配置为默认值:
```
AICTL_PROVIDER=gguf
AICTL_MODEL=Llama-3.2-3B-Instruct-Q4_K_M
```
推理在 `tokio::spawn_blocking` 任务上运行,因此它不会阻塞异步运行时。成本始终显示 $0.00。消息被展平为 ChatML 风格的提示,这对于现代指令微调模型效果很好;特定于模型的聊天模板可能会在以后添加。如果您尝试在没有 `--features gguf` 的构建中使用 GGUF 模型,aictl 将打印明确的错误并告诉您重新构建。
##### 经过测试的 GGUF 模型
以下模型已通过 `/gguf` 拉取菜单的预定义目录进行端到端(下载、加载、推理、工具调用)验证:
| 模型 | 拉取命令 |
|-------|--------------|
| `Qwen3-4B-Q4_K_M` | `aictl --pull-gguf-model lmstudio-community/Qwen3-4B-GGUF:Qwen3-4B-Q4_K_M.gguf` |
#### 原生 MLX (Apple Silicon) — 实验性
aictl 可以通过 [`mlx-rs`](https://crates.io/crates/mlx-rs) 进程内运行 MLX 模型 — 无需 Python、无需 `mlx_lm`、无需单独的服务器。来自 [`mlx-community`](https://huggingface.co/mlx-community) Hugging Face 组织的量化 4 位权重通过 `safetensors` 直接加载。默认情况下,没有可用的本地 MLX 模型;用户必须将其显式下载到 `~/.aictl/models/mlx//` 中。
GitHub Releases 上的 macOS Apple Silicon 预编译二进制文件附带了启用的 `--features mlx`,并在安装时包含了一个放置在二进制文件旁边的同级 `mlx.metallib` 文件(MLX 的第一个运行时回退是 `/mlx.metallib`)。其他平台的版本仅包含 `aictl` 二进制文件 — 它们不支持 MLX。
原生推理受 `mlx` cargo 特性门控。从源代码构建时,`mlx` 特性**默认关闭**。显式选择启用(仅限 Apple Silicon):
_BLOCK_26/>
使用 `--features mlx` 构建需要 **Xcode Metal Toolchain**(完整的 Xcode,不仅是 Command Line Tools)。通过 Xcode → Settings → Components 安装,或使用 `xcodebuild -downloadComponent MetalToolchain`。使用 `xcrun --find metal` 进行验证。
**模型管理**(在每次构建中均可工作,即使没有 `--features mlx` 甚至在非 Apple Silicon 主机上):
```
# 从 Hugging Face (mlx-community) 拉取 MLX 模型
aictl --pull-mlx-model mlx:mlx-community/Llama-3.2-3B-Instruct-4bit
# 简写形式
aictl --pull-mlx-model mlx-community/Qwen2.5-7B-Instruct-4bit
# 列出、移除、清除
aictl --list-mlx-models
aictl --remove-mlx-model mlx-community__Llama-3.2-3B-Instruct-4bit
aictl --clear-mlx-models
```
在 REPL 中,`/mlx` 会打开一个包含相同操作以及流行 `mlx-community` 仓库精选目录的交互式菜单。下载以每个文件进度条流式传输多文件 safetensors 目录。
一旦模型被下载,它就会出现在 `/model` 选择器中的 **MLX (Apple Silicon)** 标题下。将其配置为默认值:
```
AICTL_PROVIDER=mlx
AICTL_MODEL=mlx-community__Llama-3.2-3B-Instruct-4bit
```
推理在 `tokio::spawn_blocking` 任务上运行,因此它不会阻塞异步运行时。成本始终显示 $0.00。如果您尝试在没有 `--features mlx` 的构建中或在非 Apple Silicon 主机上使用 MLX 模型,aictl 将打印清晰的错误说明此限制。
##### 经过测试的 MLX 模型
以下模型已在 Apple Silicon 上端到端(下载、加载、推理、工具调用)验证:
| 模型 | 拉取命令 |
|-------|--------------|
| `mlx-community__DeepSeek-R1-Distill-Qwen-7B-4bit` | `aictl --pull-mlx-model mlx-community/DeepSeek-R1-Distill-Qwen-7B-4bit` |
| `mlx-community__Llama-3.2-3B-Instruct-4bit` | `aictl --pull-mlx-model mlx-community/Llama-3.2-3B-Instruct-4bit` |
| `mlx-community__gemma-2-9b-it-4bit` | `aictl --pull-mlx-model mlx-community/gemma-2-9b-it-4bit` |
### 成本估算
上文的每 token 表格告诉您每个模型的收费标准;它们并没有告诉您实际工作日的真实成本。为此,请参阅 [LLM_PRICING.md](LLM_PRICING.md) — 它模拟了两种使用模式(聊天助手和编码代理),并报告了目录中每个模型的每日和每月总计。
高强度使用的标题数字(每天 150 个聊天轮次或 50 个编码任务,每月 22 个工作日,缓存定价):
| 使用模式 | 最便宜 | 旗舰集群 | Opus 4.6 |
|---|---|---|---|
| 聊天 | **$2.64/月** (grok-4-fast) | ~$35–$48/月 | $69.74/月 |
| 编码代理 | **$34.76/月** (grok-4-fast) | ~$460–$525/月 | $874.50/月 |
在您做预算之前,有几件事值得了解:
- **高强度编码代理的使用成本大约是聊天使用的 60 倍**,对于任何给定模型都是如此,因为代理循环在每次迭代时都会重新发送不断增长的对话历史,并生成长且代码密集的输出。工具调用计数不是主导因素。
- **提示缓存可将成本大致减半**,但“缓存”列仅对 Anthropic 可靠 — aictl 通过 `cache_control` 标记显式写入 Anthropic 的提示缓存。OpenAI、Gemini、Grok、DeepSeek 和 Kimi 在服务器端自动缓存,因此您将在持续会话期间达到缓存费率,但在超过提供商 TTL(通常为 5-10 分钟)的空闲间隔之后则不会。Z.ai GLM 和 Mistral 在 aictl 中没有缓存处理,因此它们始终按全费率计费。
- **aictl 在每次轮次后打印的成本计量器**反映了每个提供商响应中实际缓存与新鲜 token 的对比,因此它比任何估算都更准确。如果您想知道您的特定工作负载的实际成本,请运行几个典型的会话并观察每轮摘要。
### 代理循环与工具调用
aictl 运行一个代理循环:LLM 可以调用工具,查看其结果,并继续推理,直到产生最终答案。
默认情况下,每个工具调用都需要确认(y/N 提示)。使用 `--auto` 跳过确认并自主运行。
可用工具:
| 工具 | 描述 |
|------|-------------|
| `exec_shell` | 通过 `sh -c` 执行 shell 命令 |
| `read_file` | 读取文件内容 |
| `write_file` | 向文件写入内容(第一行 = 路径,其余 = 内容) |
| `remove_file` | 移除(删除)一个文件(仅限常规文件,不适用于目录) |
| `create_directory` | 创建一个目录及任何缺失的父目录 |
| `list_directory` | 列出路径下的文件和目录,带有 `[FILE]`/`[DIR]`/`[LINK]` 前缀 |
| `search_files` | 按模式(grep regex)搜索文件内容,可选目录范围 |
| `edit_file` | 对文件应用定向的查找和替换编辑(需要精确的唯一匹配) |
| `diff_files` | 比较两个文本文件并返回带有 3 行上下文的统一 diff。第一行是“之前”的路径,第二行是“之后”的路径。通过 LCS DP 表在进程内工作 — 无需外部 `diff` 二进制文件,无平台差异。拒绝 diff 超过 2000 行的文件 |
| `search_web` | 通过 Firecrawl API 搜索网络(需要 `FIRECRAWL_API_KEY`) |
| `find_files` | 查找匹配 glob 模式的文件(例如 `**/*.rs`),可选基础目录 |
| `fetch_url` | 获取 URL 并返回可读的文本内容(剥离 HTML 标签) |
| `extract_website` | 获取 URL 并仅提取主要的可读内容(剥离脚本、样式、导航、样板文本) |
| `fetch_datetime` | 获取当前日期、时间、时区和星期几 |
| `fetch_geolocation` | 通过 ip-api.com 获取 IP 地址的地理位置数据(城市、国家、时区、坐标、ISP) |
| `read_image` | 从文件路径或 URL 读取图像以进行视觉分析(PNG、JPEG、GIF、WebP、BMP、TIFF、SVG、ICO) |
| `generate_image` | 通过 DALL-E、Imagen 或 Grok 从文本描述生成图像(根据可用密钥自动选择提供商;将 PNG 保存到当前目录) |
| `read_document` | 读取 PDF、DOCX 或电子表格并将内容提取为 markdown 文本。支持 `.pdf`、`.docx`、`.xlsx`、`.xls`、`.ods`。PDF 文本直接提取;DOCX 转换为 markdown;电子表格转换为 markdown 表格(每个工作表一个) |
| `git` | 运行受限的 `git` 子命令(无 shell)。允许 `status`、`diff`、`log`、`blame`、`commit` 并带有按子命令的标志允许列表。危险标志(`-c`、`-C`、`--ext-diff`、`--upload-pack`、`--exec-path`、`--no-verify`、`--amend`、`--git-dir`、`--work-tree`)和所有其他子命令将被拒绝。可能重定向子进程的环境变量(`GIT_DIR`、`GIT_SSH_COMMAND`、`GIT_CONFIG_*`、editor/askpass)将被清除 |
| `run_code` | 在选定的解释器中执行简短的代码片段并返回 stdout/stderr。第一行是语言(`python`、`node`、`ruby`、`perl`、`lua`、`bash`、`sh`);其余行通过 stdin 管道传递给解释器(无临时文件)。适用于快速计算、数据转换和一次性逻辑检查。与 `exec_shell` 共享 shell 超时、环境清除器和
- **注入防护**:用户提示词在发送到 LLM 之前会进行扫描。包含指令覆盖短语("ignore previous instructions"、"disable security" 等)或伪造的角色/工具标签(``、``、`### System:` 等)的输入会被阻止并返回明确的错误信息。使用 `AICTL_SECURITY_INJECTION_GUARD=false` 可禁用此功能。
- **审计日志**:每次工具调用都会在 `~/.aictl/audit/` (JSONL) 中追加一行 JSON 数据,包含时间戳、工具名称、截断的输入以及结果标签(`executed` + `result_summary`、`denied_by_policy` + `reason`、`denied_by_user`、`disabled`、`duplicate`)——这与会话历史是分开的,以便审查者可以准确重构模型运行的内容。文件名与 `~/.aictl/sessions/` 下的会话文件相对应。在无痕模式和单次运行中会跳过此功能。使用 `AICTL_SECURITY_AUDIT_LOG=false` 可禁用此功能。
- **敏感数据脱敏**(需选择启用):每条出站消息体在到达远程提供商之前,都可以对其进行凭据和个人身份信息 (PII) 屏蔽。设置 `AICTL_SECURITY_REDACT=redact` 可启用,将匹配到的内容在线上替换为 `[REDACTED:]`,或设置 `=block` 以在匹配到任何内容时中止当前轮次。Layer A:针对 API 密钥 (OpenAI / Anthropic / Google / GitHub / Stripe / Slack / HuggingFace / Groq)、AWS 访问密钥、JWT(带有 base64 头部健全性检查)、PEM 私钥、数据库/AMQP 连接字符串、电子邮件、上下文门控电话号码、信用卡 (Luhn)、IBAN (mod-97) 的正则表达式检测器。Layer B:用于不透明 token 的香农熵扫描器。Layer C(可选的 `redaction-ner` cargo feature + 拉取的 GLiNER 模型):人员/位置/组织检测。用户提供的 `AICTL_REDACTION_EXTRA_PATTERNS` 和 `AICTL_REDACTION_ALLOW` 用于调整检测器。本地提供商 (Ollama / GGUF / MLX) 默认绕过此检查。每个脱敏事件都会记录在审计日志中;持久化的会话文件始终保留用户的原始文本。
安全拒绝会作为工具结果返回给 LLM(以红色显示),以便其进行调整。使用 `--unrestricted` 可禁用所有安全检查。各项设置可通过 `~/.aictl/config` 中的 `AICTL_SECURITY_*` 键进行配置。审计日志和脱敏层是可观察性和隐私控制手段,而非工具调用的强制执行,因此除非配置键将其关闭,否则即使使用 `--unrestricted` 它们也会继续运行。
### 示例
```
# 在 ~/.aictl/config 中配置好默认值后,只需运行:
aictl
# 或者发送单条消息:
aictl --message "What is Rust?"
# 从命令行覆盖 provider/model:
aictl --provider openai --model gpt-4o --message "What is Rust?"
# 带 tool calls 的 Agent (交互式确认)
aictl --message "List files in the current directory"
# Autonomous mode (无确认提示)
aictl --auto --message "What OS am I running?"
# Quiet mode (仅最终答案,无 tool calls 或 reasoning)
aictl --auto --quiet --message "What OS am I running?"
```
## 测试
```
cargo test
```
单元测试涵盖了六个模块的核心逻辑:`commands`(斜杠命令解析)、`config`(配置文件解析)、`tools`(工具调用 XML 解析)、`ui`(格式化辅助)、`llm`(成本估算和模型匹配)以及 `security`(shell 验证、路径验证、输出清理)。`session` 模块负责处理 `~/.aictl/sessions/` 下 REPL 对话的持久化。
## 路线图
有关计划中的功能和未来方向,请参阅 [ROADMAP.md](ROADMAP.md),包括新工具、UX 改进、桌面应用计划和编程智能体能力。
## 架构
有关以下内容的详细 ASCII 图表,请参阅 [ARCH.md](ARCH.md):
- 模块结构
- 启动流程
- Agent 循环
- 工具执行调度
- LLM 提供商抽象
- UI 层
- 端到端数据流
## Claude Code 技能
本项目包含用于常见工作流的 [Claude Code](https://claude.ai/code) 技能。可以在 Claude Code 会话中将它们作为斜杠命令运行:
| 技能 | 描述 |
|-------|-------------|
| `/commit` | 使用清晰的提交消息提交已暂存和未暂存的更改 |
| `/update-docs` | 更新 README.md、CLAUDE.md 和 ARCH.md 以匹配当前项目状态 |
| `/evaluate-rust-quality` | 审计代码质量、惯用 Rust 用法及最佳实践 |
| `/evaluate-rust-security` | 审计安全态势、注入风险和凭据处理 |
| `/evaluate-rust-performance` | 审计性能模式、内存分配和 CLI 响应能力 |
| `/project-stats-report` | 生成项目统计报告(代码行数、提交活动、贡献者等) |
| `/sync-models` | 检查每个提供商是否有新发布的模型,并更新支持的模型集合和 README |
| `/create-hook` | 向 `~/.aictl/hooks.json` 添加生命周期钩子(事件、匹配器、命令、超时) |
| `/add-mcp-server` | 通过向 `~/.aictl/mcp.json` 添加条目来连接 MCP 服务器 |
评估报告将保存至 `.claude/reports/`,文件名带有时间戳。
## 许可证
本项目采用 [PolyForm 非商业许可证 1.0.0](LICENSE) 进行许可。可免费用于非商业用途,包括个人使用、研究、教育以及非营利组织使用。如需商业使用,请联系 [piotr@wittchen.io](mailto:piotr@wittchen.io)。
标签:AI代理, AI助手, Apex, Apple Silicon, DLL 劫持, GGUF, HTTP代理, llama.cpp, LLM代理, LLM评估, Mac, MLX, Ollama, Rust, 云模型, 人工智能, 可视化界面, 大语言模型, 安全, 开源, 服务枚举, 本地模型, 机器学习, 桌面应用, 模型代理, 用户模式Hook绕过, 终端, 网络流量审计, 网络调试, 自动化, 调试插件, 超时处理, 通知系统