Skip to content

配置参考 ​

Nahida Bot 从 YAML 文件、.env 文件和环境变量读取配置。值的合并优先级从高到低:

  1. CLI 参数(--debug、--config-yaml)
  2. .env 文件中的值
  3. YAML 配置文件
  4. 内置默认值

所有 YAML 值都支持环境变量插值,语法为 ${VAR} 或 ${VAR:fallback}。


顶层设置 ​

键类型默认值说明
app_namestr"Nahida Bot"应用名称,用于日志、生命周期事件和 memory dreaming prompt
debugboolfalse调试模式。开启后若未显式设置 log_level,则强制为 DEBUG
log_levelstr"INFO"日志级别:TRACE、DEBUG、INFO、WARNING、ERROR
log_jsonbool|nullnullJSON 日志输出。null = 自动(生产环境用 JSON,调试模式用控制台)
log_filestr|nullnull可选日志文件路径。设置后会额外添加文件 handler,并自动创建父目录
log_file_levelstr|nullnull文件日志级别。null = 跟随 log_level,可设为 DEBUG 让文件收集更详细日志
log_file_jsonbooltrue文件日志是否使用 JSON Lines 格式
hoststr"127.0.0.1"服务器绑定地址(保留)
portint6185服务器绑定端口(保留)
db_pathstr"./data/nahida.db"SQLite 数据库文件路径
workspace_base_dirstr"./data/workspace"工作区存储目录
plugin_pathslist[str]["./plugins"]额外的插件扫描目录
discover_builtin_channelsbooltrue自动发现内置频道插件
system_promptstr"You are a helpful assistant."Agent 对话的默认系统提示词
default_providerstr""默认使用的 provider ID。空值 = 使用 providers 中的第一个
providersdict{}LLM provider 配置(见下文)
multimodalobject(见下文)图片/媒体处理配置
agentobject(见下文)Agent 循环配置
contextobject(见下文)上下文窗口预算配置
schedulerobject(见下文)定时任务调度配置
routerobject(见下文)消息路由配置
webapiobject(见下文)WebAPI 服务配置
webuiobject(见下文)WebUI 控制台配置
memoryobject(见下文)长期记忆与 embedding 配置
motion_plannerobject(见下文)Desktop DisplayPlan 服务端动作规划
processesobject(见下文)附属进程监管(sidecar 进程)
enable_silent_replybooltrue全局开关:是否允许 Agent 以 NO_REPLY 静默回复

示例 ​

yaml
app_name: "Nahida Bot"
debug: false
log_level: "INFO"
log_file: "./data/logs/nahida.log"
log_file_level: "DEBUG"
db_path: "./data/nahida.db"
system_prompt: "You are a helpful assistant."
default_provider: deepseek-main

LLM Providers ​

providers 是一个字典,每个键是自定义的 provider ID,用于 default_provider 和 /model 命令中引用。

Provider 条目 ​

键类型默认值说明
typestr"openai-compatible"Provider 类型,见 Provider 类型
api_keystr""API 密钥,为空时跳过该 provider
base_urlstr""API 端点基础 URL
modelslist[]模型列表,第一个元素为默认模型
merge_system_messagesboolfalse发送前合并所有 system 消息为一条(用于需要单一 system 的后端)
stream_responsesboolfalseprovider 内部使用上游流式接口接收并聚合返回;不改变 channel 发送方式

stream_responses 当前支持 openai-compatible 族(含 deepseek、glm、groq)、anthropic 族(含 minimax)和 openai-responses。开启后 provider 会持续读取上游 SSE 事件,最后仍返回一个完整 ProviderResponse;这主要用于长推理/重任务时区分“服务端仍在生成”与“服务端完全无响应”。当前不会把 token 级增量直接发送到聊天频道。

deepseek provider 还支持 thinking_enabled(默认 true)和 reasoning_effort;前者控制是否向请求体注入 thinking: {"type": "enabled"},后者可被运行时 reasoning.effort 覆盖。

Anthropic / Minimax 输出上限 ​

键类型默认值说明
max_tokensint16000Anthropic / Minimax 的输出 token 上限;适用于 anthropic 和 minimax provider
reasoning_effortstr|nullnullClaude 原生推理深度,注入请求体的 output_config.effort("low"/"medium"/"high"/"max")。可被运行时 /reasoning 覆盖。仅 Claude 原生端点(anthropic provider)——Minimax 兼容端点可能拒绝该字段
context_1mboolfalse为 Anthropic 原生 provider 启用 1M 上下文预算。现代 Claude 4.6+ 模型不需要 anthropic-beta 头;仅在上游账号和模型支持 1M context 时有效
anthropic_beta_headerslist[str]|str[]显式发送 anthropic-beta header。官方 1M Claude 4.6+ 不需要;部分 Anthropic-compatible 转发层可能仍用旧 beta 名作为路由开关

模型条目 ​

models 中的每个元素可以是纯字符串或对象:

yaml
models:
  - "deepseek-v4-pro"                      # 纯字符串
  - name: "Qwen/Qwen3.6-35B-A3B"           # 带 capabilities 的对象
    tags: [primary, vision]
    capabilities:
      image_input: true
      max_image_count: 4
      context_window: 128000

模型标签 ​

每个模型可以声明 tags(字符串列表),供内部任务 model spec 解析使用。详见 Model Specs。

键类型默认值说明
tagslist[str][]模型标签,用于 model spec 的 tag 匹配

模型能力声明 ​

在 capabilities 下按模型声明其支持的能力:

键类型默认值说明
text_inputbooltrue接受文本输入
image_inputboolfalse原生接受图片输入
tool_callingbooltrue支持函数/工具调用
reasoningboolfalse支持推理/思维链 token
prompt_cacheboolfalse支持 prompt 缓存
prompt_cache_imagesboolfalse在 prompt 中缓存图片
explicit_context_cacheboolfalse需要显式缓存控制标记
prompt_cache_min_tokensint0缓存断点的最小 token 数
max_image_countint0每次请求最大图片数(0 = 不限)
max_image_bytesint0单张图片最大字节数(0 = 不限)
supported_image_mime_typeslist[str]["image/jpeg", "image/png", "image/webp"]接受的 MIME 类型
context_windowint|nullnull模型实际上下文窗口;声明后每轮按模型重算 prompt 预算
max_context_windowint|nullnull模型可配置的最大上下文窗口;当 context_window 为空时作为 fallback
effective_context_window_percentint95可用于 prompt 的上下文比例;默认保留 5% 余量
auto_compact_token_limitint|nullnull自动摘要/滑窗的软阈值;为空时按 90% context window 派生
image_generationboolfalse模型可通过内置工具生成图片
web_searchboolfalse模型支持内置网页搜索
file_searchboolfalse模型支持内置文件搜索
code_interpreterboolfalse模型支持内置代码解释器

OpenAI Responses API 选项 ​

以下字段仅在 type: "openai-responses" 时生效:

键类型默认值说明
store_responsesboolfalse启用响应持久化,用于 previous_response_id 链式调用
use_previous_response_idboolfalse开启后从历史 assistant metadata 中查找上一轮 response id,并只发送新增输入
reasoning_effortstrnull推理深度:"low"、"medium"、"high"
max_output_tokensintnull最大输出 token(替代 max_tokens)
built_in_toolslist[str]null启用的内置工具:"web_search"、"file_search"、"image_generation"、"code_interpreter"

Provider 类型 ​

类型类说明
openai-compatibleOpenAICompatibleProvider通用 /chat/completions 端点
deepseekDeepSeekProviderDeepSeek(扩展 OpenAI 兼容,增加思维模式)
glmGLMProviderGLM / 智谱(完全 OpenAI 兼容)
groqGroqProviderGroq(OpenAI 兼容,不同的 reasoning 字段名)
anthropicAnthropicProviderAnthropic Claude(独立协议)
minimaxMinimaxProviderMinimax(Anthropic 兼容端点)
openai-responsesOpenAIResponsesProviderOpenAI Responses API(/v1/responses),支持内置工具和有状态链式调用
codexCodexProviderChatGPT Codex(订阅额度,OAuth 设备码登录)

type: codex 不需要 api_key:先运行 nahida-bot auth login codex 完成 OAuth 设备码登录,refresh token 写入 SQLite,bot 启动时自动加载并按需刷新。 非官方用法,仅面向 ChatGPT Plus/Pro 订阅者;账号存在被 OpenAI 风控的风险。

yaml
codex:
  type: codex
  stream_responses: true
  reasoning_effort: "medium"
  models:
    - name: "gpt-5.5"

高级覆盖项(可选环境变量):

变量说明
NAHIDA_OPENAI_ORIGINATOROAuth 归因字符串,默认 "nahida-bot"
NAHIDA_OPENAI_CLIENT_IDOAuth client id,默认内置;仅作为逃生阀

Provider 配额查询 ​

provider 条目可以声明 quota,用于查询 provider 侧的余额 / 订阅额度,配合 聊天命令 /quota [provider_id] [refresh|force|all] 使用:

键类型默认值说明
adapterstr""配额适配器:deepseek、minimax-coding-plan、kimi、zhipu、json-v1 等
urlstr""配额查询 API 地址(json-v1 需要)
api_keystr""配额 API 密钥(敏感字段,会被脱敏)
teamboolfalse是否查询团队额度
organization_idstr""组织 ID
project_idstr""项目 ID
windowslist[]json-v1 的窗口定义(used/limit/reset JSON 路径)
yaml
minimax:
  type: minimax
  api_key: "${MINIMAX_LLM_API_KEY:}"
  base_url: "https://api.minimaxi.com/anthropic"
  quota:
    adapter: minimax-coding-plan

示例 ​

yaml
providers:
  deepseek-main:
    type: deepseek
    api_key: "${DEEPSEEK_LLM_API_KEY:}"
    base_url: "${DEEPSEEK_LLM_BASE_URL:https://api.deepseek.com}"
    stream_responses: true
    models: ["deepseek-v4-pro", "deepseek-v4-flash"]

  siliconflow:
    type: "openai-compatible"
    api_key: "${SILICONFLOW_LLM_API_KEY:}"
    base_url: "${SILICONFLOW_LLM_BASE_URL:https://api.siliconflow.cn/v1}"
    merge_system_messages: true
    stream_responses: true
    models:
      - "Pro/zai-org/GLM-5"
      - name: "Qwen/Qwen3.6-35B-A3B"
        capabilities:
          image_input: true
          max_image_count: 4
          max_image_bytes: 10485760

  minimax:
    type: minimax
    api_key: "${MINIMAX_LLM_API_KEY:}"
    base_url: "https://api.minimaxi.com/anthropic"
    stream_responses: true
    models: ["MiniMax-M2.5"]

  openai:
    type: "openai-responses"
    api_key: "${OPENAI_API_KEY:}"
    base_url: "${OPENAI_API_BASE_URL:https://api.openai.com/v1}"
    store_responses: true
    use_previous_response_id: false
    stream_responses: true
    reasoning_effort: "medium"
    built_in_tools: ["web_search", "image_generation"]
    models:
      - name: "gpt-5.2"
        capabilities:
          image_input: true
          image_generation: true
          web_search: true
          tool_calling: true
          reasoning: true

default_provider: deepseek-main

Model Specs ​

内部任务的模型配置使用单个 model spec 字符串。model spec 可以是 tag、provider/model 或裸模型名,统一由 ModelRouter.resolve() 解析。

常用默认 tag:

Tag用途
primary主对话模型
memorymemory dreaming / consolidation
embedding文本 embedding
reranker检索重排
vision图片理解 fallback
cheap低成本后台任务标记

示例:

yaml
memory:
  consolidation:
    rule_based_enabled: false
  embedding:
    model: embedding

multimodal:
  image_fallback_model: siliconflow/Qwen/Qwen3.6-35B-A3B

多模态 / 图片处理 ​

在 multimodal 键下配置。

键类型默认值说明
image_fallback_modestr"auto"主模型不支持图片时的策略:auto(自动调用 fallback 视觉模型)、tool(注入 image_understand 工具)、off(跳过图片)
media_context_policystr"cache_aware"历史中的媒体保留方式:cache_aware(近期图片保留原生块,旧的降级为描述)、native_recent(仅最新图片保留原生)、description_only(全部使用文本描述)
image_fallback_modelstr""Fallback 视觉模型 spec;空则默认找 vision tag
max_images_per_turnint4每轮对话处理的最大图片数
max_image_bytesint10485760单张图片最大字节数(10 MB)
media_cache_ttl_secondsint3600媒体缓存过期时间(秒)

示例 ​

yaml
multimodal:
  image_fallback_mode: "auto"
  media_context_policy: "cache_aware"
  image_fallback_model: "siliconflow/Qwen/Qwen3.6-35B-A3B"

Agent Loop ​

在 agent 键下配置。控制 LLM + 工具调用的迭代循环。

键类型默认值说明
max_stepsint8每轮对话最大工具调用迭代次数
provider_timeout_secondsfloat120.0单次 LLM API 调用超时时间(秒)
retry_attemptsint2Provider 瞬态错误重试次数
retry_backoff_secondsfloat0.2重试退避间隔(秒)
tool_timeout_secondsfloat135.0单次工具执行超时时间(秒)
tool_retry_attemptsint1工具执行失败重试次数
tool_retry_backoff_secondsfloat0.1工具重试退避间隔(秒)
max_tool_log_charsint400工具结果日志截断长度
tool_use_system_promptstr(内置)注入的工具使用行为引导提示
provider_error_templatestr(内置)Provider 错误时的用户提示模板(支持 {code} 占位符)

Motion Planner(Desktop DisplayPlan) ​

在 motion_planner 键下配置服务端动作规划。启用后,Agent 回复会调用一个 低成本 LLM 模型分析回复文本,为每一句生成情绪 / 动作 / 语音风格标签, 结果挂在 OutboundMessage.extra["display_plan"] 上,并通过 agent.message.completed 事件转发给 Desktop Node。任何失败都返回中性计划, 不会阻塞回复。

键类型默认值说明
enabledboolfalse是否启用服务端 motion planner
model_tagstr"cheap"通过 ModelRouter 解析的模型标签
timeout_secondsfloat15.0单次规划调用的超时(秒),范围 1–60
yaml
motion_planner:
  enabled: true
  model_tag: "cheap"
  timeout_seconds: 15.0

仅在回复路由为 Desktop node 路径(node:...)时生效;普通聊天频道不受影响。 生成的情绪 / 动作枚举见 Live2D 动作智能层。


Context Budget ​

在 context 键下配置。控制 prompt 上下文组装和 token 预算。 如果当前模型在 providers.*.models[].capabilities 中声明了 context_window, 运行时会优先使用模型窗口;这里的 max_tokens / reserved_tokens 是未知模型的 fallback。

键类型默认值说明
max_tokensint272000未声明模型窗口时的 fallback context window
reserved_tokensint10000未声明模型窗口时为模型响应保留的 token 数
max_charsint|nullnull字符数预算覆盖(兼容旧逻辑,优先使用 max_tokens)
reserved_charsint0使用 max_chars 时的字符保留数
summary_max_charsint2000历史消息摘要的最大字符数
reasoning_policystr"budget"reasoning chain 处理方式:strip(丢弃)、append(始终包含)、budget(预算内包含)
max_reasoning_tokensint2000reasoning chain 内容的 token 预算

Scheduler ​

在 scheduler 键下配置。控制基于 cron 的定时任务调度服务。

键类型默认值说明
poll_interval_secondsfloat1.0调度器检查到期任务的间隔(秒)
max_concurrent_firesint5最大并发执行任务数
job_timeout_secondsfloat120.0单个定时任务执行超时(秒)
min_interval_secondsint60允许的最小 cron 间隔(防止过于频繁触发)
max_prompt_charsint12000定时任务 prompt 最大字符数
max_jobs_per_chatint20每个聊天会话的最大定时任务数
failure_retry_secondsint300任务失败后重试等待时间(秒)
max_consecutive_failuresint3连续失败多少次后自动禁用任务
max_fire_lateness_secondsint300到期后超过此秒数才被调度到的任务直接跳过不执行(0 关闭)。once 任务作废;cron/interval 任务重排到从当前时间起算的下一个周期。用于避免长时间停机后重新上线时积压任务集中触发刷屏
memory_dreaming_enabledbooltrue是否启用内部记忆 dreaming 周期任务
memory_dreaming_interval_secondsint3600记忆 dreaming 周期(秒)
memory_dreaming_initial_delay_secondsint300应用启动后首次 dreaming 延迟(秒)
memory_dreaming_session_limitint20单次 dreaming 最多扫描的最近会话数
memory_dreaming_recent_turn_limitint40单个会话最多读取的最近 turns 数
memory_dreaming_modelstr""dreaming 模型 spec;空则默认找 memory tag,失败后使用会话模型

Processes(附属进程监管) ​

在 processes 键下配置 sidecar 进程监管。被监管的进程在所有 Channel / 插件启用之前就绪、在它们之后收尾,适合放需要先于 Channel 建立的 SSH 隧道、frpc、cloudflared 等。进程默认不继承 bot 进程环境,只有 PATH、LANG 等少量白名单(Windows 额外含 SYSTEMROOT、WINDIR、 APPDATA、USERPROFILE)加你声明的 env 会传入;密钥请放 .env 用 ${VAR} 引用。

键类型默认值说明
enabledbooltrue总开关;false 则不拉起任何进程
defaultsobject(见下文)所有 spec 的默认值,可被单项覆盖
specsdict{}进程声明,键名为 [a-z0-9_-]+,跨配置与插件唯一

processes.defaults ​

键类型默认值说明
restart_policystr"on-failure"no / on-failure / always
backoff_initial_secondsfloat1.0崩溃后首次重启等待(秒)
backoff_max_secondsfloat60.0指数退避上限
backoff_factorfloat2.0退避倍率
restart_max_attemptsint00 = 不限;>0 触发熔断(停止自动重启)
restart_window_secondsfloat300.0统计重启次数的滑动窗口
shutdown_timeout_secondsfloat10.0SIGTERM 后多久 SIGKILL
startup_wait_secondsfloat0.0启动后等待健康检查的宽限期
log_buffer_linesint1000stdout/stderr 各自的环形缓冲行数

processes.specs.<name> ​

键类型默认值说明
commandstr(必填)启动命令
argslist[str][]shell: false 时的 argv 列表
shellbooltruetrue 走 shell;false 把 command 当可执行文件、args 当参数
envdict[str,str]{}额外环境变量
working_dirstr|nullnull工作目录
restart_policystr|nullnull覆盖 defaults.restart_policy
depends_onlist[str][]同段内其他 spec 名,决定启动顺序(循环会被校验拒绝)
shutdown_timeout_secondsfloat|nullnull覆盖默认收尾超时
startup_wait_secondsfloat|nullnull覆盖默认健康检查宽限
health_checkobject(见下文)健康探测

health_check 字段:

键类型默认值说明
typestr"none"tcp_port(TCP 连上即健康)/ none
hoststr"127.0.0.1"探测地址
portint0探测端口
interval_secondsfloat15.0探测间隔
timeout_secondsfloat3.0单次探测超时
unhealthy_afterint3连续失败 N 次才判不健康并触发重启
start_period_secondsfloat0.0启动宽限期内失败不计入
yaml
processes:
  enabled: true
  defaults:
    restart_policy: "on-failure"
    backoff_initial_seconds: 1.0
    backoff_max_seconds: 60.0
    backoff_factor: 2.0
    restart_max_attempts: 0
    shutdown_timeout_seconds: 10.0
    log_buffer_lines: 1000
  specs:
    ssh-db-tunnel:
      command: "ssh -N -L 3306:db.internal:3306 bastion@example.com"
      shell: true
      env:
        SSH_KEY_PATH: "${SSH_KEY_PATH}"
      restart_policy: "always"
      health_check:
        type: "tcp_port"
        host: "127.0.0.1"
        port: 3306
        interval_seconds: 15.0
        timeout_seconds: 3.0
        unhealthy_after: 3
        start_period_seconds: 0.0

完整的监管模型、生命周期顺序、事件与安全边界见 附属进程监管设计。WebUI「进程」页与 /api/processes* API 可查看状态和日志、启停重启进程。


Memory ​

在 memory 键下配置长期记忆检索和 embedding。默认保持 FTS-only,不会调用 embedding API。

键类型默认值说明
enabledbooltrue是否启用 memory 子系统配置
retrieval.fts_enabledbooltrue是否允许使用 SQLite FTS/BM25 检索长期记忆
retrieval.vector_enabledboolfalse是否启用向量召回;需要 embedding.enabled=true
retrieval.hybrid_enabledbooltrueFTS 和 vector 同时可用时是否使用 RRF hybrid fusion
retrieval.vector_backendstr"json"向量后端:json、sqlite-vec、none
retrieval.max_injected_itemsint5单轮最多注入的长期记忆条数
retrieval.max_injected_charsint4000单轮长期记忆注入字符预算
embedding.enabledboolfalse是否启用长期记忆 embedding
embedding.modelstr""embedding 模型 spec;空则默认找 embedding tag
embedding.dimensionsint0embedding 维度;sqlite-vec 后端必须填写
embedding.batch_sizeint16embedding 批量大小
embedding.embed_after_consolidationbooltrueconsolidation/dreaming 写入长期记忆后是否刷新 embedding
consolidation.rule_based_enabledbooltrue是否启用每轮对话结束后的规则抽取;设为 false 后只保留后台 dreaming 和显式 memory_write//memory remember 写入

Router ​

在 router 键下配置。控制消息从频道到命令/Agent 的路由行为。

键类型默认值说明
system_promptstr"You are a helpful assistant."Agent 系统提示词(建议使用顶层 system_prompt 字段)
max_history_turnsint200每个会话加载的最大对话历史轮数
agent_enabledbooltrue是否启用 Agent 循环(设为 false 进入纯命令模式)
command_timeout_secondsfloat30.0命令处理器执行超时(秒)
command_timeout_messagestr"Command timed out..."命令超时时显示的消息
reply_to_inboundbooltrue默认是否让回复引用触发消息;频道插件可用同名配置覆盖
show_reasoningboolfalse是否在回复中附带模型推理过程
reasoning_max_charsint2000推理过程显示的最大字符数
enable_silent_replybooltrue是否允许 Agent 使用 NO_REPLY 静默回复(运行时可通过 /reasoning 调整)
group_contextobject(见下文)群聊观察上下文注入配置

群聊观察上下文 ​

在 router.group_context 下配置。控制群聊中未直接触发 bot 的消息作为上下文注入的行为。

键类型默认值说明
enabledbooltrue是否启用群聊观察上下文注入
max_messagesint20注入的最大观察消息数
ttl_secondsint900观察消息过期时间(秒),超出的不注入
max_charsint4000观察上下文总字符预算
topic_gap_secondsint300群消息静默超过此值时开始新的自动上下文话题窗口。0 关闭
continuity_gap_secondsint1800对话连续性判定(秒):当前触发与上一次对话 turn 的时间间隔超过此值时,视为新对话并丢弃旧 history,仅保留 observed 窗口。0 关闭(保留旧的纯按条数截断行为)。仅群聊生效

WebAPI ​

在 webapi 键下配置。控制 HTTP REST API 服务。

键类型默认值说明
enabledboolfalse是否启用 WebAPI 服务
auth_tokenstr""API 认证令牌;请求需在 Authorization: Bearer <token> 中携带
cors_originslist[str]["*"]CORS 允许的来源列表
hoststr""绑定地址;空值跟随顶层 host
portint0绑定端口;0 表示自动分配

Desktop / Gateway 语音合成 ​

webapi.speech 启用统一的 Gateway TTS 与音频缓存接口。Desktop 只调用 POST /api/speech/jobs,不会直接持有云厂商密钥或依赖具体 Provider 协议。

键类型默认值说明
enabledboolfalse是否启用 Gateway TTS
default_backendstr"default"默认后端名称
backendsdict{}Provider 后端配置;每项必须包含 type
voicesdict{}逻辑音色配置;可通过 backend 指定后端
default_voicestr""未显式指定音色时使用的逻辑音色
artifact_cache_dirstr"./data/speech_cache"合成音频缓存目录
artifact_ttl_secondsint21600音频缓存有效时间
artifact_max_bytesint268435456音频缓存总字节上限(256 MiB),超过后按 LRU 淘汰
max_text_lengthint500单次合成文本长度上限
max_concurrencyint1最大并发合成数

MiniMax 使用 type: minimax-t2a-v2。voice_id 可以是系统音色、已激活的 克隆音色或设计音色。Provider 使用同步非流式 /v1/t2a_v2 接口,并支持 mp3、wav、flac 和 pcm 输出。

yaml
webapi:
  enabled: true
  auth_token: "${WEBAPI_AUTH_TOKEN}"
  speech:
    enabled: true
    default_backend: minimax
    backends:
      minimax:
        type: minimax-t2a-v2
        api_key: "${MINIMAX_LLM_API_KEY}"
        base_url: "https://api.minimaxi.com"
        model: speech-2.8-hd
        audio_format: mp3
        sample_rate: 32000
        bitrate: 128000
        channel: 1
        language_boost: Chinese
        timeout_seconds: 60
    voices:
      nahida:
        backend: minimax
        voice_id: "your-activated-minimax-voice-id"
        speed: 1.0
        volume: 1.0
        pitch: 0
        emotion: calm  # 可选;请求中的受支持 style 会覆盖它
    default_voice: nahida
    max_text_length: 500
    max_concurrency: 2

MiniMax 后端还支持 tts_path、trust_env、force_close_connections、 aigc_watermark 和 extra_body。SpeechRequest.speed、pitch、受支持的 情绪 style 以及 output_format 会按请求覆盖对应默认值。API Key 应通过 环境变量注入,不要写入 YAML。

Desktop / Gateway Node 协议 ​

webapi.nodes 控制 Gateway 与 Desktop App 等 Node 之间的 WebSocket 协议层 (心跳、配对与 node token)。

键类型默认值说明
enabledbooltrue是否启用 Node 协议层
heartbeat_interval_msint15000Node 心跳发送间隔(毫秒)
heartbeat_timeout_msint45000心跳超时(毫秒),超时判定节点离线
pairing_ttl_secondsint600一次性配对 token 的有效期(秒)
node_token_ttl_secondsint0长期 node token 有效期(秒);0 = 永不过期
yaml
webapi:
  enabled: true
  auth_token: "${WEBAPI_AUTH_TOKEN}"
  nodes:
    enabled: true
    heartbeat_interval_ms: 15000
    heartbeat_timeout_ms: 45000
    pairing_ttl_seconds: 600
    node_token_ttl_seconds: 0

WebUI ​

在 webui 键下配置。控制浏览器端管理控制台。

键类型默认值说明
enabledbooltrue是否启用 WebUI(需构建前端资源)
authobject(见下文)认证配置

WebUI 认证 ​

在 webui.auth 下配置。

键类型默认值说明
enabledbooltrue是否启用登录认证
admin_password_hashstr""PBKDF2-SHA256 管理员密码哈希;格式为 pbkdf2_sha256$迭代次数$salt$digest
session_ttl_secondsint3600登录会话有效期(秒)
login_rate_per_minuteint5每分钟最大登录尝试次数
bind_session_to_ipbooltrue是否将 session 绑定到客户端 IP

可在部署目录交互式生成哈希,密码不会进入 shell 历史:

bash
nahida-bot webui hash-password

频道插件 ​

频道配置通过 extra="allow" 机制注入:顶层键名如果匹配某个插件 ID,对应的值会合并到该插件的配置中。

Telegram ​

在 telegram 键下配置。

键类型默认值说明
bot_tokenstr""Telegram Bot API token(必填),可回退到 TELEGRAM_BOT_TOKEN 环境变量
proxystr""SOCKS5/HTTP 代理地址,如 socks5://127.0.0.1:1080
polling_timeoutint30Long polling 超时(秒)
polling_max_backofffloat30轮询错误时的最大退避延迟
allowed_chatslist[str][]聊天 ID 白名单,空 = 接受所有
reply_to_inboundbool | nullnull是否覆盖 router.reply_to_inbound;null/省略表示跟随全局
send_retry_attemptsint3发送限流时的重试次数
media_download_dirstr"./data/temp/media"媒体文件下载目录

示例 ​

yaml
telegram:
  bot_token: "${TELEGRAM_BOT_TOKEN}"
  polling_timeout: 30
  allowed_chats: []

Discord ​

在 discord 键下配置。基于 discord.py 网关连接;需先在 Discord Developer Portal 创建 Bot 并手动开启 Message Content Intent(Privileged Intent),再执行 uv sync --group discord。

会话地址映射:私信 → discord:private:<dm_channel_id>,服务器文字频道 → discord:channel:<channel_id>,Thread/论坛帖 → discord:thread:<thread_id>(每个 Thread 独立会话)。

已注册的 / 命令会自动同步为 Discord 原生 slash command(服务器级、即时生效;插件启停后自动重推)。带 choices/completer 参数元数据的命令(如 /model)在 Discord 里获得原生参数自动补全;slash 调用与文本 / 调用走同一套 handler。

键类型默认值说明
bot_tokenstr""Discord Bot token(必填),可回退到 DISCORD_BOT_TOKEN 环境变量
proxystr""HTTP/SOCKS 代理地址(国内部署通常需要),可回退到 DISCORD_PROXY 环境变量
group_trigger_modestr"mention"服务器频道/Thread 内的触发方式:none / mention(@bot)/ command(命令前缀或 @bot)/ always;私信始终响应
group_context_captureboolfalsetrue 时未触发的服务器消息记录为观察上下文
reply_to_inboundbool | nullnull是否覆盖 router.reply_to_inbound;null/省略表示跟随全局
allowed_guildslist[str][]服务器(guild)ID 白名单,空 = 不限制;私信不受此限制
allowed_dm_userslist[str][]私信用户 ID 白名单,空 = 不限制
blocked_channelslist[str][]在允许的服务器内排除特定频道/Thread
register_slash_commandsbooltrue将已注册命令同步为 Discord 原生 slash command
message_max_lengthint2000出站消息拆分长度上限(Discord 硬限制 2000)
send_retry_attemptsint3发送限流时的重试次数
media_download_dirstr"./data/temp/media"媒体文件下载目录

示例 ​

yaml
discord:
  bot_token: "${DISCORD_BOT_TOKEN}"
  proxy: "${DISCORD_PROXY:}"
  group_trigger_mode: "mention"
  allowed_guilds: []

Milky (QQ) ​

在 milky 键下配置。需要先启动 Lagrange.Milky 实例。

连接 ​

键类型默认值说明
base_urlstr"http://127.0.0.1:3000"Milky HTTP 基础 URL
access_tokenstr""Milky API 访问令牌
api_prefixstr"/api"HTTP API 前缀
event_pathstr"/event"WebSocket 事件路径
ws_urlstr""完整的 WebSocket URL 覆盖(如 ws://host:3000/event)

触发 / 访问控制 ​

键类型默认值说明
command_prefixstr"/"命令前缀
group_trigger_modestr"mention"群消息进入 Router/Agent 的方式:none(不触发)、mention(必须 @ 机器人,命令也需 @)、command(命令前缀或 @ 机器人)、always(全部消息)
reply_to_inboundbool | nullnull是否覆盖 router.reply_to_inbound;null/省略表示跟随全局
allowed_friendslist[str][]QQ 好友白名单,空 = 不限制
allowed_groupslist[str][]QQ 群白名单,空 = 不限制

超时 / 重连 ​

键类型默认值说明
connect_timeoutfloat10.0HTTP 连接超时(秒)
heartbeat_timeoutfloat30.0WebSocket 心跳超时(秒)
reconnect_initial_delayfloat1.0初始重连延迟(秒)
reconnect_max_delayfloat30.0最大重连延迟(秒)

发送 / 媒体 / 转发 ​

键类型默认值说明
send_retry_attemptsint3发送消息的重试次数
send_retry_backofffloat1.0重试退避间隔(秒)
max_text_lengthint4000出站文本最大长度
media_download_dirstr"./data/temp/media"媒体文件下载目录
enable_media_download_toolbooltrue是否注册媒体下载工具
resource_url_ttl_hintint300临时 URL 的 TTL 提示(秒)
cache_media_on_receivebooltrue收到消息时立即缓存媒体
pending_file_ttl_secondsfloat600.0待投递文件队列的 TTL(秒);纯文件消息不会单独触发 Agent,文件会排队等下一个触发消息一并注入
max_forward_depthint3合并转发最大嵌套深度
max_forward_messagesint80单次合并转发最大消息数
forward_render_max_charsint12000转发渲染的文本预算(字符)
scene_cache_sizeint4096Peer-to-scene 缓存条目数

示例 ​

yaml
milky:
  base_url: "http://127.0.0.1:3000"
  access_token: "${MILKY_ACCESS_TOKEN}"
  group_trigger_mode: "mention"
  allowed_friends: []
  allowed_groups: []

OneBot (v11) ​

在 onebot 键下配置。目前仅支持 OneBot v11 正向 WebSocket 模式 (protocol_version: "v12" 与 WebHook 模式未实现)。

键类型默认值说明
protocol_versionstr"v11"仅支持 v11;v12 未实现
ws_urlstr""正向 WS 地址(必填),如 ws://127.0.0.1:6700
ws_access_tokenstr""WS 鉴权 token
command_prefixstr"/"命令前缀
group_trigger_modestr"mention"群消息触发方式:none / mention / command / always
group_context_captureboolfalse是否捕获群聊观察上下文
reply_to_inboundbool | nullnull覆盖 router.reply_to_inbound
allowed_friendslist[str][]好友白名单,空 = 不限制
allowed_groupslist[str][]群白名单,空 = 不限制
reconnect_initial_delayfloat1.0初始重连延迟(秒)
reconnect_max_delayfloat30.0最大重连延迟(秒)
max_text_lengthint4000出站文本最大长度
split_long_textbooltrue超长文本自动分段发送
max_forward_depthint3合并转发最大嵌套深度(0–10)
max_forward_messagesint80单次合并转发最大消息数
forward_render_max_charsint12000合并转发渲染的文本预算
media_download_dirstr"./data/temp/onebot"媒体文件下载目录
enable_media_download_toolbooltrue是否注册媒体下载工具
cache_media_on_receivebooltrue收到消息时立即缓存媒体

合并转发在收到后会被解析而非占位:通过 get_forward_msg 递归拉取, 按 - {sender_name}: {content} 渲染,超过 max_forward_depth 时截断为 [Forward: {id}, messages={n}, truncated=true],超过 forward_render_max_chars 时以 [Truncated] 标记截断;转发内部的图片、 语音、视频、文件会提取为一等 InboundAttachment。

示例 ​

yaml
onebot:
  ws_url: "ws://127.0.0.1:6700"
  ws_access_token: "${ONEBOT_ACCESS_TOKEN}"
  group_trigger_mode: "mention"
  allowed_friends: []
  allowed_groups: []

插件配置 ​

以下为常见内置插件的顶层配置块(同样通过 extra="allow" 机制注入)。

image_generation(图片生成) ​

顶层 image_generation: 启用 /draw、/生图 命令和 image_generate 工具。backends 是后端字典,provider 选择默认使用的后端名。

键类型默认值说明
providerstr"default"默认后端名
backendsdict(见下文)后端配置
output_dirstr"generated/images"输出目录(相对 workspace,不能越界)
auto_sendbooltrue生成后自动发送
command_nameslist[str]["draw", "生图"]注册的命令名
caption_templatestr""图片说明模板
max_images_per_24hint0每 24h 生成上限,0 = 不限

openai-images(OpenAI 兼容 Images API) ​

键类型默认值说明
typestr"openai-images"后端类型
base_urlstr"https://api.openai.com/v1"API 端点
api_keystr""API 密钥
modelstr"gpt-image-1"模型名
sizestr"1024x1024"图片尺寸
qualitystr"auto"质量
timeout_secondsfloat120.0生成超时
download_timeout_secondsfloat60.0下载超时
max_concurrencyint1最大并发(1–16)
max_images_per_requestint1单请求最多图片(1–10)

minimax(MiniMax 图片生成) ​

键类型默认值说明
typestr"minimax"后端类型
base_urlstr"https://api.minimaxi.com"API 端点(/v1/image_generation)
api_keystr""API 密钥
modelstr"image-01"模型名
aspect_ratiostr"1:1"比例:1:1、16:9、4:3、3:2、2:3、3:4、9:16、21:9
width / heightint0尺寸;0 时用 aspect_ratio(image-01 需为 8 的倍数)
style_typestr""风格(image-01-live:漫画/元气/中世纪/水彩)
style_weightfloat0.8风格强度(0.01–1.0)
response_formatstr"url"url 或 b64_json(映射为 base64)
seedint|nullnull随机种子
prompt_optimizerboolfalse提示词优化
aigc_watermarkboolfalseAIGC 水印
max_images_per_requestint1单请求最多图片(1–9)

codex-images(ChatGPT Codex 订阅) ​

复用 type: codex LLM provider 的 OAuth token 调用 chatgpt.com/backend-api/codex/images/generations,走 Plus/Pro 订阅额度。 前提是先运行 nahida-bot auth login codex。

键类型默认值说明
typestr"codex-images"后端类型
provider_idstr"codex"必须匹配 providers 中 type: codex 的 key
base_urlstr"https://chatgpt.com/backend-api/codex"API 端点
modelstr"gpt-image-2"模型名
size / quality / backgroundstr"auto"生成参数
timeout_secondsfloat180.0生成超时
max_images_per_requestint1单请求最多图片(1–10)
yaml
image_generation:
  enabled: true
  provider: codex
  backends:
    codex:
      type: codex-images
      provider_id: codex
      model: "gpt-image-2"
      size: "auto"
      quality: "auto"
      background: "auto"
      timeout_seconds: 180
  output_dir: "generated/images"
  auto_send: true
  max_images_per_24h: 20

环境变量 ​

所有 YAML 值均支持插值:

  • ${VAR_NAME} — 从 .env 文件或环境变量解析
  • ${VAR_NAME:fallback} — 解析并带回退值

配置中常用的环境变量:

变量使用者说明
TELEGRAM_BOT_TOKENTelegram 频道Bot API token
DISCORD_BOT_TOKENDiscord 频道Bot token
DISCORD_PROXYDiscord 频道HTTP/SOCKS 代理地址
DEEPSEEK_LLM_API_KEYDeepSeek providerAPI 密钥
DEEPSEEK_LLM_BASE_URLDeepSeek providerAPI 基础 URL
SILICONFLOW_LLM_API_KEYSiliconFlow providerAPI 密钥
SILICONFLOW_LLM_BASE_URLSiliconFlow providerAPI 基础 URL
MINIMAX_LLM_API_KEYMinimax providerAPI 密钥
OPENAI_API_KEYOpenAI Responses providerAPI 密钥
OPENAI_API_BASE_URLOpenAI Responses providerAPI 基础 URL
IMAGE_API_KEYimage_generation 插件图片生成 API 密钥
IMAGE_BASE_URLimage_generation 插件图片生成 API 基础 URL
GITHUB_WEBHOOK_SECRETGitHub notifier 插件GitHub webhook 签名密钥
GITHUB_TOKENGitHub notifier 插件GitHub API token
MILKY_ACCESS_TOKENMilky 频道访问令牌
ONEBOT_ACCESS_TOKENOneBot 频道WS 访问令牌
NAHIDA_CONFIG配置加载器覆盖 config.yaml 路径
ENV_PATH配置加载器覆盖 .env 文件路径
NAHIDA_OPENAI_ORIGINATORCodex providerOAuth 归因字符串,默认 "nahida-bot"
NAHIDA_OPENAI_CLIENT_IDCodex providerOAuth client id(逃生阀)
NAHIDA_BOOTSTRAP_PROVIDERbootstrap非交互模式要配置的 provider 类型
NAHIDA_BOOTSTRAP_PROVIDER_IDbootstrap非交互模式 provider ID,默认 main
NAHIDA_BOOTSTRAP_CHANNELSbootstrap非交互模式要接入的 channel 列表(逗号分隔)

变量通常存放在项目根目录的 .env 文件中。CLI 命令(start、doctor、 config 等)会自动发现 ./config.yaml 与 ./.env,解析顺序见 快速开始。也可用 nahida-bot bootstrap 交互式生成最小配置。


完整示例 ​

项目根目录的 config.yaml 已是多 provider 的完整配置模板。

yaml
app_name: "Nahida Bot"
debug: false
log_level: "INFO"
log_file: "./data/logs/nahida.log"
log_file_level: "DEBUG"
db_path: "./data/nahida.db"
system_prompt: "You are a helpful assistant."
default_provider: deepseek-main
enable_silent_reply: true

providers:
  deepseek-main:
    type: deepseek
    api_key: "${DEEPSEEK_LLM_API_KEY:}"
    base_url: "${DEEPSEEK_LLM_BASE_URL:https://api.deepseek.com}"
    stream_responses: true
    models:
      - name: "deepseek-v4-pro"
        tags: [primary]
      - name: "deepseek-v4-flash"
        tags: [cheap]

  siliconflow:
    type: "openai-compatible"
    api_key: "${SILICONFLOW_LLM_API_KEY:}"
    base_url: "${SILICONFLOW_LLM_BASE_URL:https://api.siliconflow.cn/v1}"
    merge_system_messages: true
    stream_responses: true
    models:
      - name: "Qwen/Qwen3-Embedding-8B"
        tags: [embedding]
      - name: "Qwen/Qwen3.6-35B-A3B"
        tags: [primary, vision]
        capabilities:
          image_input: true
          max_image_count: 4

multimodal:
  image_fallback_mode: "auto"
  media_context_policy: "cache_aware"
  image_fallback_model: "siliconflow/Qwen/Qwen3.6-35B-A3B"

router:
  max_history_turns: 200
  show_reasoning: false
  reasoning_max_chars: 2000
  group_context:
    enabled: true
    max_messages: 20
    ttl_seconds: 900
    topic_gap_seconds: 300
    continuity_gap_seconds: 1800

webapi:
  enabled: true
  auth_token: "${WEBAPI_AUTH_TOKEN}"
  cors_origins: ["*"]

webui:
  enabled: true
  auth:
    enabled: true
    admin_password_hash: "${WEBUI_ADMIN_PASSWORD_HASH}"

memory:
  enabled: true
  retrieval:
    fts_enabled: true
  embedding:
    enabled: true
    model: "embedding"
  consolidation:
    rule_based_enabled: true

scheduler:
  memory_dreaming_enabled: true
  memory_dreaming_model: "memory"

processes:
  enabled: true
  defaults:
    restart_policy: "on-failure"
  specs:
    ssh-db-tunnel:
      command: "ssh -N -L 3306:db.internal:3306 bastion@example.com"
      shell: true
      restart_policy: "always"
      health_check:
        type: "tcp_port"
        host: "127.0.0.1"
        port: 3306

motion_planner:
  enabled: false
  model_tag: "cheap"
  timeout_seconds: 15.0

身份与动作授权 ​

identity.enabled 只控制 Person 关联、身份观察与记忆归属。工具授权由独立的 authorization 配置控制,关闭 identity 不再关闭权限检查。平台认证账号仍会 传递给授权模块,但不会因此创建 Person 或启用身份记忆。

模式普通用户执行策略风险审查
standard(默认)exec、workspace_write 等要求管理员保留标准权限检查
relaxed允许脚本、文件写入和其他经审查的工具调用独立模型检查具体调用,有明确危险证据才拒绝
unsafe放开普通执行工具的管理员门槛不做风险模型审查,记录放行事件

当前 relaxed 和 unsafe 都使用 bot 的宿主机账号执行,不是沙箱。 风险模型 可能漏检;脚本能接触该 OS 账号可访问的文件、环境和网络。这里的管理员身份限制 仅约束直接工具调用,不能阻止已获宿主机执行权限的脚本间接访问相同资源。 隔离执行、网络出口控制和产物所有权管理尚未实现。

yaml
identity:
  enabled: true

authorization:
  mode: standard
  admins:
    - "milky:user:123456789"
  chats:
    "milky:group:833325688": relaxed
    "milky:group:732870642": relaxed
  # 精确账号覆盖优先于所在群和默认模式;只给明确选择的账号开放。
  # accounts:
  #   "milky:user:987654321": unsafe
  review:
    model: cheap                 # 已配置的模型标签或 provider/model
    timeout_seconds: 20
    max_input_chars: 60000

模式匹配顺序:accounts 精确账号 → chats 精确聊天地址 → mode。聊天键可以 包含 SDK 支持的线程 ID;不要填写会话历史 ID。配置由部署者选择,模型参数和群消息 不能修改模式。配置修改后需要重启 bot;本版本没有权限热更新或用户自助切换 UI。

authorization.admins 未填写时兼容读取 identity.admins;显式 admins: [] 代表不继承任何管理员。Person 关联不会赋予管理员身份。即使启用了 relaxed/unsafe, 无可识别账号的特权调用仍然拒绝,身份/MCP 管理、桌面控制和跨聊天 message 工具 仍要求管理员,历史工具仍按 identity.chat_domains 限定聊天范围。

search_files、web_fetch、当前聊天附件及既有范围受限工具不因使用网络或文件而 要求管理员。relaxed 对 exec、workspace_write、未知插件/MCP 工具等执行独立 风险审查;审查器仅获得原始任务、工具描述和参数,不附带完整历史、宿主文件或工具。 审查服务不可用、超时、输出无效或输入过长时,不执行该调用并返回 risk_review_unavailable;明确危险行为返回 dangerous_action。不会自动切换 unsafe。

定时脚本创建/修改时审查实际命令,每次触发时重新按发起账号和目标聊天检查。 撤回相应模式后,后续脚本触发会失败,不会改走 Agent 来绕过拒绝。旧的无账号脚本任务 在新策略下不能执行,需要部署者补齐归属或以已认证账号重新创建。网关创建脚本任务也 需要保存有效发起账号,否则触发时会失败。

升级注意:未配置 authorization 时使用 standard。之前依靠 identity.enabled: false 让任意用户执行 shell 的部署,升级后会收紧;如需保留宽松体验,应显式选择 relaxed 或 unsafe。回滚策略使用 standard,不能再通过关闭 identity 回滚授权。

日志:authorization.configured、authorization.host_execution_enabled、 authorization.reviewed、authorization.review_unavailable、 authorization.unsafe_allowed。授权审计不记录完整脚本、参数或模型证据原文;原有工具 执行日志与运行记录仍按各自配置保留。