Magent Doctor
用途
/doctor 和 M-x magent-action-run-doctor 用于诊断 Magent、Emacs runtime
和当前项目状态,但不会把通用 Emacs 或 shell 工具交给 LLM。两个入口执行同一个
Action,并在 magent-session-directory/actions/doctor 下创建独立 Action session。
M-x 入口启动后会立即显示一个只读 Org *Magent Doctor* buffer。持续保留的 Preflight、
runtime/package 版本、Doctor 实际使用的 model route、结构化 probe tasks 和最终
诊断都显示在同一个 buffer 中。Probe heading 会在 TODO~、~DONE~、~FAIL 和
KILL 之间变化。Probe 结果在分析前会限长并脱敏;task 只额外标记 omitted 和
failure。如果 probe 读取的内容已经显示在某个 live Emacs buffer 中,task 会链接到
该 buffer,而不复制冗长内容。独立 session 落盘后,其 session id 会链接到只读
Action session viewer;该链接使用标准 Org link 语义,因此 embark-dwim 等
Org-aware 命令也能打开它。
Buffer 保留 ~#+startup: content~。Tasks 和 Diagnosis 是主要一级章节;Runtime 和 Doctor model 归入 Environment,Preflight 保留在末尾。等待确认时自动展开 Preflight,运行结束时自动展开 Diagnosis。
使用 /doctor select 或给 M-x 命令传递 prefix argument,可以在 minibuffer 中
审查适用的 probes;
core runtime probe 始终保留。
信任边界
Doctor 分为两个阶段:
- 受信任、只读的 Elisp probes 采集有界结构化事实。
- 一次无工具的
gptel-request分析脱敏后的诊断 bundle。
Provider request 不包含工具,也不进入普通 Magent agent loop 或 runtime queue。它可以和普通对话并发,但不会把 Action session 安装成用户当前 session。~/doctor~ 使用发起请求的 runtime session 的有效 model route;M-x 入口回退到当前 gptel defaults。Sampling 使用 gptel streaming 路径,但 Doctor 只公开完成后的诊断结果。如果 gptel 在联系 provider 前同步失败,Doctor 会在 这个边界分类失败并给出可操作的 backend 配置提示,而不会采集或显示凭据值。
Doctor 不会主动采集 gptel backend 对象、API key、~auth-source~、环境变量、
HTTP headers 或原始 *gptel-log*~。绝对路径会被规范化为 ~$PROJECT~、
~$HOME 和 ~$TMP~。Probe 原始返回值不会持久化或写日志;只有经过递归
脱敏和限长的数据会进入 Action session 和 provider request。
脱敏属于纵深防御,不是 sandbox。自定义 probe 是受信任 Emacs Lisp, 权限等同于安装的 package。Magent 无法阻止恶意 Elisp 读取或修改用户状态; 扩展作者必须遵守只读契约。不支持或循环的数据结构会 fail closed,并在 发送 provider request 前终止。
内置 Probes
- ~core-runtime~:Magent、gptel、agent-shell、ACP 和 Emacs 版本,Magent source、mode、session、queue、approval,以及安全的 Doctor model-route metadata;不会序列化 provider backend 对象。
- ~current-buffer~:不含 buffer 内容的 metadata。
- ~project~:项目标识文件和只读 Git status。
- ~diagnostics~:已有 Flymake、Flycheck 和 Eglot 状态。
- ~compilation~:已有项目 compilation buffer 的有界尾部。
- ~magent-logs~:有界 Magent log,以及过滤后的相关 warnings/messages; 不读取原始 provider traffic。
- ~source-context~:point 附近的有界源码片段,仅允许手动选择。
Probes 默认串行运行。普通 probe error 或 timeout 会安全记录并继续;输出 校验或脱敏失败会终止整个运行,且不联系 provider。
扩展 Doctor
使用 magent-doctor-register-probe 注册受信任 probe:
(require 'magent-action-builtin-doctor)
(magent-doctor-register-probe
"my-runtime-check"
:description "Read-only status for my package"
:predicate (lambda (context)
(buffer-live-p
(magent-action-invocation-origin-buffer context)))
:collector (lambda (_context _state)
`((feature-loaded . ,(featurep 'my-package))))
:timeout 2
:data-categories '(runtime))
Probe ID 只能包含小写字母、数字、连字符和下划线,最长 64 字符。Collector 必须返回 JSON-safe 的字符串、数字、布尔值、symbol、vector、list、plist、 alist 或 hash table。Live buffer、process、backend struct 和循环值会被拒绝。
固定外部诊断可以使用 magent-doctor-run-process 并传递 executable 与 argv;
它不会启动 shell,并参与 Doctor timeout 和取消清理。Probe 不得 configure、
build、test、编辑或以其他方式修改项目。
Session 与取消
使用 M-x magent-action-list-sessions 查看结果。Viewer 会优先显示最终诊断,
默认折叠 probe activity;~TAB~ 切换当前 section,~S-TAB~ 切换全部 activity。
使用 M-x magent-action-cancel 取消活动 Doctor。在交互式 Doctor buffer 中,
也可以在未结束的 task 上按 ~C-c C-t~:该 heading 会标为 ~KILL~,并请求取消
整个 Doctor,而不是只跳过该 probe。取消会终止活动 probe process 或 abort
直接 gptel request,将 Action session 标记为 cancelled,并保持用户当前
session 不变。内置 Elisp probes 是短时同步读取,因此 task 取消通常在外部 probe
process 或 provider 分析阶段真正可操作。
配置
主要限制项包括:
magent-doctor-probe-timeoutmagent-doctor-process-timeoutmagent-doctor-total-timeoutmagent-doctor-max-diagnostic-charsmagent-doctor-max-probe-charsmagent-doctor-source-context-max-charsmagent-doctor-log-max-lines
magent-bypass-permission 只跳过 preflight confirmation,不会关闭采集限制、
路径规范化、脱敏或 provider 无工具边界。