关于 duoduo-runtime-admin
用于管理 Duoduo 主机模式运行时、守护进程设置和会话的运维技能。它指导操作人员选择运行时、修改配置、诊断问题、控制模型,并通过命令行管理会话和任务。
主要功能
- 01查看守护进程状态、配置和日志
- 02管理持久化主机设置
- 03选择并排查运行时
- 04控制会话模型和推理力度
- 05通过命令行管理会话
- 06维护记忆和用量记录
适用场景
- 01修改设置前诊断守护进程行为
- 02为频道或任务配置运行时
- 03更改会话模型或推理力度
- 04通知、安排或归档会话
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ openduo/ duoduo --skill duoduo-runtime-admin安装后在 Claude Code 中输入/duoduo-runtime-admin确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/codex-runtime.mdgrok-runtime.mdmemory-cli.mdmodel-context-profiles.mdmodel-defaults.mdmodel-switching.mdpi-runtime.mdruntime-settings.mdsession-cli.mdslash-commands.mdsubconscious-refresh.mdusage-archive.mdscripts/update_host_env.py详细介绍
Duoduo Runtime Admin
此技能负责主机模式运行时标志、守护进程诊断,以及 ~/.config/duoduo/.env 中的持久设置。
从运行时发现开始
- 使用
duoduo daemon status确认主机模式。 - 更改持久设置前,先读取
duoduo daemon config。 - 如果用户是在排查行为,而非请求更改配置,请使用
duoduo daemon logs。
请阅读 references/runtime-settings.md 了解主机模式的主要配置项;启用 Codex 前阅读 references/codex-runtime.md,启用 Grok 前阅读 references/grok-runtime.md,启用 Pi 前阅读 references/pi-runtime.md——其中的 Context and compaction 部分也介绍了 pi 会话开始只回复单个字符的情况(这是上下文窗口已满,并非模型故障)。
持久主机模式设置
需要获得可预测的结果时,请使用 scripts/update_host_env.py 编辑 ~/.config/duoduo/.env,而不要临时通过 shell 修改。
当用户询问 duoduo 本身是否已过时时,请检查:
duoduo --version
npm view @openduo/duoduo version
然后说明是否确实需要更新,再进行任何更改。
常见键:
ALADUO_DEFAULT_RUNTIMEALADUO_LOG_LEVELALADUO_LOG_RUNNER_THOUGHT_CHUNKSALADUO_LOG_SESSION_LIFECYCLEALADUO_TELEMETRY_ENABLEDALADUO_CADENCE_INTERVAL_MSALADUO_SPINE_INDEX_RETENTION_DAYSALADUO_CODEX_SANDBOX(codex 会自动检测;无需启用标志 — 请参阅 codex-runtime 参考文档)
更改守护进程环境设置后,请运行:
duoduo daemon restart -r "changed <setting>"
除非用户明确要求只编辑、不执行。
运行时选择
请准确说明:
- 如果未声明运行时,Claude 仍是保守的回退选项。
- 对于频道会话、作业和符合条件的后台分区,Claude、Codex、Grok 和 Pi 是同级运行时。Codex 和 Grok 会自动检测:安装 CLI 并登录(
codex login/grok login)。探测失败时会在下一条消息到来时重试,因此消息路由无需重启;设置卡中的运行时列表仍来自启动时的探测结果,要识别新安装,需要运行duoduo daemon restart。Pi 内置于 duoduo 中——无需安装,始终报告为可用,但每个 pi 会话都需要一个模型指针(provider/modelId),可来自作业 frontmatter、/model或分区 frontmatter。 - 运行时可以按操作者、按频道类型选择,也可以通过
ALADUO_DEFAULT_RUNTIME(claude、codex、grok或pi)全局选择。 - 如果 duoduo 不识别某个运行时值,就会拒绝该值,而绝不会替换为其他运行时:在
ALADUO_DEFAULT_RUNTIME中,守护进程不会启动;在频道描述符中,所选层级决定运行时的轮次会被拒绝(有效的实例值会覆盖未知的类型值);作业会失败;分区会被跳过——每种情况都会显示说明该值及有效值的句子。void是一种频道值,供 tether 等会话永不运行模型的插件使用;但它不能作为默认值,也不能用于作业或分区。 - 将工作路由到
codex之前,请确认已安装并完成身份验证。对于grok,duoduo 只检查二进制文件——将工作路由给它之前,请自行确认已登录。无法提供服务的显式 codex 或 grok 会导致硬性失败——该轮次会附带原因被拒绝,绝不会转由 Claude 执行。Pi 也采取相同策略:如果 pi 会话无法解析模型,就会失败,并在回复中说明修复方法,绝不会静默改由 Claude 执行。
切换会话的运行时
会话绑定到拥有其对话 ID 的运行时;不同运行时的历史记录不能互换。只更改 runtime 值——实例或类型描述符、ALADUO_DEFAULT_RUNTIME、任务 frontmatter——不会迁移现有会话。会话的下一轮请求将被拒绝(“Request was not executed”),并指出绑定的运行时、会话 ID 和配置的运行时。
- 唯一获准的切换方式:先对频道会话执行
/clear,然后更改运行时。在旧运行时下设置的/model覆盖会在切换到新运行时时丢弃;同一运行时下设置的/model覆盖在执行/clear后仍会保留,/effort也一样。 - 写入时拒绝:对实例执行
duoduo session config <target> set runtime=<rt>,以及会更改运行时的频道重新生成操作(例如设置卡片),如果该频道的任何会话绑定到其他运行时,就会被拒绝并列出这些会话——逐个执行/clear,然后重试。类型范围、环境变量和任务 frontmatter 的更改不会在写入时检查;受影响的会话会在下一轮请求时被拒绝。 - 恢复原状:将运行时恢复为绑定的运行时,然后重新发送消息——会话会正常恢复。
- 保留先前工作:真正切换前,旧会话的历史记录仍会以拒绝消息中指出的 ID 保存在磁盘上。让子 Agent 定位并总结这些记录,然后执行
/clear。 - 任务:运行时不再匹配的有状态任务会导致本次运行失败(
job.fail,唤醒所有者,并在失败退避时间后重试),直到所有者作出决定——恢复原运行时,或在新任务上开始工作。无状态任务不受影响。
潜意识刷新
<kernel>/subconscious/ 下的分区提示词不会因 npm install 升级而受到影响——安装只会合并缺失文件,并保留本地编辑和 Agent 的自我编程内容。用户需要随较新版本的 duoduo 更新分区提示词时,必须显式刷新。
进行任何更改前,请阅读 references/subconscious-refresh.md。其中介绍了前置条件(kernel Git 工作树干净,确认目标标签)、覆盖前先查看差异的规范、如何处理用户编写的分区和对已发布分区的本地编辑、作为回滚点的提交模式,以及刷新后为何无需重启守护进程。
内存维护中不使用 LLM 的机械性部分由 duoduo memory CLI 负责:lint 会将 .pending 信号写入分区收件箱,此外还包括手动的孤立项 reclaim 生命周期。操作员或分区需要直接使用时,请阅读 references/memory-cli.md。
执行节奏与遥测
- 更改执行间隔前,请说明缩短间隔会增加后台活动和令牌用量。
- 禁用遥测持久化会停止写入 JSONL,但不一定会抑制进程内的所有调试日志行。
- 在声称本机的默认值是什么之前,请使用
duoduo daemon config检查当前生效值。
使用记录维护
var/usage/<session_key>.jsonl 只允许追加写入,且不会自动清理——长期运行的主机会累积数百 MB。主机操作员(或用户提出请求时的此技能)会将过期文件归档到同级目录 var/usage-archive/<bucket>/。守护进程无需重启;它会在每次 usage.get 调用时扫描 var/usage/。
请阅读 references/usage-archive.md,了解已验证的 find -mtime +N | xargs mv 操作方法、恢复方式和竞态窗口说明。
斜杠命令(/compact、/model、/effort)
/compact 会就地缩小上下文窗口。它适用于每种运行时,并通过常规的通道消息流水线(spine → mailbox → drain)传递,因此命令完成时,用户会收到常规文本回复。
请阅读 references/slash-commands.md,了解运行时语义、命令似乎不起作用时的故障排除方法,以及如何向困惑的用户说明情况。
/model 可在运行时为会话切换模型,无需重启。请阅读 references/model-switching.md,了解语法、Claude 与 Codex 的时机差异,以及如何从无效的模型 ID 中恢复。在 Pi 上,/model 只会写入存储;会话的工作进程会在下一条消息到来时使用新模型重建 — 参见 references/pi-runtime.md。
如果用户想为多个会话而非单个会话指定模型 — 某种通道类型的所有会话,或整个主机 — 这属于模型默认值(claude.model / codex.model / pi.model / grok.model,0.8.1+),可通过 duoduo session config 在全局、类型或实例层级设置。请阅读 references/model-defaults.md,了解各个层级、优先级,以及 /model 现在会报告的两项内容:会话继承的配置层级,以及上一次回复实际使用的模型。用户说模型“无法固定”或“又变回旧模型”时,请查阅该文件 — 这两行信息就是诊断依据。
对于运行第三方模型的主机,模型配置档案会告知 duoduo 每个模型的实际上下文窗口、端点和凭据(按模型路由),以及子 Agent 层级别名(仅限 Claude 运行时 — codex 没有配置档案命名空间)。回答任何有关配置档案的问题前,请先阅读 references/model-context-profiles.md — 该文档以引导式操作指南的形式编写(添加模型 / 路由到端点 / 重新映射层级 / 故障排除 / 探测端点),其中包含可转述给用户的通俗表述,并在末尾列出供你自行核实的机制事实。它强制要求遵守的原则:妥善保管密钥(你可以收到人类通过聊天、环境变量或文件提供的密钥 — 但原始值绝不能出现在你输出的任何内容中;应立即将其存入配置档案存储,并确认值已遮蔽)、提供证据后再给出任何数字、执行会导致重建的写入操作前先确认。
/effort 用于设置模型在会话中的推理强度(low | medium | high | xhigh | max)— 这是独立于 /model 的一个维度。在 Claude 上会立即生效(不支持 max 的 Claude 模型会将 max 作为 high 运行);在 Codex 和 Pi 上则从下一条消息开始生效(在 Pi 上,各级别会映射到 pi 原生的思考级别)。无效值会立即被拒绝;在 Grok 上,级别必须是模型支持的值,否则更改会被拒绝。请参见 references/slash-commands.md 中的 /effort 部分。两个选项也可通过 CLI 按会话设置(0.8.0+),使用 duoduo session model / duoduo session effort — 参见 references/session-cli.md。
会话管理(duoduo session …)
这些子命令通过 CLI 管理会话(用户、通过 Bash 操作的 Agent 或外部脚本——共用一个入口):
duoduo session list [--kind …] [--named] [--json]— 查看实时路由表。duoduo session alias <key> "<name>"— 为会话设置便于识别的名称,以便在list中查看并用作notify目标。未命名的会话显示为—(不会自动使用其 key 命名)。duoduo session notify <target> -m "<msg>" [--force]— 通过 key 或别名联系会话,并发送带有来源标记的通知。仅允许channel/job目标;subconscious/kernel 平面处于隔离状态,因此会拒绝请求。如果某个 channel 会话已有一小时无人读取,则会以no_consumer拒绝(0.8.2+;回复会列出确实有读取者的会话;--force可强制发送)。标记为<room> · <device>的通知来自具有notify权限范围的环境设备(duoduo-ambient,references/devices.md);可在该处撤销设备权限以阻止其发送通知。duoduo session wake <target> --in <duration> | --at <iso>(v0.8.1 起新增)— 安排该会话在未来执行一次操作,所需上下文从 stdin 读取。notify会立即发送;wake会延后发送。目标规则与notify相同:仅允许channel/job;subconscious/kernel 平面会被拒绝。可在触发前通过duoduo job archive <wake-id>取消。duoduo session model <target> [<id>|reset]/duoduo session effort <target> [<level>|reset](0.8.0+)— 在 CLI 中查看或设置 channel 会话的模型/推理力度,使用与聊天中/model和/effort相同的选项,无需进入会话聊天。仅适用于 channel 会话。duoduo session archive <key>— 移动(绝不删除)会话的构件。
当用户说“将此会话命名为 X”或希望按名称从一个会话唤醒另一个会话时,应使用此接口。完整用法、隔离边界、输出/--json 规范及拒绝原因,请参阅
references/session-cli.md。
作业生命周期(duoduo job …,自 v0.8.1 起新增)
可通过命令行查看并结束计划作业。会话内工具负责创建、列出和读取作业;所有用于结束或重新安排作业时间的动词都是 Shell 命令,因此无论是终端上的人、通过 Bash 操作的 Agent,还是外部脚本,都会使用同一套命令。
duoduo job list [--json]— 列出活动作业,包括计划、待执行的一次性触发、上次运行和上次结果。待触发的唤醒也会列在这里,类型标记为wake,无论是会话为自己安排的,还是操作员通过duoduo session wake安排的。duoduo job read <id> [--json]— 读取单个作业的定义、任务和上次运行情况,包括错误。duoduo job archive <id>— 停止后续调度。不会删除任何内容:作业文件会移至var/jobs/archive/,其会话也会一并归档。已经开始的运行会继续直至结束。取消待触发的唤醒也使用此命令。duoduo job interrupt <id> -r "<reason>"— 请求结束正在进行的运行。必须提供-r;该作业下次运行时会收到这条原因说明,因此应写明发生了什么变化,而不是只写“停止”。运行如何收尾由作业自身的生命周期决定,而非命令决定:尚未重新安排的一次性作业会被归档,并通知其所有者作业失败;其他作业会继续保持计划状态;如果运行尚未开始执行就被中断,则会保留该次运行,视同从未开始。不要把回执中的“已中断”理解为“该次运行已终止”——这表示请求已被接受。duoduo job reschedule <id> <when>— 在@in 30m或带明确时区的 ISO 时间戳安排一次额外触发。计划类别不会改变。
两个动词,两种含义,很容易误换:archive 会停止后续运行,但不影响当前运行;interrupt 会结束当前运行,但不影响计划。卡住的周期性作业通常两者都需要。
用户询问时,请如实说明 interrupt 的作用范围:运行时会收到停止请求。忽略中止信号的工具不会被强制终止,而运行已分离到后台进程中的工作则完全不受影响。
Spine 检查(duoduo spine …,0.8.0+)
事件日志(Spine WAL)应通过 CLI 读取,而不是直接打开 JSONL 分区——单日数据可能有 10-30MB,其中工具结果可能长达数 MB;原始行中有 92% 是读者不需要的工具流程数据。
duoduo spine cat --date <yyyy-mm-dd> [--session <key>] [--type <t>]… [--kind external|all] [--from … --to …] [--after <id>] [--json]— 紧凑的 记录:完整显示人类/Agent 文本,将工具调用折叠为一行,并提供use=/res=深入查看锚点、准确的多项计数标题,以及END spine页脚(没有页脚 = 读取已被截断)。--date默认为今天。所有时间均为 UTC,每个范围均为(from, to];--from/--to也接受带偏移量的绝对 ISO 时间(2026-08-31T08:29+08:00),此类范围可能跨越多天。--after <id>会在相同边界内严格从某个事件之后继续读取,因此输出是同一次读取的后缀。--kind external是按轮次限定,而非按来源筛选:保留来自外部的事件,以及每个保留的channel.message所开启轮次中的内部行。作业会话不会展开。默认为all。duoduo spine cat --interval '<date>[t1,t2]' …— 机器格式的有界读取(潜意识使用此方式),读取一个分区,边界同为(t1, t2]。务必给 interval 加引号:zsh 会将方括号视为 glob,导致 CLI 运行前就失败。duoduo spine cat … --sessions— 按会话汇总(精确键、事件计数、首末时间戳),用于在繁忙的一天中查找会话键。duoduo spine cat … --count-only— 仅显示大小,不含正文;在将大时间窗口载入 Agent 上下文前先检查。duoduo spine show <event-id> [--date <yyyy-mm-dd>]— 显示单个事件的完整 JSON,不省略任何内容。行 ID 会缩短显示;show接受任意唯一前缀,前缀有歧义时会列出候选项。按 ID 查询的索引是启动时压缩的近期缓存。较早的裸 ID 会回退到完整分区扫描;--date仅缩小扫描范围,WAL 行本身不会改变。- 如果
cat在没有缩小范围的筛选条件时会输出正文,则会拒绝执行,除非传入--unfiltered——这是为了保护 Agent 上下文窗口,并非权限控制。--count-only和--sessions不输出正文,因此不受此限制;统计整天的数据无需此标志。 - 标题中的
missing_partitions=/skipped_malformed=是信息说明,并非错误:没有事件的日期不会写入分区文件,而末尾行被截断是常见的崩溃残留。
操作规则
- 配置值与过时文档不一致时,优先参考
duoduo daemon config。 - 在主机模式下,将
~/.config/duoduo/.env视为持久的事实来源。 - 用户更新已安装的
@openduo/duoduo软件包时,请提醒他们仍需运行duoduo daemon restart,因为运行中的守护进程是独立的后台进程。 - 如果检查配置、重启和日志后,运行时行为仍有异常,请将其视为可能的 duoduo 错误,并使用公开的问题反馈流程: ../duoduo-admin/references/issue-reporting.md。
- 如果请求实际涉及频道安装/启动/提示词/工作区相关工作,请转交给
duoduo-channel-admin。