Mafdet AI 帮助中心English

Mafdet CLI

@mafdet/cli 是官方命令行:调用模型、查询账户,以及运行一个受权限约束的本地 Agent,在你自己的机器上读取和修改代码。Agent 的工具在本地执行——服务端只返回 结构化的 tool call,不放宽任何服务端 Agent 权限。

需要 Node.js 20 或更高。

安装

npm install -g @mafdet/cli

也可以免安装直接运行:

npx @mafdet/cli doctor

交互式会话

在终端里不带参数直接敲 mafdet 就进入会话:选认证方式、选模型,然后和 Agent 对话。

mafdet                       # 只读
mafdet --allow-write         # 改动先展示 diff 再确认
mafdet --allow-command "pnpm test"

它和 mafdet agent同一个 Agent,只是画法不同——同样的工具、同样的审批、 同样的计费。参数含义与那边完全一致,两个都不给的会话根本没有加载写工具和命令工具。

管道里、--json 下、CI 中、TERM=dumb、或带 --no-tui 时,mafdet 仍然是把用法写 stderr 并 exit 2,与之前完全一样。任何读取 CLI 输出的程序都不会突然收到一个界面。

快速开始

export MAFDET_API_KEY="sk-mafdet-live-..."
export MAFDET_MODEL="deepseek-v4-flash"

mafdet doctor                 # Key、端点、模型、余额、工作区、git 一次查完
mafdet models list            # 这把 Key 实际能调用的模型
mafdet chat "解释一下 TypeScript 装饰器"
mafdet account balance

出问题时先跑 mafdet doctor。它会检查 Node、两个端点、Key、工作区、git、 两个 API 面、选定模型、该模型的工具调用能力和余额,并且只有真正阻断的问题才判 失败——缺一个可选 scope 只是警告,不会误报成错误。

PowerShell

$env:MAFDET_API_KEY = "sk-mafdet-live-..."
$env:MAFDET_MODEL   = "deepseek-v4-flash"

mafdet doctor

所有用户可见输出都是纯 ASCII,因此在非 UTF-8 代码页的控制台(Windows PowerShell 5.1 的默认状态,中文系统为 cp936)也不会变成乱码。PowerShell 默认按 UTF-16 走管道, 所以请把 prompt 作为参数传入,或使用 --input <文件>,而不要用管道。

命令

命令作用
mafdet doctor一次检查 Node、端点、Key、工作区、git、模型与工具调用、余额
mafdet models list [--surface chat|embeddings|speech] [--agent]这把 Key 能调用的模型,并附上目录元数据
mafdet models show <id>单个模型详情,含 Agent 是否可以驱动它
mafdet chat [提示词] [--model] [--system <文件>] [--input <文件>]发一次对话,默认流式
mafdet agent "<目标>"本地 Agent,默认只读
mafdet agent交互会话(需要终端)
mafdet embed [文本|<文件>] --model <id> [--output <文件>]文本转向量
mafdet speech [文本|<文件>] --model <id> --output <文件> --voice文本转音频
mafdet account balance|usage|subscription钱包、用量、套餐(需 account:read scope)
mafdet sessions list|show|usage|delete保存在这台电脑上的会话(不会调用模型)
mafdet sessions usage <id> --refresh在本地估算旁显示账单账本的已结算金额
mafdet config list当前生效的配置及其来源

--json 输出一份完整 JSON 文档;--plain 输出无表头的 TSV,方便 cutawk 处理。

Agent 的权限模型

默认只读:可以列目录、搜索、读文件、看 git status / git diff不能改 任何东西。

--allow-write 才会加上 edit_filecreate_file,并且:

  • 每次改动都先展示 diff 再询问,回车即拒绝;
  • 非交互环境一律不给写权限,即使显式传了该参数——此时写工具根本不会提供给模型;
  • 没有任何"全部同意"的开关

批准一条命令,意味着允许那个程序在你的机器上、以你的身份运行。 工作区限定的是 Agent 自己的工具能碰哪些文件,它不是沙箱,也约束不了那个程序。 我们会拒绝一小份明显破坏性的名字(sudosudoaschownshutdownreboot, 以及按路径调用),但请把它当作防手滑的护栏,而不是隔离

--allow-command "<前缀>" 才会加上 run_command,且只对这些命令前缀免提示: pnpm test 放行 pnpm test --filter web,但不放行 pnpm publish没有 shell——命令被切成 argv 直接执行,所以管道、重定向、;&&、反引号、 $( ) 一律被拒绝并说明原因,而不是尝试"消毒"。

看起来像密钥的文件——.env*、私钥、id_rsa*kubeconfigcredentials*.npmrc,以及 .ssh.aws.gnupg.docker.kube 整个子树——一律拒绝, 没有任何总开关可以绕过。工作区边界按真实路径判定,符号链接无法指向工作区外。

会话内命令:/model/permissions/diff/cost/compact/exit

哪些模型可以驱动 Agent

只有工具调用经过端到端实测验证的模型。看 AGENT 列:

mafdet models list --agent

未验证的模型会被直接拒绝而不是先试再说,免得你为一次跑到一半失败的任务付钱。 mafdet models show <id> 会说明某个模型属于哪种情况。

凭据

Key 只从 MAFDET_API_KEY 读取。刻意不提供 --api-key 参数——那会把 Key 写进 shell 历史和进程列表。Key 不会被写入任何配置文件,也不会完整出现在任何输出里, 只以 sk-mafdet-live-<redacted> 这样的指纹形式展示。

项目可以放一个 .mafdet.json,但只允许 model 一项。 里面出现凭据或端点会直接报错:克隆一个仓库绝不该改变你的 Key 发往哪里。

mafdet account ... 需要 Key 带 account:read scope(在 API Keys 里创建)。没有它其他命令照常可用。

退出码

脚本可以据此分支。

含义
0成功
1一般失败(含 doctor 有检查项未通过)
2命令行或配置错误
3认证或权限失败
4模型或 API 不可用
5本地权限被拒绝
6用户取消
7达到费用、时间或轮次上限

结果与机器可读的 JSON 走 stdout;进度、警告、摘要、审批提示走 stderr。 所以 mafdet chat ... > answer.txt 只会拿到答案本身,而 mafdet models list --json | jq 永远能解析。

保存下来的会话

交互式会话会保存在这台电脑上,也只在这台电脑上。它们不会上传,Mafdet 没有副本。

这是关于存档的说法,不是关于模型的。你发送的消息仍然会送到 API 去作答, 仍然出现在你的用量记录里;留在本地的是那份保存下来的副本。

平台路径
Linux / WSL${XDG_STATE_HOME:-~/.local/state}/mafdet/sessions
macOS~/Library/Application Support/mafdet/sessions
Windows%LOCALAPPDATA%\mafdet\sessions

这些文件是明文。一份存档包含你的消息、模型的回复,以及 agent 工作时读过的任何源码, 所以请把会话目录当作它所对应的那个项目本身来对待。API Key 是唯一的例外: 所有内容在写盘前都会过一遍脱敏,你粘进提示词里的 Key 会以 <redacted> 的形式存下来。

Agent 读不到这些目录——即使你在家目录里运行 mafdet、存档实际落在工作区内也一样。

mafdet --no-history            # 这一次运行完全不记录
mafdet chat "..." --save       # 一次性对话只有明确要求时才保存
mafdet sessions list           # 已保存的会话;没有时会告诉你路径
mafdet sessions delete <id> --yes

一次 mafdet chat 不是有人会去恢复的对话,所以不带 --save 就不保存--no-history 仍然压过 --save;被 Ctrl+C 取消的对话完全不保存。

删除会移除本地消息和这个会话的用量映射。它不会移除 API 用量、账单记录或扣费—— 那些属于 API Key,不属于存档。而且它只是一次普通的文件删除,不是安全擦除: 备份、快照和文件系统本身仍可能保有副本。

对账:这次会话到底花了多少

mafdet sessions usage <id> 从本地记录累加一次会话的用量。那些金额是估算, 算法与网关一致,但是在你的机器上算的。

--refresh 会按会话时间窗口和游标查询当前 API Key 的用量事件;request ID 只留在本地, 用于匹配账本返回的记录。它不发送消息、标题、工作区路径或 session ID。由另一把 API Key 支付的请求会被跳过并如实告知,好让你知道该换那把 Key 再跑一次。

账本还没结算的请求保持 pending,从未拿到 ID 的请求保持 unknown两者都不会显示为 0——0 读起来像「免费」。

费用

chat 会在 stderr 打印 token 数与预估费用,算法与网关计费一致, 但以钱包为准——参见用量与计费

Ctrl+C 会关闭连接。实测中被取消的流式请求没有产生费用,但这是一次观察结果、 不是保证:如果上游已经生成完毕,仍可能产生扣费。因此取消后的摘要标注为 partial:

已知限制

以下限制是主动写出来的,不是等你去发现的:

  • macOS 与 Windows 尚未验收。 已在真实终端验过的是 Linux、WSL、tmux、SSH 以及 SSH + tmux,Node 20 和 22 都过。
  • Windows 上的命令超时终止:已实现,但未验证。 POSIX 走进程组信号,Windows 走 taskkill /T;该调用的形状有测试,但从未在真 Windows 上执行过, 所以它是否真的能杀到每一个孙子进程属于未知。只影响 --allow-command
  • /compact 是截断历史,不是生成摘要。长时间运行在接近上下文上限时也会自动压缩, 丢掉最早的若干次工具往返——只影响发出去的内容,本地存档不受影响
  • --json 形状与退出码的兼容承诺自 1.0.0 起正式生效;当前是 0.x, 按 semver 次版本号仍允许破坏性变更。

下一步