Undefined 提供了一套强大的斜杠指令(Slash Commands)系统。管理员可以通过简单的带前缀的命令(如 /help)在群聊或私聊中快速管理机器人状态、查询统计信息或分配权限。
本文档将分为使用指南和自定义开发指南两部分,帮助你全面掌握命令系统。
- 所有的管理类斜杠命令需要发送者具有管理员或超管权限(在
config.local.json中配置或通过/admin add动态添加)。 - 普通用户使用此类命令时会收到权限不足的提示。
- 私聊里只有
config.json显式声明"allow_in_private": true的命令可直接执行;未开放命令会提示“当前不支持私聊使用”。
-
/help [命令名]
-
说明:
- 不带参数时,默认将所有可用命令的快速速查表渲染为图片发送。
- 带命令名时,默认将该命令的统一格式帮助渲染为图片发送(命令元信息 + 命令目录下 README 文档内容)。
- 命令目录下 README 会作为 Markdown 渲染到图片中,而不是以源文件文本展示。
-
参数:
参数 是否必填 说明 命令名可选 目标命令名,支持带或不带 /,如stats或/stats-t可选 直接发送纯文本帮助,不进行图片渲染 -
示例:
/help /help -t /help stats /help /faq /help stats -t
-
-
/copyright
- 说明:查看项目版权信息、开源协议和风险免责声明。
- 别名:
/license、/about、/disclaimer - 参数:无
- 示例:
/copyright /license
-
/version
- 说明:查看当前 Undefined 版本号与最新版本变更标题。
- 别名:
/v - 参数:无
- 示例:
/version /v
-
/changelog [list [数量] | show <版本号> | latest]
-
说明:
- 查看仓库内
CHANGELOG.md维护的版本历史。 - 不带参数时,默认列最近 8 个版本,只展示版本号与标题,避免刷屏。
show/latest会展示单个版本的标题、摘要和变更点。
- 查看仓库内
-
参数:
参数 是否必填 说明 list可选 列出最近多个版本;省略时默认等价于 /changelog数量可选 list模式返回的版本数量,默认 8,最大 20show可选 查看指定版本详情 版本号show时必填目标版本号,支持 v3.2.6或3.2.6latest可选 直接查看最新版本详情 -
返回内容:
list:版本号 + 标题的紧凑列表,并提示使用/changelog show <version>查看详情。show/latest:版本标题、摘要和 bullet 变更点。
-
边界行为:
list的数量超过 20 会自动截到 20。- 版本不存在、参数格式不合法或
CHANGELOG.md格式异常时,会返回明确错误提示。
-
示例:
/changelog /changelog list 12 /changelog show v3.2.6 /changelog show 3.2.6 /changelog latest
-
-
/profile [group] [-f|-r|-t] [目标ID]
-
说明:查看用户或群聊的认知侧写。侧写由系统根据聊天历史自动生成和更新。
-
别名:
/me、/p -
参数:
参数 是否必填 说明 group/g可选 查看群聊侧写(仅群聊可用) -f/--forward可选 合并转发模式输出 -r/--render可选 渲染为图片发送(默认) -t/--text可选 直接文本消息发送 <QQ号>可选 🔒 超管专用:查看指定用户的侧写 g <群号>可选 🔒 超管专用:查看指定群聊的侧写 -
行为:
- 私聊:查看自己的用户侧写,不支持
group参数。 - 群聊:不带参数查看自己的用户侧写,带
group/g查看当前群聊侧写。 - 超管指定目标:超级管理员可传入 QQ 号或群号查看任意用户/群的侧写,非超管使用时提示无权限。
- 输出模式:默认渲染为图片;
-f合并转发;-t直接文本发送。 - 图片结构:不再使用类型/ID/更新顶栏;先渲染 YAML 键值表(并标注正文长度),再独立评价块,紧接着锐评(损友式毒舌短评,不是第二条冷静评价),正文按 Markdown 渲染。旧侧写若缺评价或锐评,对应块不显示。
- 私聊:查看自己的用户侧写,不支持
-
限流:普通用户 60 秒,管理员 10 秒,超管无限制。
-
示例:
/profile → 查看自己的侧写(渲染图片) /p -f → 查看自己的侧写(合并转发) /p -t → 查看自己的侧写(直接文本) /p -r → 查看自己的侧写(显式渲染图片) /me → 同上(别名) /profile group → 查看当前群聊的侧写 /p g → 同上 /p 123456 → 🔒 超管:查看QQ号123456的侧写 /p g 789012 → 🔒 超管:查看群号789012的侧写 /p 123456 -r → 🔒 超管:查看指定用户侧写(渲染图片)
-
-
/summary [条数|时间范围] [自定义描述]
-
说明:程序自动拉取指定范围的聊天消息,并直连
models.summary模型生成总结(不经过 Agent、不暴露工具)。未配置[models.summary]时回退到models.agent。 -
与
summary_agent的区别:斜杠命令走[models.summary];主 AI 在对话里调用summary_agent时始终走[models.agent]。两者互不影响,详见 configuration.md 中的「消息总结模型路由」。 -
别名:
/sum -
参数:
参数 是否必填 说明 条数可选 纯数字,表示总结最近 N 条消息(默认 50;实际上限见 [history].summary_fetch_limit)时间范围可选 格式如 1h、6h、1d、7d,与条数互斥自定义描述可选 总结的重点方向,如"技术讨论"、"项目进展" -
限流:普通用户 120 秒,管理员 30 秒,超管无限制。
-
示例:
/summary → 总结最近 50 条消息 /summary 100 → 总结最近 100 条消息 /summary 1d → 总结过去 1 天的消息 /summary 50 技术讨论 → 总结最近 50 条,重点关注技术讨论 /sum 1d 项目进展 → 总结过去 1 天,重点关注项目进展
-
- /stats [时间范围] [--ai]
-
说明:生成过去一段时间内 Token 的使用统计数据、模型消耗排行、输入输出比例,并输出可视化图表。默认不启用 AI 分析,显式传
--ai(或-a)才会触发。 -
参数:
参数 是否必填 说明 时间范围可选 统计的回溯时间跨度,不传时默认为最近 7 天 --ai/-a可选 显式启用 AI 智能分析(默认关闭) 时间范围格式:
Nd:N 天,如7d= 最近 7 天,30d= 最近 30 天Nw:N 周,如2w= 最近 14 天Nm:N 个月,如1m= 最近 30 天N:纯数字,直接解释为天数,如14= 最近 14 天
范围限制:天数最小为 1 天,最大为 365 天。超出范围自动钳制。无法解析的格式回退到默认值 7 天。
-
返回内容:
- 默认:包含折线趋势图、模型对比柱状图、输入/输出饼图、模型明细表格和摘要的合并转发消息。微信私聊使用 iLink 保序多项目消息模拟该投递,不会生成 QQ 式可展开转发卡片;投递失败时至少返回纯文本摘要。
- 传入
--ai时:系统会先等待 AI 分析,再渲染并投递图表包;等待上限会根据当前队列和模型重试配置动态计算,超时时将超时提示作为图表包内容一并发送。 - 统计读取会流式处理目标时间范围内的记录,并跳过文件名可判定为过期的归档,降低长期运行后的延迟和内存占用。
-
示例:
/stats → 最近 7 天 /stats 30d → 最近 30 天 /stats 2w → 最近 14 天 /stats 1m → 最近 30 天 /stats 14 → 最近 14 天 /stats --ai → 最近 7 天并启用 AI 分析 /stats 30d --ai → 最近 30 天并启用 AI 分析
-
通过指令动态管理管理员列表,变更会自动持久化到 config.local.json,无需重启。超管(Superadmin)拥有最高权限,由配置文件的 core.super_admins 静态定义。
- /admin [ls|add|del] [参数]
-
说明:管理员管理统一入口,支持子命令和自动推断。
-
子命令:
子命令 用法 权限 说明 ls/admin ls管理员 列出当前所有管理员(超管 + 动态管理员) add/admin add <QQ号|@用户>仅超管 将指定 QQ 号添加为动态管理员 del/admin del <QQ号|@用户>仅超管 移除指定 QQ 号的动态管理员权限 -
自动推断:无参数
/admin→ 列表(ls)。 -
边界行为:
add:若 QQ 号不是数字,返回格式错误提示;若目标已是管理员,返回已存在提示。del:若目标是超级管理员,操作被拒绝;若目标本身不是管理员,返回"不是管理员"提示。
-
示例:
/admin— 查看管理员列表/admin ls— 同上/admin add 123456789— 添加管理员/admin del @某人— 移除管理员
-
用于对常见问题(FAQ)进行检索和管理。FAQ 不必每次请求 AI 大模型,极大地节省 Token 并加快响应。
- /faq [子命令] [参数](别名
/f)-
说明:FAQ 管理统一入口,支持子命令和自动推断。
-
子命令:
子命令 用法 权限 说明 ls/faq ls公开 列出当前群组所有 FAQ 条目(最多 20 条) view/faq view <ID>公开 查看指定 ID 的 FAQ 完整内容 search/faq search <关键词>公开 按关键词搜索 FAQ(最多 10 条) del/faq del <ID>管理员 删除指定 ID 的 FAQ -
自动推断:无需显式写子命令,系统自动推断意图:
- 无参数
/faq→ 列表(ls) - 参数为 ID 格式(如
20241205-001)→ 查看(view) - 参数为非 ID 格式(如
登录)→ 搜索(search) - 显式子命令优先,不会被推断覆盖
- 无参数
-
示例:
/faq— 列出所有 FAQ/faq 20241205-001— 查看 FAQ(自动推断为 view)/faq 登录— 搜索 FAQ(自动推断为 search)/faq del 20241205-001— 删除 FAQ(需管理员)
-
-
/feedback [add|view|del] [内容或ID](别名
/fb)-
说明:公开意见反馈板,群聊和私聊均可提交与查看;超级管理员可查看完整审计信息并删除反馈。
-
子命令:
子命令 用法 权限 说明 add/feedback add <内容>公开 提交一条反馈 view/feedback view [ID]公开 无 ID 时列出最近 20 条反馈;有 ID 时查看详情 del/feedback del <ID>仅超管 删除指定反馈 -
自动推断:
- 无参数
/fb→ 查看反馈列表(view) - 参数为 ID 格式(如
20260509-1000)→ 查看该反馈(view) - 其他文本 → 提交反馈(add)
- 显式子命令优先,不会被推断覆盖
- 无参数
-
可见范围:
- 普通用户列表和详情只显示反馈 ID 与公开内容,不显示提交者 QQ、群号、私聊用户 ID、创建时间等元数据。
- 超级管理员列表和详情会显示完整审计信息。
- 反馈保存到
data/feedback/feedback.json,ID 格式为YYYYMMDD-N,同一天从 1 递增,不限制 999。
-
示例:
/fb— 查看最近 20 条反馈/fb 希望增加夜间静默模式— 提交反馈/fb 20260509-1— 查看指定反馈/feedback del 20260509-1— 删除反馈(需超级管理员)
-
-
/bugfix <QQ号1> [QQ号2...] <开始时间> <结束时间>
-
说明:从群历史记录中抓取指定用户在指定时间段内的消息(包含文字、图片的 OCR 描述),交给 AI 进行分析并生成 Bug 修复报告,结果自动存入 FAQ 库。
-
参数:
参数 是否必填 说明 QQ号1 [QQ号2...]必填 一个或多个目标用户 QQ 号(纯数字,空格分隔) 开始时间必填 格式严格为 YYYY/MM/DD/HH:MM,如2024/12/01/09:00结束时间必填 格式同上,或填写 now表示截止到当前时刻 -
边界行为:
- 总参数少于 3 个时,返回用法提示。
- QQ 号或时间格式解析失败时,分别返回对应的格式错误提示。
- 指定时间段内无记录时,返回"未找到符合条件的对话记录"。
- 历史消息一次最多拉取 2500 条。
-
示例:
/bugfix 123456 2024/12/01/09:00 now /bugfix 111111 222222 2024/12/01/09:00 2024/12/01/18:00
-
⚠️ 此功能面向与 NagaAgent 对接的高级场景,普通用户不建议开启。 需要在config.toml中同时启用[api].enabled、[features].nagaagent_mode_enabled和[naga].enabled。
-
/naga <子命令> [参数]
- 说明:NagaAgent 绑定管理。当前只保留发起绑定和解绑两个子命令。
- 前置条件:
api.enabled = true、features.nagaagent_mode_enabled = true且naga.enabled = true。
子命令列表:
子命令 权限 作用域 说明 bind <naga_id>公开 仅群聊(受会话策略) 在当前 Naga 会话策略允许的群中提交绑定申请,生成 bind_uuid并发送到 Naga 端等待回调确认unbind <naga_id>超管 群聊/私聊(受会话策略) 吊销当前绑定,并 best-effort 通知远端同步解绑 权限模型:
bind子命令配置permission: public+allow_in_private: false(仅群聊可用),unbind子命令配置permission: superadmin(仅超管可用),均在config.json的subcommands中声明,分发层自动检查。额外还受[naga].mode会话策略约束。-
示例:
/naga bind alice ← 策略允许的群内发起绑定 /naga unbind alice ← 超管解绑(策略允许的群或私聊) -
额外行为:
- 群聊/私聊均需通过
naga.mode名单策略;不通过则命令不可见且静默忽略(/help也不展示),与 Runtime API 的naga policy denied(HTTP 403)不同。 - 进程级仍要求
api.enabled、nagaagent_mode_enabled、naga.enabled同时开启。 - 私聊名单判定对 superadmin 会绕过(实现内置,非
[access].superadmin_bypass_*);群聊无 superadmin 绕过。 bind的成功提示只代表“本地已记录并尝试提交到 Naga 端”,真正生效要等bind/callback回调确认。unbind成功后会私聊通知绑定用户,并尝试调用远端bind/revoke接口同步状态。- 配置细节见 configuration.md §4.27。
- 群聊/私聊均需通过
Undefined 具有可插拔的指令解析层,所有的指令逻辑实现均放在 src/Undefined/skills/commands/ 目录下(作为一项特殊的核心系统技能存在)。
开发一个新命令极为简单,只需几行代码即可完成自动注册、权限鉴定要求和参数解析。
src/Undefined/
├── changelog.py # CHANGELOG.md 解析与查询公共模块
├── services/commands/
│ ├── __init__.py
│ ├── context.py # 核心上下文 (CommandContext) 定义
│ └── registry.py # 命令注册表 (CommandRegistry) 和 Meta 定义
└── skills/commands/ # 具体的所有指令实现存放目录
├── __init__.py
├── changelog/ # 内置命令:版本历史查询
├── version/ # 内置命令:版本号与最新变更标题
├── help/ # 内置命令:基础帮助
├── copyright/ # 内置命令:版权与免责声明
├── faq/ # 内置命令:FAQ增删改查
├── feedback/ # 内置命令:公开意见反馈板
└── my_custom_cmd/ # 👈 你新建的自定义命令目录(需要包含 config.json 和 handler.py)
在 skills/commands/ 目录下新建一个你的命令大类目录,例如 skills/commands/hello_world/,然后在里面创建 config.json、handler.py 和 README.md。
如果命令需要读取仓库级文档或共享数据源,建议像 /changelog 一样先把解析逻辑抽到公共模块中,再让命令层只负责参数解析和文本格式化。这样后续即使再接一个 tool 或 API,也不用重复解析同一份文档。
{
"name": "hello",
"description": "向群里的盆友问个好",
"permission": "admin",
"allow_in_private": true,
"rate_limit": {
"user": 10,
"admin": 5,
"superadmin": 0
},
"show_in_help": true,
"order": 100,
"aliases": ["hi", "helloworld"],
"subcommands": {
"list": { "description": "列出打招呼记录", "permission": "public" },
"greet": { "description": "执行打招呼", "args": "<目标>", "permission": "admin" }
},
"inference": {
"default": "greet",
"rules": [
{ "pattern": "^[a-z]+$", "subcommand": "greet" }
],
"fallback": "greet"
}
}提示: permission 可选 public / admin / superadmin。
提示: allow_in_private 控制该命令是否允许在私聊中通过 /命令 直接触发,默认 false。
提示: rate_limit 单独指定各级使用者的独立调用冷却拦截秒级时间(0代表无限制)。
提示:可选字段 subcommands 为子命令声明,每个子命令可独立配置 description(必填)、permission、allow_in_private、rate_limit、args(参数格式,用于帮助展示);缺省值继承父命令。
提示:可选字段 inference 为自动推断配置,default 为无参数时推断的子命令,rules 为正则匹配列表(按顺序匹配 args[0]),fallback 为规则都不命中时的兜底子命令。
提示:可选字段 help_footer 为字符串数组,主要用于 /help 这类命令在列表页尾部输出固定提示文案。
# src/Undefined/skills/commands/hello_world/handler.py
import logging
from Undefined.services.commands.context import CommandContext
logger = logging.getLogger(__name__)
async def execute(args: list[str], context: CommandContext) -> None:
# args 为空格分割的参数列表
if not args:
target = "世界"
else:
target = " ".join(args)
# 执行回复动作
await context.sender.send_group_message(
context.group_id,
f"👋 你好, {target}! 这个命令是由 {context.sender_id} 触发的。"
)README.md 会被 /help <command> 自动读取并作为 Markdown 渲染到统一帮助图片中。若需要纯文本可使用 /help <command> -t。建议保持文档简洁、可读、结构稳定(推荐包含“功能 / 用法 / 参数 / 示例 / 说明”)。
# /hello 命令说明
## 功能
向群友打招呼。
## 用法
- /hello [目标]被自动注入的 ctx 对象包含当前命令生命周期的所有可用资源:
| 属性 | 类型 | 说明 |
|---|---|---|
ctx.group_id |
int |
当前接收指令的群组 ID。私聊时这通常会映射为 0 或特定逻辑池。 |
ctx.sender_id |
int |
发出命令的用户 QQ 号。 |
ctx.args |
list[str] |
参数列表(用空格切割),例如 /hello foo bar 则为 ["foo", "bar"] |
ctx.sender |
MessageSender |
消息收发器工具,包含 send_group_message, send_private_message |
ctx.config |
Config |
系统的核心配置管理器 |
ctx.bot_qq |
int |
当前机器人的自身 QQ 号 |
ctx.ai |
AIClient |
主 AI Client,可以用于进行分析、总结等大模型调用 |
ctx.faq_storage |
FAQStorage |
FAQ 的键值操作入口 |
ctx.cognitive_service |
Any | None |
认知侧写服务,可调用 get_profile(entity_type, entity_id) |
ctx.history_manager |
Any | None |
消息历史管理器,可调用 get_recent(chat_id, msg_type, start, end) |
命令可以限定谁能执行:
"superadmin": 仅config.toml中[core].superadmin_qq的人可执行。"admin": 超级管理员 +config.local.json动态添加的管理员均可执行。"public": 群内或私聊中的任何用户均可执行。(注意风控和被滥用刷屏的风险)
可见性:
/help会根据当前用户的权限级别过滤命令列表。superadmin权限的命令不会对普通用户显示;admin权限的命令不会对非管理员显示。主 AI 的系统提示会注入当前消息发送者可用的命令摘要(不是完整目录);commands.search/commands.get默认查询全部斜杠命令(纯文本匹配,不接 RAG),也可传入group_id、user_id或两者,改为按该用户在该群/私聊视角过滤。介绍时注明权限。AI 只应介绍命令,不要代替用户发送斜杠命令。
对于拥有多个子命令的复合命令(如 /faq),在 config.json 中用 subcommands 声明各子命令,用 inference 配置自动推断逻辑。
{
"subcommands": {
"ls": { "description": "列出所有FAQ" },
"view": { "description": "查看FAQ详情", "args": "<ID>" },
"search":{ "description": "搜索FAQ", "args": "<关键词>" },
"del": { "description": "删除FAQ", "permission": "admin", "args": "<ID>" }
}
}子命令字段(均可选,缺省继承父命令):
description— 子命令描述(必填)permission— 权限级别,默认继承父命令allow_in_private— 是否允许私聊,默认继承父命令rate_limit— 限流配置,默认继承父命令(仅覆盖指定字段)args— 参数格式如<ID>,用于/help详情展示
子命令限流按父命令与解析后的子命令共同计数,例如 /faq ls 与 /faq search 不会互相占用冷却时间。
{
"inference": {
"default": "ls",
"rules": [
{ "pattern": "^\\d{8}-\\d{3}$", "subcommand": "view" }
],
"fallback": "search"
}
}default:无参数时推断为该子命令rules:正则匹配列表,按顺序匹配args[0],命中则推断为对应子命令;命中后 args 保留为子命令的参数fallback:所有规则都不命中时,推断为该子命令,原始参数整体传入
分发层会自动处理:
args[0]显式匹配子命令名 → 直接使用该子命令的元信息- 无匹配则按
inference推断 → 推断出的子命令同样做权限/作用域/限流检查 - 权限检查、作用域检查、限流均在分发层统一完成,handler 无需内部再判断
你无需去任何主函数写 import hello_world!
Undefined 会在运行时自动检测 skills/commands/ 目录变化并热重载命令(新增目录、修改 config.json / handler.py / README.md 都会生效)。只需保证文件存在并且合法:
uv run Undefined命令就绪后在群里输入 /help,你会看到 /hello 出现在列表中;输入 /help hello 可以看到你在 README.md 里写的详细说明。