配置文件
Kiki 的长期偏好保存在 TOML(结构清晰的纯文本格式)文件里,分布在三处,改之前值得先分清:
| 文件 | 存放内容 |
|---|---|
~/.kiki/config.toml | Agent 与运行时设置,以及模型和供应商定义 |
~/.kiki/credentials/credentials.toml | API 密钥、OAuth 令牌与 MCP 凭据 |
~/.kiki/tui.toml | 终端侧偏好:主题、编辑器、通知、自动更新 |
config.toml 在首次运行时创建。保存的偏好会保留到下次启动,运行中 Kiki 会同时监听 config.toml 和凭证文件。
配置文件位置
要把整个数据目录换到别处,设置 KIKI_HOME 环境变量:
export KIKI_HOME=/path/to/kiki-home配置文件随之变为 $KIKI_HOME/config.toml——无论目录在哪,文件名始终是 config.toml——凭证在 $KIKI_HOME/credentials/credentials.toml。
TIP
TOML 字段名一律用下划线(snake_case),如 default_model、max_context_size。字段名里若含 .,需用引号包住,例如 [models."gpt-4.1"]——否则 TOML 会把 . 解释为嵌套表分隔符。
配置修改如何生效
Kiki 在运行时监听 config.toml 和 credentials/credentials.toml。保存合法修改后内容稳定即自动重载,改请求并发规则不需要重启或执行 /reload;定期检查会补上遗漏的文件通知,尚未写完的保存会被重试。解析失败时保留上一份有效配置并给出诊断,请修复诊断指名的文件,不要从设置页覆盖它。
文件重载与设置生效的时机不同:
| 设置 | 生效时机 |
|---|---|
request_governance | 修改加载后立即重新判断等待中的请求和 Agent 启动;在飞工作正常结束 |
default_model、default_permission_mode、default_plan_mode 等会话默认值 | 新会话;已有会话保留自己的选择 |
identity | 下次启动进程 |
tui.toml | 下次启动,或在 TUI 执行 /reload-tui |
TUI 的 /reload 仍可手动重载 config.toml 和 tui.toml。按轮次或会话保存快照的设置遵循各节说明的时机;文件自动重载不会替换正在执行的请求。
完整示例
以下示例覆盖最常用的配置项,可直接复制后按需修改:
default_model = "kimi-code/k3"
default_permission_mode = "auto"
default_plan_mode = false
merge_all_available_skills = true
[providers."managed:kimi-code"]
type = "kimi"
base_url = "https://api.kimi.com/coding/v1"
[models."kimi-code/k3"]
provider = "managed:kimi-code"
model = "k3"
max_context_size = 1048576
capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ]
display_name = "K3"
support_efforts = [ "low", "high", "max" ]
default_effort = "max"
[models."kimi-code/kimi-for-coding"]
provider = "managed:kimi-code"
model = "kimi-for-coding"
max_context_size = 262144
capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ]
[models."kimi-code/kimi-for-coding-highspeed"]
provider = "managed:kimi-code"
model = "kimi-for-coding-highspeed"
max_context_size = 262144
capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ]
[thinking]
enabled = true
effort = "high"
keep = "all"
[loop_control]
max_attempts_per_step = 5
reserved_context_size = 50000
[background]
max_running_tasks = 4
keep_alive_on_exit = false
[nb_search.credential_slots."exa.default"]
provider_id = "exa"
env = "NB_SEARCH_EXA_API_KEY"
[nb_search.defaults]
search_lane = "exa.search"
[[permission.rules]]
decision = "allow"
pattern = "Read"
[[permission.rules]]
decision = "deny"
pattern = "Bash(rm -rf*)"
[[hooks]]
event = "PreToolUse"
matcher = "Bash"
command = "node ~/.kiki/hooks/check-bash.mjs"
timeout = 5外部 harness 默认设置
外部 harness(实际运行 Agent 的程序)可以不选 Kiki profile,使用自身配置。main agent 的 execution 选择通过 [agent_executor_overrides.<id>.defaults] 保存可复用的 Kiki 覆盖值;会话覆盖优先于 profile 显式声明,profile 显式声明优先于这些设置,仍未设置的值由 harness 自己决定。原生执行保持 Kiki 既有的模型与 profile 默认行为。
[agent_executor_overrides."claude-acp".defaults]
# 可选:填写 harness 自己的模型 ID,而非 Kiki 原生模型 alias。
model_alias = "YOUR_HARNESS_MODEL"
thinking_effort = "high"
permission_mode = "auto"
kiki_context = []
allow_kiki_subagents = false省略模型、思考强度与权限字段,就交给 harness 自己选择。kiki_context 接受 memory、board、cron、threads、history、hooks;[] 明确关闭全部组,allow_kiki_subagents = false 明确关闭委派。在这条 execution 路径中,profile 未声明的字段继承 harness 设置。修改设置不会改写已有绑定;重新选择 execution 或显式重建上下文才会采用新值。
native_agent 选择厂商自己的 Agent。它是会话覆盖,或这里 defaults 中的一项,不是 profile 字段。会话覆盖上的 JSON null 清除这项选择,并继承 defaults。省略它,或写成 engine-default,就保留厂商默认 Agent;Kiki 此时不发送自定义 Agent 选择。新选择的值必须是该执行器已经宣告的 Agent。尚未发现时,只有执行器、该 Agent 和描述符版本仍与当前绑定一致,已有选择才会保留;发现结果不含该值时拒绝,当前绑定保持不变。
Kiki 自己的执行器只接受省略或 engine-default。AGY CLI 的菜单目前只提供 engine-default,因此默认 main agent 仍是 AGY 自己的,不会作为自定义 --agent 传出。
inject_kiki_mcp 打开或关闭 Kiki 工具桥。true 打开工具桥,且不会授予绑定已经拒绝的工具。false 关闭工具桥,已经发出的凭证也包括在内。会话覆盖上的 JSON null 继承 profile 值或这些 defaults。工具桥规则见 外部 harness 中的 Kiki 工具。
defaults.executor_prompt 接受 delivery(append、replace、preamble)、body、append、include 和 per_engine.<id> 覆盖。这些字段与所选 profile 逐项合并,因此只设置 delivery 不会抹掉默认正文。省略 include 会继承,include = [] 关闭附加段落。没有有效的 executor_prompt.body 时才使用 profile 正文。外部 execution 不会自动添加 Kiki cognition 或共享提示字段;需要哪些字段,在 include 中显式选择。
通过 REST API 修改时,向 POST /api/config 发送 agent_executor_overrides 对象。defaults 字段的 JSON null 删除该项保存值,defaults: null 删除整个默认设置块。TOML 不支持 null,直接编辑文件时删除对应键即可。bin_path、home_dir、env、args 等启动设置与 defaults 分开保存。
显示偏好与执行设置分开。外部引擎要成为新的 profile 或执行选择,需要在 [agent_executor_overrides.<id>] 下写成 show_in_profile_list = true。字段不存在时,该引擎留在设置页,不进入新选择。show_in_profile_list = false 会一直保持关闭:刷新、重新检查和再次导入都沿用这个关闭。[agent_executor_display] 的 externals_visible = false 同时挡住全部外部引擎的新选择;省略或写成 true 只打开这道总闸,已经明确关闭的引擎仍保持关闭。总闸重新打开后,只有仍为 true 的引擎回到新选择。discovery_initialized = true 记录设置页已经完成过一次导入检测,它本身不开关任何引擎。原生引擎始终留在选择里。已经绑定某个隐藏或不可用引擎的 profile 与会话继续使用该身份;这些引擎留作当前值,不会被换掉,也不会因此回到新选择列表。关闭显示不会卸载引擎、不会改已有执行绑定,也不会取消任务。
[agent_executor_overrides."claude-acp"]
show_in_profile_list = true
[agent_executor_display]
externals_visible = true
discovery_initialized = true向 POST /api/config 发送同名 snake_case 字段。JSON null 只删除对应的显示偏好,启动设置与 defaults 仍在。GET /api/config 和写入响应通过 raw.agent_executor_overrides、raw.agent_executor_display 返回这些字段;raw.agent_executors 只包含已配置的描述符,不是内置引擎目录。GET /api/executors 只读最近一次检查,不探测程序或登录。检查某一个引擎用 POST /api/executors/{id}/check。目录 status: "unknown" 表示这个引擎还没有检查结果。超过 60 秒后,响应仍带上一次的 check_status 和 checked_at,并用 check_stale: true 标明它已过新鲜期。某一引擎超时或失败只出现在该引擎上。设置页列出全部引擎,可以继续配置或 Check。第一次打开设置页且 discovery_initialized 还不是 true 时,每个外部引擎各检查一次;结果为 ready 或 warning、并且该引擎还没有明确开关的,会写成 show_in_profile_list = true。失败、超时,以及已经是 false 的引擎保持原样。这次导入记下 discovery_initialized = true 之后,再次进入设置页不再重跑。裸执行入口要同时满足三件事:程序就绪、已确认登录或已配置该引擎声明的 API 密钥环境变量、并且 show_in_profile_list 为 true。只保存了 profile、启动偏好或 Kiki 原生模型,还不能把它放进新选择。
自定义执行器描述符可通过 [agent_executors.<id>.model_probe],从只查询元数据的命令读取模型 ID。若命令的 JSON 响应把模型列表放在 command.data.models,可配置:
[agent_executors.example.model_probe]
command = "vendor.exe"
args = ["--output-format", "json", "models"]
format = "json"
json_path = ["command", "data", "models"]使用厂商真实的元数据子命令与参数顺序;print、prompt 或斜杠命令并不保证不会发起模型请求。参数以数组直接传给程序,不经过 Shell。format 接受 lines(默认)、tab 或 json;json_path 选中由字符串或带 id 对象组成的 JSON 数组,保留原始 ID。JSON 无效或数组缺失时,目录保持部分已知,不据此判定已保存的模型 ID 无效。
连续性提醒词表
Kiki 会提醒 Agent 记录持续有效的指示、查找早先决定、更新未完成待办,并在上下文压缩前后保留工作笔记。提醒追加到对话历史,不会自动保存记忆或修改系统提示词。进度提醒需要 TodoList;TodoList 不可用但记忆访问已获批准时,记录指示和回看历史提醒仍可工作。
人类轮次节奏与中英文词表统一在 loop_control 下配置。Assistant 消息、工具轮询和转发的 Agent 消息不计为人类轮次。记忆不可用时,提醒不会建议调用 MemoryWrite。
供应商凭证
供应商凭证——Kiki 调用各供应商时使用的 API 密钥——存放在 ~/.kiki/credentials/credentials.toml(覆盖数据目录时为 $KIKI_HOME/credentials/credentials.toml)。普通配置仍留在 config.toml;凭证值保持原来的 TOML 路径,供应商的 api_key 只是从 config.toml 的 [providers."<name>"] 表移到这里的同名表下。
# ~/.kiki/credentials/credentials.toml
[providers."managed:kimi-code"]
api_key = "YOUR_API_KEY"该文件是可选的。文件不存在时按空处理,回退到 config.toml 里仍然存在的凭证;两个文件为同一个供应商凭证都写了值时,credentials.toml 中的值优先。
api_key 与 [providers.<name>.env] 备用来源之间的字段级优先级见配置覆盖。
迁移已有密钥
根目录还留有旧版 credentials.toml 时,启动会把内容原样迁入 credentials/credentials.toml,迁移成功前仍可从旧位置读取;两处内容不同则停止而不擅自选择,请核对后重试。旧版 config.toml 里仍留有凭证的,启动会把它们迁入 credentials/credentials.toml 并重写 config.toml,原文件以唯一的 config.toml.bak-<YYYY-MM-DD>-<uuid> 保留为备份。备份里仍是明文密钥,核对完不再需要就删掉它。迁移成功后重复加载不会再建备份,也不会改动已迁出的凭证;同一密钥路径在两个文件里值不同时迁移会停下等你人工处理,中断或失败可能留下需要检查的备份。
文件权限
在 POSIX 系统上,Kiki 创建和改写 credentials.toml 时会请求仅属主可读写的权限(0600)。在 Windows 上,实际访问权限取决于文件及其父目录的 ACL;Kiki 目前不会验证或修复通用 credentials.toml 的 ACL。若要防止其他本机用户读取,请自行核查这些权限。
密钥处理
供应商读取 API 会返回本地存储的 API 密钥,供你在 GUI 中查看和编辑;使用环境变量的凭证只暴露变量名,不返回变量值。因此,能访问服务端 API 的人也可能读取这些已存密钥。请妥善保护 credentials.toml 和迁移备份。
顶层字段
配置文件里的字段分两类:顶层标量直接控制默认行为,嵌套表(providers、models、thinking 等)各有独立结构,在下文各节单独说明。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
default_model | string | — | 默认模型别名,必须在 models 中定义 |
default_permission_mode | string | auto | 新会话默认权限模式:manual 询问未经批准的操作;auto 自动批准普通操作、询问受保护操作;review 先交给审查者;yolo 批准大部分工具操作,但 Git 控制路径仍可能询问 |
default_plan_mode | boolean | false | 新会话是否默认以 Plan 模式(先出计划再执行)启动 |
merge_all_available_skills | boolean | true | 是否合并所有目录中的 Agent Skills |
extra_skill_dirs | array<string> | — | 额外 Skill 搜索目录,叠加到默认目录之上 |
extra_agent_dirs | array<string> | — | 额外自定义 Agent 搜索目录,叠加到默认目录之上 |
skip_builtin_profile_installation | array<string> | — | 启动时不安装到 agents/builtin/ 的内置模板名称。已有受管理副本仍可使用并继续接收安全更新;它不是运行时禁用开关 |
disabled_named_profiles | array<string> | [] | 从 subagent 发现与派发列表中隐藏的 profile 名称,不区分文件来源。默认 main agent 绑定仍可使用 |
builtin_product_skills | boolean | true | 是否向模型提供 Kiki 产品 Skills:kiki-ops 负责产品使用与配置,kiki-profile 负责创建和修改 agent profile。关闭后两者的名称和描述都不再进入系统提示词,代价是失去这些任务的引导流程 |
providers | table | {} | API 供应商表 → providers |
models | table | — | 模型别名表 → models |
model_switch | table | 先询问,再直接切换 | 切换模型时如何处理当前上下文 → model_switch |
thinking | table | — | Thinking 模式默认参数 → thinking |
loop_control | table | — | Agent 循环控制参数 → loop_control |
retry | table | — | 按错误定制的单步重试策略 → retry |
request_governance | table | 无规则 | 模型请求与 Agent 执行并发和等待预算 → request_governance |
token_counting | table | — | 对外上报哪种上下文 token 计数 → token_counting |
transcript_memory | table | — | 服务端转录历史的内存预算 → transcript_memory |
background | table | — | 后台任务运行参数 → background |
subagent | table | — | subagent 运行默认值与限额 → subagent |
agents | table | — | 委派说明默认值 → agents |
thread_communication | table | 不写 | 允许 peer thread 工具,默认关闭 → thread_communication |
mcp | table | — | MCP server 全局超时默认值 → mcp |
tools | table | — | 全局工具开关 → tools |
image | table | — | 图片压缩参数 → image |
session_title | table | — | 由哪个模型生成会话标题 → session_title |
experimental | table | — | 实验功能 flag 的持久化覆盖 → experimental |
nb_search_source | table | — | 宿主选项:内置搜索模块是否复用服务器本机的 nb-search 配置 → nb_search |
nb_search | table | — | WebSearch 与 FetchURL 背后的内置搜索与抓取模块 → nb_search |
permission | table | — | 权限规则与审查者 → permission |
interaction | table | — | Agent 提问是否阻塞当前轮 → interaction |
hooks | array<table> | — | 生命周期 hook,详见 Hooks |
identity | table | — | 自定义 Agent 身份 → identity |
prompt | table | {} | 提示词字段覆写与自定义变量 → prompt |
以下各节逐一展开上表中的嵌套配置。
providers
providers 表的每一项定义一个 API 供应商,以唯一名称为 key。可以把 API 密钥存入 credentials.toml,也可以在 config.toml 中设置 api_key_env,读取 Kiki 进程里的指定环境变量。没有这个显式引用时,在 shell 中导出密钥变量不会生效。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 供应商类型:kimi、anthropic、openai、openai_responses、google-genai、vertexai |
api_key | string | 否 | API 密钥。存放在 credentials.toml;仅当 credentials.toml 中没有该供应商的值时,才使用 config.toml 里的值 |
api_key_env | string | 否 | 非空的环境变量名,不是密钥值。存放在 config.toml;仅当 api_key 为空时读取。见凭证优先级与示例 |
base_url | string | 否 | API 基础 URL |
oauth | table | 否 | OAuth 凭据引用(storage、key 两个字段),由登录流程自动注入,通常无需手写 |
env | table<string, string> | 否 | 供应商环境值,详见下文 |
custom_headers | table<string, string> | 否 | 每次请求附加的自定义 HTTP 头 |
env 子表:可以把供应商惯用的键名(如 KIMI_API_KEY)写在 [providers.<name>.env] 里,作为 api_key / base_url 的备用来源。对于 api_key_env 指定的变量,此表中的同名值优先于进程环境,包括显式空值。这个子表只在配置文件里读取,不会修改 shell 环境:
[providers.kimi.env]
KIMI_API_KEY = "sk-xxx"
KIMI_BASE_URL = "https://api.moonshot.ai/v1"api_key_env 指定的变量缺失或为空时,不会再尝试其他凭证变量。完整解析顺序见配置覆盖。type = "vertexai" 可以不填 api_key,只要 env 子表同时写了 GOOGLE_CLOUD_PROJECT 和 GOOGLE_CLOUD_LOCATION。如果同时还设置了 API 密钥,该密钥仍会发送。见 Vertex AI。
models
models 表的每一项定义一个模型别名(即 default_model 或 -m 参数里使用的名称),以唯一名称为 key。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
provider | string | 是 | 使用的供应商名称,必须在 providers 中定义 |
model | string | 是 | 调用 API 时实际传给服务端的模型 ID |
pricing_model | string | 否 | 用于估算用量成本的规范模型名,与上游模型 ID 独立;例如代理别名可以按 gpt-6-sol 计价。价格缺失时仍标为未知,不会改变实际发给供应商的模型 |
max_context_size | integer | 是 | 最大上下文长度(token 数),必须 ≥ 1 |
max_input_size | integer | 否 | 模型声明的单次请求输入上限(当低于总窗口时,如 gpt-5 的 400k 窗口 / 272k 输入)。压缩、上下文溢出检查和用量比率优先使用它;补全预算仍使用总窗口。解析时会被钳制到不超过 max_context_size |
max_output_size | integer | 否 | 单次请求的输出 token 上限(对应 max_tokens)。目前仅 anthropic 供应商读取。为 Claude 模型设置后,这个显式值会覆盖内置的服务端最大值 |
capabilities | array<string> | 否 | 显式追加的能力标签:thinking、always_thinking、image_in、video_in、audio_in、tool_use。与供应商自动识别的能力取并集,只能追加不能移除 |
support_efforts | array<string> | 否 | 模型接受的 Thinking 档位。对 kimi 而言,在运行时选择列表外的值会报错;模型解析时若配置值或之前的值不受目标模型支持,会回落到目标模型的 default_effort,并将该有效值同步给 UI。支持 Thinking 但没有此字段的 Kimi 模型使用布尔 on / off。其他 provider 在协议提供原生 effort 字段时会原样传递具体值;协议仅提供等级或 token budget 时,只做必要的格式转换。managed 和 open-platform 刷新可能会改写该字段;如需手动固定,请改用 [models."<alias>".overrides] support_efforts |
default_effort | string | 否 | 模型的默认 Thinking 档位。managed 和 open-platform 刷新可能会改写该字段;如需手动固定,请改用 [models."<alias>".overrides] default_effort |
service_tier | string | 否 | 使用此模型的每个请求采用的服务档位:auto、default、flex 或 priority。优先于 profile、route 和单次请求的档位,对主 Agent 和子 Agent 均生效。只有 openai_responses 会编码此字段,其他协议忽略它;省略时保留 profile 或单次请求的档位 |
request_params | table | 否 | 合并进该模型每次请求的额外请求参数(如 temperature、top_p);取值可为字符串、数字或布尔值。跨层时按键合并 |
context_budget | integer | 否 | 该模型有效上下文窗口的 token 上限;不会超过模型真实容量。跨层取最小值 |
auto_compact | integer | 否 | 该模型的自动压缩点,写绝对 token 数。profile 或会话层的值优先;不改变模型窗口上限。该字段也可写在本模型的 overrides 表中 |
max_completion_tokens | integer | 否 | 单次请求补全 token 的上限。跨层取最小值,且受模型输出上限约束 |
off_effort | string | 否 | 关闭 Thinking 时在线上传输的 effort 编码(如 xai grok 的 none)。仅对声明了该编码的模型(catalog 会导入)有意义:设置后选择 Off 会发送这个值而不是省略 effort 字段——对默认就会推理的模型,这是真正关闭推理的唯一方式 |
protocol | string | 否 | 此模型的请求格式:anthropic、openai、openai_responses 或 google-genai。解析顺序是该字段,然后是本身属于这四值之一的供应商类型,最后是厂商基座格式。与供应商类型不同是合法的网关选择。不接受写入 overrides;写在那里会给出警告且不会生效 |
beta_api | boolean | 否 | 仅 anthropic 传输层:让请求走 beta Messages API 端点而不是标准端点。不接受写入 overrides |
base_url | string | 否 | 模型级端点。即使省略 protocol,解析时也优先于供应商的 base_url,且它本身不改变请求格式。不接受写入 overrides;写在那里会给出警告且不会生效 |
display_name | string | 否 | UI 中显示的名称,未设时回退到 model |
aliases | array<string> | 否 | 该模型的额外路由键。任意一项精确匹配都会解析到这个表键,包含 / 的旧名称也可以。这是重命名表键后让旧名称继续可用的正规做法。两个模型声明同一段 alias 字符串会报错 |
reasoning_key | string | 否 | 仅 openai 供应商。当网关用非标准字段名返回推理内容时才需要设置;默认自动识别 reasoning_content / reasoning_details / reasoning |
adaptive_thinking | boolean | 否 | 仅 anthropic 供应商。强制开启或关闭 adaptive thinking,覆盖按模型名推断的逻辑。省略时自动推断(Claude ≥ 4.6 使用 adaptive) |
prompt_overrides | table | 否 | 该模型 alias 的提示词字段覆写,可含 files 与 fields;详见 prompt |
cognition | table | 否 | 挂到该模型别名上的提示词正文或文件引用 → 模型认知 |
别名中含 . 时需要加引号:
[models."gpt-4.1"]
provider = "openai"
model = "gpt-4.1"
max_context_size = 1048576显式迁移旧版模型参数
旧版配置把 temperature / top_p 和 max_completion_tokens / service_tier 放在不同位置。设置 → 模型与提供商 → 服务与账号 → 维护 → 旧版模型参数迁移 可以把它们复制到某个模型的 parameters 表里。
先点预览迁移:它只读列出模型别名、参数名、需要你人工判断的原因、一个修订标识和将使用的备份名称,不写任何文件。没有歧义的值会被复制;有歧义或冲突的值留给你决定。你原有的字段不会被删除,所以请读预览,而不是假设配置已经变了。
再点应用预览的改动:它会先在 config.toml 旁以唯一的 config.toml.generation-backup-<uuid> 逐字备份原文件,然后才动配置;如果配置在预览之后被改过,它拒绝写入。该备份包含你的原始密钥,请像保护 config.toml 和 credentials.toml 一样保护它,不再需要时就删掉。
恢复备份需要单独一次确认,而且只有当前配置仍与该备份产生的版本逐字一致时才会恢复;期间任何其他编辑都会挡住它。迁移后尽早恢复:修订标识用的是逐字节比较,所以之后若某次编辑恰好让配置回到完全相同的字节,系统发现不了,旧备份就可能撤销更新的工作。
模型别名解析
[models] 每一项的键就是模型别名——default_model、-m 以及 Agent 的 model_alias 用的都是这个名字。请求按下面的顺序解析:
- 精确的表键
- 与某条模型的
aliases列表精确匹配 - 无歧义的裸名,匹配表键或记录的
model字段(相等,或以/<name>结尾) - 带供应商前缀的名称(
<prefix>/<name>):最后一段是表键,且前缀与该记录的provider一致
在匹配唯一时,裸名和带供应商前缀的名称可以互相解析。若有多个已配置模型同时匹配,解析会失败,并提示使用完整模型 id 来消歧。
缩短表键之后,把旧名称写进 aliases,会话和 Agent profile 里仍保存旧名的地方就能继续工作:
[models.fast-model]
provider = "openai"
model = "fast-model"
max_context_size = 1048576
aliases = ["openai/fast-model"]审查用模型也一样,如果旧键带供应商前缀:
[models.k3-review]
provider = "openai"
model = "k3-review"
max_context_size = 262144
aliases = ["openai/k3-review"]模型覆盖项
如果某些用户覆盖需要在 provider-model 刷新后保留,请写到 [models."<alias>".overrides]。运行时读取的是 effective 值:有 override 时用 override,否则用顶层字段。
[models."kimi-code/kimi-for-coding"]
provider = "managed:kimi-code"
model = "kimi-for-coding"
max_context_size = 262144
[models."kimi-code/kimi-for-coding".overrides]
max_context_size = 131072
display_name = "Kimi for Coding (custom)"[models."<alias>".overrides] 接受普通模型字段,例如 max_context_size、max_input_size、max_output_size、capabilities、display_name、reasoning_key、adaptive_thinking、support_efforts、default_effort、off_effort、service_tier、request_params、context_budget、auto_compact 与 max_completion_tokens。不接受身份 / 路由字段:provider、model、protocol、beta_api 和 base_url。把这些字段写进 overrides 会在加载配置时给出警告,且不会改到模型;请写在模型自身上。模型设置页会标出这条警告,并显示有效格式、端点和凭据来自模型、提供商还是环境变量,不显示密钥或端点地址。对这些新增字段,先得到模型 alias 的有效配置(包括其 overrides),再按 "模型 alias → profile 顶层 → 命中的 model_profiles 条目" 合并:request_params 逐键覆盖,service_tier 使用最后一个明确值;context_budget 和 max_completion_tokens 是限制,取各层声明值的最小值,并继续受模型容量与输出上限约束。省略限制表示不增加限制。
Recipe 可以覆盖支持的模型提示词与生成参数,但不改变模型的提供商、请求格式、端点或凭据。Recipe 中的路由字段会被拒绝;请把这些字段写在模型自身上。通过程序传入的模型设置覆盖也遵循这一规则,包括嵌套在 overrides 中的路由字段。
无需修改配置文件也可以临时切换模型——通过 KIKI_MODEL_* 环境变量在内存里合成一个临时供应商,详见用环境变量定义模型。
模型认知
[models."<alias>".cognition] 把提示词正文挂到单个模型别名上,不必修改 Agent profile。每个正文槽接受 { text = "..." },把完整正文与模型一起保存;也可引用相对 Markdown 路径或路径数组,由作者管理原文件。正文在模型绑定时读取并保存,之后的注入复用这份快照,不会重新读取磁盘上的修改。未设置的槽不会注入默认正文。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
overlay | {text: string}、string 或 array<string> | — | 合并进所绑定模型系统提示词的正文。多条文件路径按声明顺序以空行拼接 |
overlay_mode | string | append | overlay 与 profile 提示词的组合方式:append、prepend、wrap、persona 或 replace |
steering | {text: string}、string 或 array<string> | — | 在启用的 steering 触发时机作为普通 User 消息注入的正文 |
steering_on_turn | boolean | true | 在用户来源的新轮次及其压缩后重新装填上下文时注入 |
steering_on_input | boolean | true | 在新接纳的人类输入后注入,包括轮内「立即发送」的纠偏 |
steering_interval_steps | integer | 0 | 每隔用户输入驱动的 N 个模型步骤重复注入;必须非负,0 关闭定期 steering |
steering_sources | table | 已核验的子任务完成回执继承,其它来源关闭 | 按来源选择 mode:off、inherit(沿用用户设置)或 custom(单独正文与节奏) |
anchor | {text: string}、string 或 array<string> | — | 用作一轮开头若干步的完整系统提示词的正文,会替换 profile 提示词以及任何 overlay |
anchor_steps | integer | 1 | 被锚定的一轮开头有多少次模型请求使用 anchor 正文;必须至少为 1 |
anchor_scope | string | session | session 只锚定会话的第一轮;turn 锚定每一轮的开头若干步 |
内联正文保留完整文本,包括换行与首尾空白。{ text = "" } 保留显式空声明,但不注入文本,也不会用空 anchor 替换提示词;移除槽才清除该声明。main 与 independent 接受 "same"、"off" 或一份完整 cognition 对象。省略分支或 "same" 采用共享;"off" 关闭该分支上的这份声明;自定义对象缺失的槽不会从共享补齐。普通子 Agent 采用共享。
集成客户端时,先读取模型,再带上读取时的 revision(版本)保存:
const baseline = await klient.global.kosong.readModel('example-model');
await klient.global.kosong.updateModel(baseline.id, {
base_revision: baseline.revision,
cognition: {
...baseline.cognition,
overlay: { text: 'Plan first.\nThen carry out the plan.' },
},
});写入 cognition 或 prompt_overrides(包括用 null 清除)必须带 base_revision。两者均整对象写入:保留 baseline 中未改的槽、分支选择、模式和注入节奏。遇到 model_catalog.revision_conflict 时保留草稿,重新读取模型,合并编辑后再试。只编辑来源时,可带 base_revision 使用 steering_sources_patch: { common: { thread: { mode: 'inherit' } } };它增量合并指定来源及 custom 字段,不替换无关 cognition 或模型设置。
main 与 independent 的 patch 各自对应所在分支。该分支被省略或为 "same" 时,第一次保存提示词编辑会把当时生效的整组——包括未改的文件引用和节奏——复制进该分支,再替换被编辑的槽。此后该分支是自己的对象:之后对共享组的编辑不再流入它,已有的自定义对象或 "off" 也不会再从共享组补齐。steering_sources 的 inherit 沿用当前选中身份上、用户消息已经在用的 steering 正文和节奏。它用的是这份已保存的 steering,不是用户消息的原文。身份成为自己的对象之后,读的是该对象上的 steering。
main 与 independent 上的用量差异不是这种整组复制。thinking_effort、service_tier、max_completion_tokens、auto_compact 和 context_budget 按字段继承模型的共享值。保存时只发送改过的字段,放在 usage.main 或 usage.independent 下。把某个字段写成 null 会恢复该字段的继承;省略该字段不会。共享的 context_budget 或 max_completion_tokens 已经设置时,身份上更高的值不会抬高它,更低的值会收紧。thinking_effort、service_tier 和 auto_compact 按该身份上的值覆盖。
cognition_bodies.branches.<scope>.steering_sources.<source> 也返回已保存的 custom 草稿,即使当前模式为 off 或 inherit。cognition_bodies 返回共享、main、independent 已保存的手调正文与来源,不是 Recipe 或 profile 覆盖后的最终合成提示词。文件槽按声明顺序返回每个引用文件的完整原文,以及运行时裁去首尾空白、以空行拼接的正文。source_read_only: true 保护作者文件,不妨碍另存为模型正文;读取失败或该槽文件超过 2 MiB 编辑读取上限时,槽会返回错误及 writable: false,不会冒充空正文。
路径相对于 数据根目录(默认为 ~/.kiki)。绝对路径、解析后落到数据根之外的路径(包括经由符号链接)以及缺失的文件,会在 profile 绑定时被拒绝,错误信息会标出字段和路径。已声明且存在但内容为空的文件会被跳过;某个字段声明的文件全部为空时,该字段视为未设置。读取模型不改变这些文件。明确把编辑后的文件槽保存为 {text} 时,正文改存到模型中,原文件保持不变;要再次使用原文件,恢复原路径引用即可。已有会话保留冻结正文,直到显式重建上下文或换模。
三个正文槽离模型下一个 token 的远近不同。overlay 和 anchor 改写系统提示词,模型在你的请求之前读取。steering 作为普通 User 消息跟在输入之后注入,不包装成 <system-reminder>。它的正文与节奏适用于直接用户消息,包括排队输入、「立即发送」、用户斜杠激活的 Skill 和插件命令。已核验且完成的 subagent 任务回执默认继承该 steering;明确设置 steering_sources.task.mode = "off" 仍优先关闭。普通进程结果、失败子任务及其它非用户来源保持关闭,需在 steering_sources 中启用。重试沿用原输入来源。
选 mode = "inherit" 沿用当前选中身份上、用户消息已经在用的 steering 正文和节奏,选 mode = "custom" 则使用 custom.steering、custom.steering_on_turn、custom.steering_on_input 和 custom.steering_interval_steps。单独正文接受相同的内联、路径及路径数组形式;缺正文时不会继承用户文本。off 和 inherit 都保留已保存的 custom 草稿。来源键包括 thread(peer 消息和模型创建的 thread)、room、agent(子 Agent 消息与父级通知)、task、cron、hook、automation(goal 自动继续)、skill(模型工具激活)及 external(外部客户端 thread 输入)。未知来源保持关闭;通过「立即发送」投递不会把其他来源变成用户输入。
[models."example-model".cognition.steering_sources.thread]
mode = "inherit"
[models."example-model".cognition.steering_sources.task]
mode = "custom"
custom = { steering = { text = "先核结果,再继续。" }, steering_on_turn = true, steering_on_input = true, steering_interval_steps = 0 }启用 steering_on_input = true 时,新物化的输入会在下一个安全请求中跟上其已启用来源的 steering;正在流出的请求不会被改写。同一批送达的多条输入保留各自来源,相同正文只注入一份。steering_on_turn 也控制压缩后的重新注入,但轮次或间隔触发都不会开启已关闭的来源。
设置 steering_interval_steps = N 后,每经过该来源驱动的 N 个模型步骤就会再次注入,只计本 Agent,并跨轮次累计。该来源的一次 steering 注入会重新开始其间隔;轮次、输入和间隔同时命中时只追加一份。例如 N = 2 且第 1 步已有注入时,不间断继续执行会在第 3、5 步再次注入。工具结果、空闲时的状态协调和其他 Agent 的步骤都不计数。把两个布尔值设为 false 可只按间隔注入(第一份在第 N 步出现);再把间隔设为 0 可完全关闭该来源的 steering。
正文与触发参数在绑定时一起保存;恢复时继续使用冻结值,即使配置或文件已经修改。新绑定或冷恢复会重新开始间隔计数。subagent 使用公共 cognition 配置;main 和 independent 省略或设为 "same" 时共用公共配置,设为 "off" 时关闭 cognition,改为子表时则替换整个 cognition 对象。替换不会继承缺失的公共字段,因此需在子表中同时写明 steering 路径和非默认触发参数。
overlay_mode 决定 profile 提示词还剩多少:
| 模式 | 结果 |
|---|---|
append | 先是 profile 提示词,然后是 overlay |
prepend | 先是 overlay,然后是 profile 提示词 |
wrap | overlay、profile 提示词,然后是一句固定收尾,声明 overlay 仍支配推理 |
persona | overlay 替换 profile 提示词开头的 You are … 段落;该提示词的其余部分保留 |
replace | overlay 成为完整的系统提示词 |
persona 通过匹配提示词最开头的 You are 来定位身份段落。提示词以其他方式开头的 profile 没有可替换的身份段落,此时改为把 overlay 追加到末尾。
锚定是按请求替换,而不是改写已存储的提示词。被锚定的一轮里,前 anchor_steps 次请求会把 anchor 正文当作完整系统提示词发给模型;从下一步起直到会话结束,模型收到的是含 overlay 在内的常规提示词。适合用在这种场景:冗长的 profile 提示词挤掉了你希望模型在规划当下看到的调节内容,而完整提示词只在它开始工具调用之后才重要。调用方显式传入的系统提示词永远不会被替换。
模型认知绑定在别名上,而不是主 Agent 上。绑到该别名的普通子 Agent(无论该别名来自 profile pin 还是派发参数)采用其共享 cognition;main 与 independent Agent 采用各自选中的身份分支。会话中途切换别名会为新绑定的模型重新渲染 overlay。
下面的例子给一个 DeepSeek V4 模型做调节:它默认习惯逐步叙述执行过程,而不是先规划。短 anchor 是一层精简 persona,在模型规划时顶替 profile 提示词;再配上要求先规划再行动的 steering:
[models."axon-message/deepseek-v4-flash-0731".cognition]
anchor = "cognition/flash-anchor.md"
anchor_steps = 3
steering = "cognition/flash-steering.md"~/.kiki/cognition/flash-anchor.md:
You are a helpful software engineer assistant.~/.kiki/cognition/flash-steering.md:
Router: classify this task (build or fix) now, then adopt the matching style — build: direct production; fix: inspect-first. Let's first understand the problem and devise a plan; then let's carry out the plan and act.两个文件都就位后,模型会在会话的前三步先规划再行动,随后继续使用完整的 profile 提示词。
把那段措辞当作起点,而不是一项设置。哪种表述真能改变模型的推理,是在这一个模型上测出来的;另一个模型——或另一份 profile 提示词——可能需要不同的正文,也可能完全不需要。机制本身并不解读这些文件。
子 Agent 的模型绑定
子 Agent 按此顺序选模型:具体的 AgentRun 参数 model_alias → 生效 profile、route、caller lease 上的 pin → 显式配置的 [subagent].default_model。 调用方模型与主 Agent 的 default_model 都不是静默回退来源;这些来源都不存在时,派发会以 model.not_configured 失败,不会创建子 Agent。在 subagent profile、route 或 caller lease 中写 model_alias: inherit,才会绑定调用方当前已解析的模型。AgentRun 拒绝 model_alias: "inherit":请写具体的已配置模型名,或省略参数以使用目标默认模型。main agent 没有调用方,其 profile 不可使用 inherit。
thinking effort 可以留空。使用 model_alias: inherit 时,它会跟随调用方的有效思考强度;工具显式 effort,或 profile、route、caller lease、匹配的 model_profiles 条目上适用的 effort pin 优先。其他情况下按工具 effort → 匹配的 model_profiles 档位 → 所选模型与 profile pin 匹配时的 thinking_effort → 所绑定模型的 overrides.default_effort → 模型的 default_effort → 全局 [thinking].effort → 模型能力兜底档位解析。
model_switch
[model_switch] 决定切换模型时如何处理当前上下文。桌面入口是 设置 → 模型与提供商 → 默认值 上的 切换模型;这张表是保存下来的配置。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
default_mode | string | "direct" | 没有启用的规则命中时使用:direct 保留当前上下文,compact 先生成摘要,fresh 开始新的上下文窗口 |
confirm | boolean | true | 切换前询问。false 时立即按命中规则或此默认方式执行 |
rules | array<table> | [] | 例外规则,第一条启用且命中的规则生效。发送 rules 会整表替换;部分保存时省略它则保留原列表 |
每条规则有唯一且非空白的 id,enabled(省略时为 true),可选的 from_models 和 to_models,必填的 mode,以及可选的 confirm。某一侧省略表示匹配任意模型。规则自己的 confirm 在写明时覆盖全局的询问设置。匹配区分大小写,只有 * 和 ? 是通配符;其他字符(包括方括号)按字面匹配。设置页拒绝包含空格或方括号的模式。随该条提示词发送的 model_switch_mode 只覆盖这一次消息的命中规则,见 提示词。
[model_switch]
default_mode = "direct"
confirm = true
[[model_switch.rules]]
id = "to-fresh"
enabled = true
from_models = ["example/Source-*"]
to_models = ["example/target?"]
mode = "fresh"
confirm = false部分更新只改你发送的字段。POST /api/config 发送 { "model_switch": { "confirm": false } } 会保留已有规则。无效的 model_switch 对象返回信封错误码 40001,文件保持不变;同一次请求里的其他修改也不会写入。
thinking
thinking 设置 Thinking 模式的全局默认行为。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | boolean | true | 新会话是否默认开启 Thinking;设为 false 时,未固定的 effort 会关闭,但显式请求与模型覆盖项仍生效 |
effort | string | — | 模型的 default_effort 和 overrides.default_effort 之后的全局兜底档位(例如 low、medium、high、xhigh、max)。非 Kimi provider 在上游协议接受具体 effort 值时不会改写该值;如果上游拒绝,请改成该模型支持的档位。协议仅提供等级或 token budget 时,仍需做格式转换。对于带 support_efforts 的 Kimi 模型,若该配置值不在列表中,会回落到模型默认档位;没有该列表的 Kimi 模型会把任意开启值视为布尔 on |
keep | string | "all" | 保留思考透传。在 kimi 上以 thinking.keep 发送;在 anthropic(Claude 以及 Kimi 的 Anthropic 兼容模式)上以 context_management 的 clear_thinking_20251015 编辑发送(开启 keep 会让 Anthropic 请求走 beta Messages API;关值可禁用 keep 并回到标准端点)。"all" 会保留历史轮次的思考内容(reasoning_content / Anthropic thinking blocks);传入关值(false/0/no/off/none/null)可禁用。可被 KIKI_MODEL_THINKING_KEEP 覆盖;仅在 Thinking 开启时注入 |
已废弃字段
| 字段 | 废弃版本 | 描述 |
|---|---|---|
default_thinking | 0.21.0 | 顶层布尔值,由 [thinking] enabled 取代。将 default_thinking = true 迁移为 enabled = true,default_thinking = false 迁移为 enabled = false。 |
thinking.mode | 0.21.0 | 可选值 auto / on / off,由 [thinking] enabled 取代。mode = "off" 改为 enabled = false;mode = "on" 和 mode = "auto" 等价于 enabled = true(默认值),可删除该行。 |
loop_control
loop_control 控制 Agent 执行循环的步数上限、单步尝试次数上限、触发上下文自动压缩的阈值,以及压缩请求失败后的尝试次数上限。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
max_steps_per_turn | integer | — | 单轮最大步数;不设或设为 0 则无上限 |
max_attempts_per_step | integer | 5 | 单步失败后的最大总尝试次数(含首次尝试) |
thinking_only_continuation | boolean | true | 模型正常结束且只有非空思考时,显式发送一次 Continue. User 消息 |
zero_output_continuation | boolean | false | 正常结束且没有思考文本、可见正文和工具调用时,显式发送一次 Continue. User 消息 |
reserved_context_size | integer | 50000 | 自动压缩点以上为模型输出预留的 token 数 |
auto_compact | string | — | 全局默认自动压缩点,按模型可用窗口写百分比,如 "85%"。全局不接受 token 数;模型、profile、会话用正整数 token |
compaction_trigger_ratio | number | 0.85 | 旧版触发比例,仅在各层都没有设置 auto_compact 时使用 |
compaction_soft_context_size | integer | 0 | 旧版绝对 token 上限,仅在各层都没有设置 auto_compact 时使用 |
compaction_max_attempts | integer | 3 | 压缩失败后的最大总请求次数(含首次请求);所有恢复路径共用这份预算 |
会话按模型保存的 token 覆写优先,其次为命中的 model_profiles 条目、profile 顶层、模型别名,最后才是全局百分比。没有任何新 auto_compact 时,沿用旧阈值:min(0.85 × 可用窗口, 可用窗口 − 50000, 正值 compaction_soft_context_size);显式旧比例替换 0.85。保存全局新值时,会按当前模型把 token 数换算成百分比,并删除旧比例和绝对 token 上限键;换算后无法保证其他窗口大小不同的模型仍保持旧绝对上限。新阈值在下一个模型 step 前生效,不会立即压缩。用 /autocompact 查看当前会话的生效值。
max_steps_per_turn 可被环境变量 KIKI_LOOP_MAX_STEPS_PER_TURN 覆盖,max_attempts_per_step 可被 KIKI_LOOP_MAX_ATTEMPTS_PER_STEP 覆盖,优先级均高于配置文件。
重试仅针对瞬时故障——连接错误、超时、HTTP 429 限流,以及符合重试条件的 HTTP 500–599 服务端错误。已有部分输出、安全拒绝或额度耗尽时会停止,不重放请求。
当供应商确认模型正常结束,且只有非空思考、没有正文、工具调用或拒绝时,Kiki 会保留思考及原始签名,每轮最多显式发送一条 Continue. User 消息。网关的精确 antigravity_thinking_only 事件也可触发续接,但 Kiki 必须实际保留了思考,并确认没有其它输出、外部信息检索(grounding)或拒绝。取消、缺少终态事件、流中断、token 上限导致的停止均不符合条件。续接算一次真实模型请求,用量单独记录。第二次仍为空或请求失败时停止本轮;这次续接即使遇到 HTTP 429 或临时服务端错误,也不重试。
设置 [loop_control] thinking_only_continuation = false 可关闭这条自动消息,从下一个 step 边界起生效。拒绝尾部 Model 消息的 Google 模型仍保留原有的原始快照重试,它与显式续接共用每轮一次的恢复预算,不受该设置关闭。Google CONTINUATION 终态仍需此 SDK 无法发送的 continuation token。
未配置或设为 false 时,zero_output_continuation 保持关闭。设为 [loop_control] zero_output_continuation = true 后,供应商确认正常结束,且思考文本、可见回答和工具调用都为空时,Kiki 会在同一轮发送一条 Continue. User 消息。附在空思考上的签名不是思考内容,并保留在对话里。非空的 redacted 思考数据算输出。非空思考文本仍走 thinking_only_continuation。子 Agent 使用同一规则;开关关闭时,没有内容的子任务完成仍失败,第二次仍为空也会停止本轮。token 用量不参与判断。该选择从下一个 step 边界起生效。这次续接是同一轮里的一次模型请求,不按连接错误或限流重试。取消、供应商错误,以及没有正常停止终态的流,仍走原有路径。
连续性提醒设置
TodoList 和工作笔记的进度提醒按人类轮次计时,不按 Assistant 消息数量计时。已接收的用户提示、用户调用的插件命令和用户通过斜杠激活的 Skill 会推进时钟。人类 steer 纠正可触发记录指示或回看历史提醒,但不增加轮次。转发的 peer 消息、subagent 回执、模型激活的 Skill 和定时触发不推进时钟,也不构成新的人类规则。以下三个节奏字段接受正整数,示例即默认值:
[loop_control.continuity_cadence]
age_human_turns = 6
cooldown_human_turns = 8
long_task_steps = 24常规进度提醒需要有新的成功工作,距相关内容变更至少六个人类轮次,距该类上次提醒(或会话开始)至少八个人类轮次。该类首次提醒后间隔加倍到 16 个人类轮次;每类状态未变时最多发出两次进度提醒。待办提醒要求仍有未完成项。笔记提醒还要求未覆盖工作量达到 8,000 token 与压缩阈值的 10% 两者中的较大值。长任务笔记检查点可不等待新的人类轮次:距上次笔记变更和上次笔记提醒均须完成至少 24 个成功工作 step,未覆盖工作量还须达到 16,000 token 与压缩阈值的 10% 两者中的较大值。仅轮询不算成功工作。
待办与笔记分别保留年龄、工作水位、提醒时钟和两次提醒预算。内容实际变化只重置该类的年龄、工作水位及提醒预算,提醒间隔回到基础冷却值。修改列表不会重置笔记状态,修改笔记也不会重置列表的。重复写入相同内容不重置这些状态。
若要关闭低频的长期记忆维护提醒,同时保留任务进度提醒,设置:
[loop_control.continuity_cadence]
memory_maintenance = falsememory_maintenance 是布尔值,省略时默认为 true。合法配置重载后,从下一次提醒判断起生效,不会删除对话中已有的提醒。它只控制活跃工作期间的周期性维护提示(M3),每个上下文窗口最多一次。设为 false 后,新的人类持续指示提醒(M1)与压缩前对已识别、仍未处理指示的检查(M2)仍保留。它不会禁用记忆工具、改变审批策略或关闭 TodoList 工作笔记。
记忆提醒仅对非临时会话中的主 Agent 可用,前提是已启用记忆、记忆审批不为 off,且 MemoryWrite 已注册并获工具策略允许。空闲或只做轮询时不发周期性提醒。提醒要求保留对未来任务有用的指示、稳定决定或有证据的知识;没有值得保留的变化就不写。任务进度留在工作笔记中,待审批的记忆提案不算生效指引,也不应重复创建。
记录指示和回看历史提醒先匹配可配置的中英文词表,再经过本地结构门判断,不单独调用分类模型:
[loop_control.directive_cues]
instructions = ["always", "never", "以后", "不要"]
history = ["as I said", "earlier", "之前", "我说过"]提供的列表替换默认列表;空列表关闭该类提醒。英文词按单词边界匹配且不区分大小写,中文词按子串匹配。命中关键词还不够:引用示例和产品讨论不能确立持久规则,steer 纠正也必须经过同一结构门。记录指示和回看历史提醒按已接收的输入或 steer 修订去重,不是整个 turn 最多一次。已覆盖的历史引用不重复提醒;对同一已识别主题的重复引用,在待办和笔记状态未变时有三个人类轮次的冷却。新的规则修改和撤销不受该历史冷却或进度冷却限制。
配置决定默认记入任务笔记,除非用户明确要求更广的适用范围;跨会话记忆仍受原有审批策略约束。上下文窗口保留与交接重建提醒跟随压缩状态,不使用进度提醒节奏。
新会话把变化的日期、目录列表、工作区指令和记忆放在带版本的运行时快照消息中,不再为这些变化重写系统提示词。已有会话保留原布局,直到自然上下文压缩边界才迁移;不会重排旧历史。Profile 绑定、配置的提示词和运行时权限仍会随底层策略变化而更新。
retry
retry 可为指定的单步错误、Output Layer 转换和会话标题请求定制总尝试次数与固定退避时间。默认情况下,每次可重试操作最多尝试 5 次,重试前依次等待 2、4、8、16 秒,并加入最多 25% 的随机抖动(总计 30–37.5 秒)。provider 返回的 Retry-After 值或命中策略的固定 backoff 会替代对应的默认等待时间。策略还可限定精确的模型和 provider 配置键,避免一个 provider 的临时故障改变其它渠道的重试行为。本节及每条策略都是严格配置:未知字段会被拒绝,不会静默忽略。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
max_attempts | integer | — | 最大总尝试次数(含首次尝试);用于 Agent 单步时优先于 loop_control.max_attempts_per_step |
policies | array<table> | — | 用 [[retry.policies]] 编写的有序逐错误策略;首个命中的策略生效 |
每条 [[retry.policies]] 包含以下字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
match | string | 是 | 与错误码和错误名称匹配的 JavaScript 正则表达式(按模式匹配文本的规则);(?i) 等内联修饰符无效,该策略会被忽略并产生配置警告 |
models | array<string> | 否 | 精确的规范 [models] 配置键;仅绑定模型在列表中时生效 |
providers | array<string> | 否 | 精确的 [providers] 配置键;仅绑定 provider 在列表中时生效 |
max_attempts | integer | 否 | 命中错误的最大总尝试次数(含首次尝试);优先于本节的总预算 |
backoff | integer | 否 | 每次重试前固定等待的毫秒数;provider 返回的 retry-after 提示仍优先 |
retry | boolean | 否 | 默认为 true。false 可抑制 Kiki 内建判定原本会重试的错误;true 不能强制重试被判定为不可重试的错误 |
策略从上到下检查。models 或 providers 不包含当前绑定时会跳过该策略,余下策略中首个 match 命中错误的策略生效;同时设置两个 selector(选择条件)时必须全部命中。省略两个 selector 时保持原有的全局逐错误行为。
下面的配置只为一个原生 Google GenAI Argon 绑定的 HTTP 429 提供最多 20 次总尝试;其它模型和 provider 仍使用默认的 5 次:
[[retry.policies]]
match = '^provider\.rate_limit$'
models = ['gemini-4-argon']
providers = ['google-native']
max_attempts = 20
backoff = 15000请把 gemini-4-argon 和 google-native 替换成 [models] 与 [providers] 表中的精确配置键。仅当 provider 未返回 Retry-After 时才使用 backoff。模型流在协议完成事件到达前结束,属于连接失败,不会把部分回答当作成功;只有尚未观察到文本、思考或工具调用时才能重试,未完成响应中的原生工具不会执行。该策略不会让 HTTP 400、额度耗尽、部分输出或已经执行的失败变成可重试;retry = true 不会越过 Kiki 的不可重试判定。
transcript_memory
transcript_memory 控制服务端把多少转录历史留在内存里。三个字段都是可选的:省略即使用默认值。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
tail_turns | 正整数 | 20 | 每个 agent 常驻保留多少个已结束的 turn |
max_agent_bytes | 正整数 | 16777216(16 MiB) | 每个 agent 的常驻字节预算,即留在内存里的量。更早的 turn 会按需从磁盘读取 |
max_detail_cache_bytes | 非负安全整数 | 268435456(256 MiB) | 单次完整正文读取的最大缓存量。0 关掉这个额外缓存槽,内容照样读取,只是不留在该缓存里。改动后的值在下一次缓存准入或淘汰时生效;调低会淘汰放不下的内容,不会取消正在进行中的读取 |
这些是服务端内存预算,不是读取上限。调低它们会减少内存占用,可能增加从磁盘重复读取的次数。
token_counting
token_counting 决定对外上报的上下文 token 计数——即上下文大小显示所基于的值。内部逻辑(自动压缩触发、预算、超限退避)始终同时使用供应商实测与估算,不受本配置影响。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
strategy | "measured+estimated" | "measured" | "estimated" | "measured+estimated" | measured+estimated 上报实时大小——每次请求的供应商实测用量加上未实测尾部的估算——并以最近一次实测总量兜底;measured 只上报供应商实测,显示仅在每次请求完成后变化;estimated 忽略供应商实测、上报纯估算——适用于不上报用量或用量不可信的供应商 |
strategy 可被环境变量 KIKI_TOKEN_COUNTING_STRATEGY 覆盖,优先级高于 config.toml。
background
background 控制后台任务(通过 Bash 工具的 run_in_background=true 参数,或 AgentRun 工具的 background=true 参数启动)的并发数。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
max_running_tasks | integer | — | 同时运行的最大后台任务数 |
keep_alive_on_exit | boolean | false | 会话关闭时是否保留仍在运行的后台任务。默认情况下,Kiki 会在进程退出前请求停止所有后台任务;只有希望任务在会话结束后继续运行时才设为 true。在 print 模式(kiki -p)下,本字段仅作为 print_background_mode 未设置时的兼容回退:true 等价于 print_background_mode = "drain" |
kill_grace_period_ms | integer | 5000 | 会话关闭、手动停止或任务超时请求正常终止后,等待任务自行结束的宽限时间(毫秒)。超过该时间仍在运行时,Kiki 会尝试强制停止该任务 |
bash_auto_background_on_timeout | boolean | true | 前台 Bash 命令触及超时时间时,将其转为后台任务而不是直接终止:命令完成时 agent 会收到通知,转入后台的命令受 bash_task_timeout_s 默认后台超时约束。设为 false 则恢复超时即终止的行为 |
bash_file_tool_hints | boolean | true | Bash 命令只用于读、搜、写文本文件时,在结果末尾附一行专用工具提示。命令仍照常执行;设为 false 可关闭提示 |
bash_task_timeout_s | integer | 600 | 后台 Bash 任务在调用未传 timeout 时的默认超时(秒);前台命令超时转后台后也按此值重新计时。0 表示无超时——任务一直运行到自行结束或被模型手动停止。显式传入的 timeout 不受影响。在 print 模式(kiki -p)下未显式设置时默认为 0 |
print_background_mode | "exit" | "drain" | "steer" | "steer" | 仅 print 模式(kiki -p)生效,决定 main agent 的 turn 结束后如何处理未返回的后台任务:"exit" 立即退出;"drain" 退出前等待所有后台任务进入终态(结果不回馈给 main agent);"steer" 不退出,让后台任务完成时像后台 subagent 一样以合成 user 消息 steer main agent 进入新 turn,直到某 turn 结束时无未决后台任务或触及上限。设置后优先级高于 keep_alive_on_exit 的 print 回退 |
print_wait_ceiling_s | integer | 2147483 | print 模式(kiki -p)下,print_background_mode 为 "drain" 或 "steer" 时,等待/steer 循环的墙钟上限(秒;默认约 24.8 天,近似不设限)。在非 print 模式或 "exit" 时无效 |
print_max_turns | integer | 100000 | print 模式(kiki -p)且 print_background_mode = "steer" 时,允许由后台任务完成触发的新 turn 的最大数量,防止 steer 循环失控(默认值近似不设限) |
keep_alive_on_exit 可被环境变量 KIKI_BACKGROUND_KEEP_ALIVE_ON_EXIT 覆盖,max_running_tasks 可被 KIKI_BACKGROUND_MAX_RUNNING_TASKS 覆盖,优先级均高于配置文件。
在 print 模式(kiki -p "<prompt>")下,只要还有未决的后台任务,Kiki 在 main agent 的 turn 结束后不会退出:每个任务完成都会以合成 user 消息回馈给 main agent,steer 出新的 turn(默认 print_background_mode = "steer"),直到某 turn 结束时没有任何未决任务才退出。该循环受 print_wait_ceiling_s 与 print_max_turns 约束,默认值都近似不设限。print 模式下后台工作也不会被墙钟超时杀掉:后台 Bash 任务默认无超时(bash_task_timeout_s = 0),subagent 默认无超时([subagent] timeout_ms = 0),只有模型自己能停止任务。将 print_background_mode 设为 "drain" 可等待任务结束但不回馈结果,设为 "exit" 则在 main agent 结束后立即退出。
subagent
subagent 控制派生 subagent(AgentRun)的运行方式。角色选择使用 profile 的 can_spawn_subagents、allowed_subagents、preferred_subagents 和 deny_subagents;原宿主派发策略设置已移除。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
default_profile | string | 内建通用提示词 | AgentRun 省略 profile、route 和 profile_file 时采用的显式 profile 覆盖。该键不存在时(包括只配置了部分字段的 [subagent] 表),AgentRun 使用内建通用 subagent 提示词,不加载目录中的 profile。设为 "" 要求显式指定目标(严格模式) |
default_model | string | — | 仅在派发参数与生效 profile、route、caller lease pin 都未选模型时使用的显式兜底;从不继承调用方 |
deny_models | string[] | — | alias 解析后应用于所有子 Agent 绑定的硬禁止列表;pin、人工切换、恢复与 advisory 派遣都不能绕过。Profile / lease / 树策略 / model-profile 硬规则仍是额外边界 |
allowed_tools | string[] | [] | 允许越过原生 subagent 默认限制的精确工具名,适用于 subagent 默认拿不到的内置工具(AskUserQuestion、Cron、EnterPlanMode / ExitPlanMode、ThreadCreate / ThreadList / ThreadRead / ThreadWait);不会覆盖 profile 白名单、黑名单或其他策略限制 |
max_direct_children | integer | 16 | 每个派遣者同时在途的直属子 Agent 执行数上限,包括启动中和取消中;0 表示不限 |
max_total_subagents | integer | 0 | 单棵会话树同时在途的子 Agent 执行总数上限,包括孙代及更深后代,不含 main;0 表示不限 |
timeout_ms | integer | 7200000(2 小时) | 单个 subagent(AgentRun)允许运行的最长时间(毫秒)。超时后 subagent 以 timed_out 收尾。0 表示无超时——subagent 一直运行到自行结束或被模型手动停止。该值是后台任务管理器对每个 subagent 任务的 per-task timeout,因此对前台与后台 subagent 同时生效。在 print 模式(kiki -p)下未显式设置时默认为 0。注意:超过 2147483647(约 24.8 天)的值会被运行时钳到约 24.8 天 |
原生 subagent 默认可以使用普通工具,包括只读的 MemorySearch 和 MemoryRead。有一批内置工具默认关闭,需要显式开放:AskUserQuestion、Cron、EnterPlanMode 与 ExitPlanMode,以及 ThreadCreate、ThreadList、ThreadRead 和 ThreadWait。可以按档案在 subagent profile 的 tools 列表中点名,也可以设置服务端默认值:
[subagent]
allowed_tools = ["AskUserQuestion", "ThreadRead"]省略 tools 或只写 * 不算显式开放:只有具体工具名才算,通配符本身不会顺带开启任何 opt-in。这两处开放彼此是「或」的关系,但 profile 自己的名单仍会过滤结果:子智能体能用这类工具,只要服务端名单点名了它,或者该 subagent profile 的 tools 名单点名了它,同时该 profile 还得选中这个工具。因此写了有限 tools 名单的 profile 会挡住它没列出的工具,即使服务端开放了这一项;而没写名单(或写了 *)的 profile,则对两处开放覆盖到的工具都是开放的。allowed_tools = [] 会清除服务端额外允许,但不会移除 profile 的显式条目。profile 白名单、disallowedTools、禁用工具组、调用方限制、全局与会话策略、功能开关、Plan 模式和调用审批仍然生效;profile 自己的 disallowedTools 也能禁用这两处开放过的工具。MemoryWrite、ThreadSend、SendMessage 和 Goal 工具仍仅供 main agent 使用,不能通过这两个入口开放。Cron 安排的是当前会话的调度并唤醒 main agent,并不是子 Agent 私有的定时器。MCP 工具、继承的用户工具及其他扩展保持原有默认行为;外部执行器自行管理工具。
这些 opt-in 决定的是 subagent 能用什么;主对话不受它们的限制。主对话能选哪些工具,仍由同一档案自己的 tools 与 disallowedTools 名单决定。
profile 描述和设置页中的工具列表是配置预览,不保证运行时可用。功能开关、子 Agent 运行环境和审批仍可能阻止调用。
timeout_ms 可被环境变量 KIKI_SUBAGENT_TIMEOUT_MS 覆盖,优先级高于配置文件。allowed_tools、deny_models 和两个并发限额没有对应的环境变量。
限额是全局配置默认值,计数则按会话隔离。空闲子 Agent 和历史记录不计数;父 Agent 结束后仍运行的后代继续计数。恢复已有子 Agent 会占用执行名额,不会重复创建 Agent。派遣在异步启动前占位,启动失败或执行真正结束后释放。触及任一层上限会立即返回 dispatch.limit_exceeded,附带 layer、current、limit、owner(REST 业务码为 42904),不会排队或停止其他 Agent。可等待正在执行的任务结束,或显式调高对应配置限额。任务完成后的自动唤醒也遵守相同限额;唤醒被拒绝时,已完成任务及其输出仍可通过 TaskOutput 读取,通知不会被标记为已送达。
agents
这个严格配置节控制委派说明的布尔 gate。未知字段会被报告为配置错误。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | boolean | true | 为配置兼容而保留,目前不控制任何行为 |
notify_parent | boolean | true | 允许仅 subagent 可用的 AgentNotify 工具——向父 Agent 的邮箱排入一条 fire-and-forget 消息。设为 false 后所有 subagent 都不再获得该工具 |
[agents.delegation] 是嵌套表,两个槽位都只接受 boolean。false 会跳过对应说明,并始终优先于提示词字段覆写;省略槽位或设为 true 都表示启用说明。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
sub | boolean | true | 启用该 profile 作为被派发 subagent 运行时注入的说明 |
independent | boolean | true | 启用 MCP / SDK 这类没有父 Agent 的宿主调用说明 |
如需替换说明文案,在 PromptOverrides 中覆写 delegation.sub.notice 或 delegation.independent.notice。旧的字符串路径值已经移除,继续使用会触发严格解析错误;请把原文件正文迁入外部提示词覆写 TOML 的 [fields] 条目。
thread_communication
这个严格配置节是本地 peer thread 通信的允许开关。不写 enabled 时工具允许使用,但默认关闭,直到某个会话打开,或声明的 profile、这次任务点名它们。你写成 enabled = false 就是完全关闭,会话不能再打开。已经保存的 enabled = true 会保持原先的默认开启,直到 [optional_capabilities.defaults] thread 另作选择。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | boolean | 不写 | 允许 4 个主 Agent peer thread 工具以及本地 REST 与 Klient thread 操作。你写成 false 即完全关闭 |
单个工作区的覆盖值单独持久化,通过本地 REST API 或 Klient 管理。工具仍允许时,覆盖值可以关闭某个工作区;完全关闭后,覆盖值不能重新启用通信。
optional_capabilities
这一节把浏览器、电脑、记忆、线程和网页(WebSearch 与 FetchURL)的「允许使用」和「默认开启」分开。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
defaults.browser | boolean | true | 新会话是否一开始就有浏览器工具 |
defaults.computer | boolean | true | 新会话是否一开始就有电脑工具 |
defaults.memory | boolean | true | 新会话是否一开始就有记忆工具 |
defaults.thread | boolean | false | 新会话是否一开始就有 peer thread 工具 |
defaults.web | boolean | true | 新会话是否一开始就有网页工具 |
web.allowed | boolean | true | false 会完全关闭网页工具 |
浏览器、电脑、记忆和线程的允许位仍写在原有键上(native_browser、computer_control.enabled、memory.enabled、thread_communication.enabled)。会话可以打开或关闭一项仍允许的能力,但不能越过完全关闭。记忆的审批和预算、浏览器连接、电脑使用倾向是各自独立的设置。
mcp
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
startup_timeout_ms | integer | 30000(30 秒) | 所有 MCP server 的全局默认连接(启动 + 工具发现)超时(毫秒),取值范围为 1–2147483647。mcp.json 中单个 server 的 startupTimeoutMs 始终优先于本节与环境变量;都未设置时使用默认值 |
tool_timeout_ms | integer | 60000(60 秒) | 所有 MCP server 的全局默认单次工具调用超时(毫秒),取值范围为 1–2147483647。mcp.json 中单个 server 的 toolTimeoutMs 始终优先于本节与环境变量;都未设置时使用客户端内置默认值 |
startup_timeout_ms 和 tool_timeout_ms 可分别被环境变量 KIKI_MCP_STARTUP_TIMEOUT_MS 和 KIKI_MCP_TOOL_TIMEOUT_MS 覆盖,优先级高于配置文件。MCP server 的完整配置方式见 MCP。
identity
自定义 Agent 的身份标识。默认情况下,上游请求使用 kiki-cli 产品名,且不会声明自定义名称或 slug。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | string | — | Agent 在系统提示词中的自称(填充 ${product_name} 变量,你自己的 SYSTEM.md 和 agent 文件同样适用) |
slug | string | 由 name 派生 | 协议字段中使用的机器标识:发给第三方 provider 的 User-Agent 产品名,以及连接 MCP 服务器时声明的客户端名。省略时由 name 派生:转小写,连续的非字母数字字符折叠为 - |
advertise_as_kimi_code | boolean | false | 为兼容 Kimi Code,将发往上游的 User-Agent 产品名设为 kimi-code-cli,并在上游 HTTP 请求中覆盖 slug。默认情况下,Kiki 使用 kiki-cli 标识自己 |
[identity]
name = "Acme Dev Agent"
slug = "acme-dev" # 可选
advertise_as_kimi_code = falsename 和 slug 可以通过 KIKI_IDENTITY_NAME 和 KIKI_IDENTITY_SLUG 环境变量设置,优先级高于 config.toml,且不会被写回配置文件——适合不便写配置文件的容器和 CI 场景。
如果名称中不含任何 ASCII 字母或数字(例如纯中文名称),就无法派生出 slug,此时回退为 agent;需要特定协议标识请显式填写 slug。
身份在启动时解析一次,进程生命周期内保持不变——建立连接时它已宣告给 MCP 服务器和 provider,中途无法更换。修改本节配置在下次启动时对新会话生效;resume 的会话保留录制时的系统提示词,因为其历史轮次本就以原身份自称。同理,已完成的 MCP OAuth 授权保留其授予时的客户端注册;重置该服务器的认证即可在新身份下重新注册。
tools
tools 设置全局工具开关,对所有会话中的每个 Agent 生效,并在 Agent 自身的 tools / disallowedTools 策略之上再取一次交集。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | array<string> | — | 全局允许列表:非空时仅列出的工具可用;省略或设为空数组均表示不约束 |
disabled | array<string> | — | 全局禁止列表,在 enabled 之后应用 |
工具名匹配规则与 Agent 文件中的同名字段一致:内置工具按名称精确匹配(如 Read),MCP 工具用 glob 匹配(如 mcp__github__*)。有三种写法永远匹配不到任何工具,出现时会给出警告:mcp__ 模式之外使用通配符(enabled = ["*"] 会禁用所有工具,而 disabled = ["*"] 什么也禁不掉);缺少工具段的 mcp__ 字面量(mcp__github —— 匹配整个服务器要用 mcp__github__*);以及任何已注册或内置工具都没有的名字(匹配区分大小写)。
[tools]
disabled = ["EnterPlanMode", "ExitPlanMode", "mcp__github__*"]注意
与 Agent 文件中的 tools / disallowedTools 一样,本节不仅决定模型能"看到"哪些工具,还会在执行前再次强制检查。权限规则仍是独立的控制层,用于决定哪些操作需要审批。
image
image 控制图片发送给模型前的压缩行为,对所有图片入口生效(粘贴图片、ReadMediaFile 读图、MCP 工具结果里的图片等)。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
max_edge_px | integer | 2000 | 图片最长边上限(像素)。超过时按比例缩小到该值以内;调大可保留更多细节,代价是更大的请求体积 |
read_byte_budget | integer | 262144(256 KB) | 模型自行读取的图片(ReadMediaFile 默认读取)的单图字节预算。会话中模型反复截图、读图时,累计请求体大小由它控制;细节可通过 region 参数按原图坐标全保真回读(region 与 full_resolution 不受此预算限制) |
max_edge_px 可被环境变量 KIKI_IMAGE_MAX_EDGE_PX 覆盖,read_byte_budget 可被 KIKI_IMAGE_READ_BYTE_BUDGET 覆盖,优先级均高于配置文件。
哪些图片格式能送达模型,取决于该请求最终解析到的 provider。所有 provider 都接受 PNG、JPEG、GIF 和 WebP;Kimi provider 额外接受 BMP、HEIC 和 HEIF,因此 iPhone 照片无需先转换。其他图片会被替换为一行文本提示,说明当前 provider 接受的格式。
session_title
session_title 选择由谁来写会话标题。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
model | string | 未设置 | 用于写会话标题的模型别名。未设置(或留空)时 Kiki 完全不发标题请求:既不回退到 fast_model,也不使用托管的 chat_title 工具,因此标题生成不消耗任何订阅用量 |
triggers | array<string> | ["first_turn_completed"] | Kiki 主动写标题的时刻,取值为 first_user_message、first_turn_completed、context_compacted 中的一项或多项。空数组表示关闭自动生成;按需生成标题仍然可用,且仍需配置 model |
prompt | string | 内置提示词 | 可选的标题模型系统提示词。多行正文完整发送,不展开模板。删除该字段或留空恢复内置提示词;默认全文不会另存为覆盖 |
内置提示词根据当前目的和具体对象生成便于辨认的标题,保留有用的名字与标识符,不虚报尚未证实的成功。修改 prompt 会在下一次标题请求生效,已打开的会话也无需重启。保存或删除覆盖不改已有会话标题,也不主动发起标题请求。
选定的模型按原有的会话摘录预算直接使用。零输出的暂态失败遵循 retry;模型不存在或配置无效时只失败一次,已观察到模型输出后不重放。自动生成不会覆盖你手写的标题,重试等待期间手动改名也会保留,普通按需生成请求同样如此。只有强制请求(force)才会替换你手写的标题。
GET /api/config 与成功的 POST /api/config 响应包含 session_title.default_prompt 和 prompt_source(default 或 custom)。它们是只读字段;仅存在非空白覆盖时才返回 prompt。发送 { "session_title": { "prompt": "你的标题规则" } } 保存,发送 { "session_title": { "prompt": null } } 删除覆盖。省略的字段保持不变,因此这两种写入保留 model 与 triggers;model: null 只移除模型,保留提示词和生成时机。修改单个字段时不要使用 replace_domains。
按需生成对应 POST /api/sessions/{session_id}/title/generate,SDK 暴露了这个调用。它同样需要 model,没有模型就无从发问;其中 force 选项才是替换手写标题的那一个,不传则保留你写的标题。
自动生成标题默认开启。可在 GUI 中关闭,也可设置 [experimental] 下的 auto_session_title = false,或使用 KIKI_EXPERIMENTAL_AUTO_SESSION_TITLE=0。没有配置 model 时 Kiki 完全不发标题请求,既不会触发任何时刻,也不消耗订阅用量;你手写的标题、以及会话未命名时显示的首行都不受影响。
experimental
experimental 以 flag id 为 key,存放内置功能的发布与回退开关覆盖。内置功能默认可用;显式设为 false 仍会关闭。每个 flag 的优先级从高到低:对应的 KIKI_EXPERIMENTAL_<NAME> 环境变量、本节、真值的 KIKI_EXPERIMENTAL_FLAG 总开关,最后是 flag 的内置默认值。总开关为假值时视为未设置,不会全局关闭功能。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
auto_session_title | boolean | true | 是否自动生成会话标题;见 session_title |
native_browser | boolean | true | 经由受管浏览器后端运行已保存的浏览器连接;未开启时连接会被拒绝,Agent 也拿不到浏览器工具 |
local_session_resume | boolean | true | 接续本机已有的 Claude Code 和 Codex 会话;在「设置 → 会话」管理,每次新接续时读取 |
任何已注册的 flag 都可以按 id 用布尔值在这里覆盖。每个内置开关都在相关设置页提供名称与说明;设置 → 高级 → 开发与实验末尾的实验功能入口会链接到这些开关所在的页面,并显示更改何时生效。未知的扩展开关按 id 显示在该页。功能可用不代表会安装插件、授权脚本或连接未配置的外部目的端。
browser_control
browser_control 存放由浏览器控制管理的浏览器连接,以及新会话默认项。设置页是受支持的编辑入口:它按连接保存条目、保存后读回结果再显示,且保存从不启动浏览器。要新增 HTTP 桥连接,点击「添加浏览器」,将「接法」选为「Kimi WebBridge」。
| 字段 | 类型 | 说明 |
|---|---|---|
default_browser | string | 之后创建的会话使用的连接 id;未设置时调用必须自己指定连接 |
allowed_browsers | string[] | Agent 可以使用的连接 id。不写这一项时沿用原先的默认。空列表仍允许列出和发现 |
disabled_sources | string[] | 已关闭的来源:kimi-webbridge、independent-browser、codex-browser、ego-lite。关闭来源不会清空 allowed_browsers |
webbridge_preset_route | boolean | 默认 true:将旧版保存为 agent-browser-cdp、id 恰为 kimi-webbridge 的条目接到 Kimi HTTP 桥;设为 false 则让该条目继续走 CDP 驱动 |
connections | table | 每条连接一个条目,以连接的固定 id 为 key |
每个条目包含 name、enabled 与 type。类型为 agent-browser-profile、agent-browser-cdp、codex-extension、ego-lite、kimi-webbridge 或 webbridge-command;各类型字段见浏览器连接 API。字段与类型不符时会被拒绝,已保存的文件保持不变。存入的 CDP 地址按凭据对待:页面显示掩码,只有显式请求时才读取明文。webbridge-command 只接受 name 和 enabled,使用固定的本地命令桥,归 kimi-webbridge 来源开关控制。它没有 endpoint 或驱动路径;CDP 条目不会被改成此类型。
kimi-webbridge 类型使用服务器本机 http://127.0.0.1:10086 的 HTTP 桥接程序,不接受 endpoint;这不是 CDP 地址。上述旧 id 兼容路由不改写保存条目,也不影响其他 CDP id。显式 kimi-webbridge 类型始终使用 HTTP,不受 webbridge_preset_route = false 影响。
computer_control
computer_control 保存模型选择电脑工具时的软倾向。可在电脑控制中编辑,也可写入 config.toml:
[computer_control]
usage_preference = "avoid"enabled = false 会完全关闭电脑工具。不写这一项则允许使用。新会话是否一开始就带上这些工具,由 [optional_capabilities.defaults] computer 决定,默认开启。
usage_preference 可设为 "avoid"(默认)或 "prefer"。"avoid" 提示模型:除非用户或用户规则明确要求,否则一般不用电脑控制,优先已有 CLI、API、MCP、短脚本及浏览器专用能力。"prefer" 偏好用电脑控制处理适合的交互任务。两种倾向都以用户当前明确要求、正确性、工具可用性与权限规则为先。使用倾向不授予也不收回工具。改动在下次模型请求生效,无需重连,也不会安装组件;删除字段会恢复继承。
已识别的 cua-driver MCP 电脑工具默认向每个会话的 main agent 暴露,独立会话也有自己的 main agent。子 Agent 需要在 profile、route 或派发的工具选择、[subagent].allowed_tools 或 [tools].enabled 中显式指定 MCP 工具模式。安装所得连接可用 mcp__kiki-computer__* 开启;仅有 tools: ["*"] 不算明确开启。现有允许范围上限、deny 规则和已停用连接继续生效。输入结果未知的调用不会重放:先重连并观察,再决定下一步操作。
nb_search
nb_search 配置 Kiki 内置的搜索与抓取模块,也就是 WebSearch 和 FetchURL 工具背后的能力。该模块是 Kiki 的一部分:随产品一起安装,不需要额外的安装步骤;其中的 provider 实例、凭证槽、lane 和默认 fetch chain 都已经内置。
默认的 WebSearch lane 是 duckduckgo.search,无需注册、凭证或配置即可检索通用网页。公共 HTML 端点可能触发验证或限流;等待后再试,或显式选择其他已配置的来源。这些失败会报告错误,不会伪装为空结果,也不会静默切换到收费 provider。已配置的默认值和显式 lane 选择优先。仓库检索或代码库文档可显式选择 github.repositories、context7.docs;后者返回 typed 文档上下文,不能与结果型 lane 组合。字段名与合并行为遵循该模块的规范配置约定,与独立的 nb-search CLI 共用同一份 schema,因此已有的 nb-search 配置文件可以直接沿用。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
provider_instances | table | 否 | 命名 provider 实例,包含 provider_id、enabled、可选的 credential_slot_id / base_url、key_strategy(round-robin 或 priority)、balance_ttl_ms(60,000–86,400,000 毫秒)及 provider 专属 options |
credential_slots | table | 否 | 命名凭据槽,只包含 provider_id 和 env 中的环境变量名 |
lanes | table | 否 | 命名 operation lane,包含 provider_instance_id、operation_id、latency、cost 和可选 evidence_groups |
defaults.search_lane | string | 否 | 内置默认值为免密钥的 duckduckgo.search(通用网页);已配置的默认值优先。显式删除默认值且不指定 lane 时,WebSearch 仍会拒绝运行 |
defaults.fetch_chain | array<table> | 否 | URL 默认先用 direct.fetch,失败时尝试免密钥的 jina.reader;直连成功但内容无用时,需显式配置 execution.fetch.quality 规则才能触发回退 |
execution | table | 否 | provider 调用数、并发、重试、超时、内联输出、响应大小、重定向、内容长度和质量预算 |
凭据值不会写入 config.toml;规范凭据槽仍只有 provider_id 与环境变量名 env。Kiki 服务器进程环境变量优先,包括显式设置的空值。启用本机复用后,Kiki 会从服务器 NB_SEARCH_HOME(默认 ~/.nb-search)下的 nb-search secrets.json 补充缺少的变量,仅导入匹配的凭据槽并校验绑定;重定向会被拒绝。如果这两种来源都没有提供值,可选择使用该凭据槽的 Kiki 管理凭据。在「设置 → 搜索与抓取 → 服务与凭证」可保存、显式查看已存值、编辑、覆写或清除。凭据保存在当前 Kiki 服务器主目录下受保护的 secrets/nb-search/gui-credentials.json,而非 config.toml、nb-search CLI 文件或浏览器存储。修改凭据槽的提供商、变量名、使用该槽的实例或端点会使已存绑定失效,不会静默改绑;核对新绑定后显式覆写或清除旧值。只有 Kiki 管理的值可被查看;服务器环境变量及 CLI secrets.json 只显示来源,其值不会发送到 GUI。被引用的不同凭据槽必须使用不同的环境变量名,避免托管凭据跨提供商混用。如果另一处在凭据编辑器打开期间修改了槽的变量名、提供商、使用实例或端点,旧草稿保存时会提示冲突:请重新加载、核对目标后再保存。读写 REST 接口沿用现有 Kiki bearer token;持有它的人可显式查看 Kiki 管理的密钥。远程连接时凭据位于远程服务器;切换连接不会转移编辑器内的值。该模块不会读取其他终端的变量,也不会自动加载 .env 文件。
开启本机复用时,~/.nb-search/secrets.json 中 values.NB_SEARCH_TAVILY_API_KEY 原有的单个 Tavily 密钥可以直接沿用,无须迁移或补充第二个密钥。需要多个密钥时,把同一字段或 Kiki 服务器的 NB_SEARCH_TAVILY_API_KEY 环境变量设为有序、逗号分隔的 1–32 个不同且非空的密钥,例如 YOUR_FIRST_API_KEY,YOUR_SECOND_API_KEY;逗号两侧的空格会被忽略。不要把密钥写入 config.toml,且服务器环境变量仍优先于本机凭证文件。其他已配置凭证槽也使用相同格式。
同一 Kiki 服务器进程中的同步 WebSearch 和 FetchURL 调用(包括不同会话)共用密钥调度状态;配置或凭证变化时会重新建立调度器。round-robin 是默认策略,priority 则按顺序优先选用第一个可用密钥。401/403 会在当前 runtime 生命周期内隔离该密钥;429 按 Retry-After 或默认 60 秒冷却;5xx 或连接错误会对单个密钥最多重试两次,然后轮换。402 表示额度耗尽,默认缓存 10 分钟;正常调用不会逐次查询用量,手动 keyUsage() 查询只在 nb-search 本地 SDK 中提供,不属于 Kiki 的 REST 工具。脱离进程运行的异步作业各有独立 worker,不共享服务器的轮转与冷却状态。
默认按以下顺序合并设置:该模块的内置默认值、服务器本机的 nb-search 配置、服务器环境变量、Kiki 的 [nb_search] 覆盖项。本机文件由 NB_SEARCH_CONFIG 指定;未指定时,使用 NB_SEARCH_HOME(默认 ~/.nb-search)下的 config.json。默认文件不存在时仍可使用其他配置层;显式路径不存在或文件不可读时,该来源会显示不可用。
在「设置 → 搜索与抓取 → 概览与配置来源」中查看来源并控制复用,也可以设置独立的宿主选项:
[nb_search_source]
reuse_local_config = falsereuse_local_config 默认为 true。设为 false 后会跳过服务器本机的 nb-search 配置与凭证文件——内置模块改用 Kiki 自身的配置与内置默认值继续工作——既不修改被跳过的文件,也不删除 Kiki 已保存的配置或凭证环境变量。隔离模式的默认搜索存储位于 Kiki 缓存目录下,显式设置的 nb_search.home 和 nb_search.jobs_root 仍优先生效。修改无需重启,下次运行时请求即使用新配置。来源选择保存成功不代表搜索 Lane 已就绪,需要分别查看配置来源与工具的就绪状态。连接远程 Kiki 服务器时,这些文件和环境变量属于服务器,而非浏览器所在机器。
[nb_search.credential_slots."exa.default"]
provider_id = "exa"
env = "NB_SEARCH_EXA_API_KEY"
[nb_search.defaults]
search_lane = "exa.search"
[nb_search.execution]
max_provider_calls = 16
max_concurrency = 4
retry_count = 1
search_timeout_ms = 30000
fetch_timeout_ms = 60000
max_inline_bytes = 65536
[nb_search.execution.fetch]
max_source_bytes = 2097152
max_response_bytes = 2097152
max_content_chars = 200000
max_redirects = 5如果希望默认用 Tavily 搜索,并优先使用第一个可用密钥,在 Kiki 的 config.toml 中加入以下设置。不设置 key_strategy 时默认轮流选择密钥;balance_ttl_ms 控制用量与额度耗尽状态的缓存时间,不会启动后台轮询。
[nb_search.defaults]
search_lane = "tavily.search"
[nb_search.provider_instances."tavily.default"]
key_strategy = "priority"
balance_ttl_ms = 600000permission
permission 设置会话启动时自动加载的权限规则,控制 Agent 调用工具时是否需要用户确认。规则用 [[permission.rules]] 数组表写出。求值顺序固定为 deny、ask、allow,与文件中的顺序无关。命中的 deny 总是优先于命中的 ask 或 allow;规则顺序不会改变这个优先级。
Bash 参数模式使用命令匹配,不使用文件路径 glob。模式会锚定到整条命令:只有 *(匹配任意长度的字符,包括 /、点文件名、空格和换行)和 ?(匹配一个字符)是通配符,其他字符全部按字面匹配。使用 \\ 转义 *、? 或 \\;例如 Bash(arena \\*) 匹配字面量参数 *。[]、{}、()、!、| 等 Shell glob 语法在 Bash 模式中没有特殊含义。
Kiki 会把复合 Bash 命令按 ;、&&、||、| 和换行拆成多个段。命令替换($(...) 和反引号)及子 Shell 也会作为独立段检查。任意段命中 deny 都会拒绝调用。在 auto 和 yolo 之外,所有段都必须命中 allow,否则结果为 ask。解析不可靠时,任何 allow 都不能批准调用,但 deny 仍会按原始命令判断。在 kiki -p 等非交互运行中,ask 会转换为拒绝,不会等待审批界面。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
decision | string | 是 | 匹配后的处置:allow(直接放行)、deny(直接拒绝)、ask(每次询问) |
scope | string | 否 | 规则有效范围:turn-override、session-runtime、project、user;默认 user |
pattern | string | 是 | 匹配模式,格式为 工具名 或 工具名(参数模式),如 Read、Bash(rm -rf*) |
reason | string | 否 | 规则说明,仅用于调试和审计 |
内置工具名见内置工具。大多数支持规则参数的内置工具会定义自己的匹配对象,例如 Bash(command-pattern) 或 Read(path-pattern)。MCP 工具和自定义工具只能按工具名匹配,不支持参数模式。
[[permission.rules]]
decision = "allow"
pattern = "Read"
[[permission.rules]]
decision = "allow"
pattern = "Grep"
[[permission.rules]]
decision = "deny"
pattern = "Bash(rm -rf*)"
[[permission.rules]]
decision = "ask"
pattern = "Bash"如果要让非交互 Agent 只能运行 arena 命令,请使用受限权限模式并配置一条 allow 规则。在该模式下,只有每个解析后的命令段都命中时才会批准;未命中的调用会变成 ask,而 -p 会把它转换为拒绝。不要在这条 allow 规则旁再加宽泛的 deny Bash(*):deny 优先级更高,会连允许的命令一起拒绝。
kiki -p '运行状态检查' --agent arena --permission-mode default[[permission.rules]]
decision = "allow"
pattern = "Bash(arena *)"kiki permission test 'Bash(arena status; ls)' 可以在不执行命令的情况下进行同样的 dry-run。它会输出生效的权限模式、解析出的每个命令段、命中的规则、scope 和来源文件。
deny 应用于具体的危险模式;即使在 auto 和 yolo 中,命中的拒绝也不会被绕过:
[[permission.rules]]
decision = "deny"
pattern = "Bash(* ../state/*)"
reason = "禁止读取 state 目录"反例:在 allow Bash(arena *) 旁再加 deny Bash(*) 并不能提供兜底。由于 deny 先求值,它会拒绝所有 Bash 调用,包括本来允许的 arena 命令。
危险 Bash 命令
permission.dangerous_bash 是三态开关,控制 tree-sitter Bash 分析器。它识别 rm -rf、shutdown、向块设备 dd,以及 sudo / bash -c 等包装后的危险命令。开启后,原本会被自动放行的危险命令升级为 ask,走既有审批路径;既有 deny 路径不变。无法分析的命令不会升级。
| 取值 | 效果 |
|---|---|
default(未设置) | manual / auto / review 开启,yolo 关闭 |
on | 始终把危险 Bash 升级为 ask,包括 yolo |
off | 不介入 |
yolo 默认关闭,是为了不改写 Never Ask / yolo 的明确承诺。只有你确实要在该模式下也拦危险命令时,才设为 on。
[permission]
dangerous_bash = "default"审查者审批
review(「替我审批」)沿用 Auto 模式对普通操作的自动批准,但先把策略产生的审批请求交给审查者。显式配置的 deny 规则始终拦截;匹配「本会话允许」的调用先于显式 ask 规则和受保护路径检查而放行,其余命中显式 ask 的调用仍会询问你。审查者高置信批准会继续执行,高置信拒绝会阻止工具;结果不确定、格式错误、超时、凭证缺失或服务不可用时,改为询问你。同一轮连续三次被审查者拒绝后,这轮余下的请求直接询问你。审查者的批准不会写入「本会话始终批准」规则。
两种审查后端都会收到最多三条最近的真实 User 文本消息、完整的 Bash 命令或解析后的文件路径及操作、策略名称和原因,以及工作目录。对于交由审查者的 Write 和 Edit 调用,还会收到提交内容的字节数及 SHA-256 摘要(编辑时包括修改前后两段),但不会收到文件正文或 Diff 原文。向敏感文件写入或编辑时,由于审查者无法核实未发送的内容,会直接询问你。文本字段中的 PEM 私钥及常见 API 密钥格式会先脱敏。输入过长时裁剪 User 消息文本,不截断操作、策略和工作目录;Assistant 消息与工具输出不会发送。命令或目标列表超过各自上限、固定的操作或策略内容超出总长度上限、操作没有明确命令或解析后目标,或必须看到隐去的内容才能判断安全性时,改为询问你。使用模型后端时,model 必须是已配置的模型别名:
# ~/.kiki/config.toml
default_permission_mode = "review"
[permission.reviewer]
backend = "model"
model = "k3-review"
allow_threshold = 0.9
deny_threshold = 0.9
timeout_ms = 8000
categories = ["policy_compliance", "no_secret_egress", "no_irreversible_damage", "no_outward_effect", "prompt_injection_absent"]backend 可选 model 或 jev,模型后端必须配置 model。allow_threshold 和 deny_threshold 的范围都是 0.5–1;置信度低于对应阈值时会询问你。categories 从上面五个名称中选择 Jev 的是非检查项。默认超时:模型 8 秒、Jev 4 秒;timeout_ms 可覆盖为 100–30,000 毫秒。使用 TypeSafe Jev 时,把它选为审查后端,并单独保存密钥。选择 backend = "jev" 即表示同意把上述有限审查内容发送给 TypeSafe,不再有单独的同意开关(旧的 jev_consent 键会被忽略):
# ~/.kiki/config.toml
[permission.reviewer]
backend = "jev"
model = "jev-latest"# ~/.kiki/credentials/credentials.toml
[permission.reviewer]
api_key = "YOUR_TYPESAFE_API_KEY"配置写入器把 api_key 保存在 credentials.toml 而不是 config.toml。未保存密钥时,可从服务器进程的 TYPESAFE_API_KEY 环境变量读取。没有可用密钥时不会调用 Jev,而是询问你。在「设置 → 权限 → 审查者」中,已保存的密钥默认遮盖,但不是只写:可以主动显示、复制、编辑或清除;来自环境变量的密钥会标明来源,也可以在 Kiki 中另存一个值覆盖它。持有 Kiki bearer 令牌的人都能显示已保存的密钥。
TIP
MCP server 的声明配置写在 ~/.kiki/mcp.json 或项目内 .kiki/mcp.json 中,不在 config.toml 里。旧的 .kimi-code/mcp.json 路径不会读取。交互式配置入口是内置的 kiki-ops Skill(负责 Kiki 产品使用与配置的内置 Skill):输入 /kiki-ops 帮我配置 MCP,详见 Model Context Protocol。
interaction
interaction.ask_user_question 决定 AskUserQuestion 是否阻塞 Agent 当前轮。默认 background 允许 Agent 在后台提问后继续工作;设为 blocking 时,即使工具调用传了 background = true,也要等你回答。在阻塞模式中,工具说明和输入参数不会展示后台选项。没有已连接的交互客户端时,问题会被关闭,而不会无限等待。
[interaction]
ask_user_question = "blocking" # 或默认值 "background"prompt
prompt 无需复制 Agent profile,即可覆盖具有稳定语义的文案字段。字段值直接替换对应文案单元,不做追加、前置或包裹。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
variables | record<string, string> | {} | 覆写字段中以 ${name} 引用的命名变量。名称必须匹配 [A-Za-z_][A-Za-z0-9_]*;内置运行时名称属于保留名,不能在此重定义 |
overrides | table | {} | 全局 PromptOverrides,可包含 files 与 fields |
常用内置字段 ID 包括 system.language、system.reply_style、system.coding、system.shared、tool.web-search.description、tool.web-search.guidance、delegation.sub.notice 和 delegation.independent.notice。System 字段替换内置提示词的对应段落;system.shared 是唯一的共享外层补充,非空时只追加一次。工具 description 替换静态说明,但保留运行时生成的动态细节;非空 guidance 会在既有的 User-configured guidance: 标签下追加。
${name} 只做单遍字面替换,不递归,也不执行脚本。字段可以使用自身声明的内置变量及 [prompt.variables] 中的名称;未知名称会被拒绝。${base_prompt}、${parent_prompt} 等整篇组合变量不能用于字段。
[prompt.variables]
search_guidance = "除非问题明确要求历史信息,否则优先用最近的结果。"
[prompt.overrides]
files = ["prompt/team.toml"]
[prompt.overrides.fields]
"system.shared" = "引用网络来源时,请给出实际打开页面的 URL。"
"tool.web-search.guidance" = "结果跨多年时遵循 ${search_guidance}。"提示词覆写格式
每个覆写表面都使用相同对象:
files?: string[]
fields?: record<string, string>files 中的路径相对于 Kiki 主目录(默认为 ~/.kiki)。绝对路径、.. 穿越、经符号链接逃逸、缺失文件、非法 TOML、重复 key 与未知字段 ID 都会让校验失败。每个外部文件都是严格 TOML,只能包含 schema_version = 1 和一个 [fields] 表,不能继续引用其他文件:
schema_version = 1
[fields]
"system.language" = "除非用户指定其他语言,否则使用用户的语言回复。"
"tool.web-search.description" = "通过 Kiki 已配置的搜索运行时检索公开网页来源。"同一表面内按列表顺序应用文件,内联 fields 最后应用。不同表面从低到高依次为全局 [prompt.overrides]、模型 [models."<alias>".prompt_overrides]、Agent 或 SYSTEM.md Frontmatter 的 prompt_overrides,以及匹配的 model_profiles[].prompt_overrides。缺失 key 继承下层值;空字符串仅能明确清空允许为空的字段。
[models.fast-model.prompt_overrides]
files = ["prompt/fast-model.toml"]
[models.fast-model.prompt_overrides.fields]
"system.reply_style" = "回答保持紧凑,并以行动为导向。${reply_style_guide}"Agent 与 SYSTEM.md Frontmatter 使用等价的 YAML mapping:
prompt_overrides:
files:
- prompt/reviewer.toml
fields:
system.coding: 优先做最小且经过验证的修改。每个 turn 的首个模型请求准备时,会冻结当前 profile、模型、字段注册表、配置和已加载覆写文件。合法的被监听文件更新从下一 turn 生效,绝不会在当前 turn 中途变化。刷新失败时,Kiki 会报告 prompt-fields-refresh-failed 并保留上一份有效快照,不会部分应用损坏的更新。
整篇替换的 SYSTEM.md 或 Agent 正文,以及模型 cognition 的 replace 会遮蔽对应的 system.* 字段。Cognition anchor 会逐字发送,因此 anchor 生效时 system 与 delegation 字段处于 inactive 状态;工具字段仍然有效。这些状态只用于诊断,不会插入提示词。
移除
旧的 [prompt] shared 和 [prompt.tools] 键已经移除,继续使用会触发严格配置解析错误。把 shared 迁到 [prompt.overrides.fields] 下的 "system.shared" 键;每个工具条目迁到 tool.<kebab-case-name>.guidance(例如 WebSearch 对应 tool.web-search.guidance)。
桌面 GUI 中,请进入「设置 → 智能体 → 提示词字段」编辑本节;该卡片默认折叠,展开后再编辑。
[request_governance]
request_governance 可限制原生模型请求(resource = "model_request")或正在执行的 Agent(resource = "agent_execution")。没有规则时不限制并发;现有未写 resource 的规则仍按模型请求计数。GUI 的「用量 → 实时」显示运行与排队请求,同页「并发限制」可新增、编辑、暂停或删除规则。默认打开的「历史」标签显示 Token 用量与估算费用。诊断流程见用量。
global 规则让同一个 Kiki 服务进程内的会话共享容量;each_session 按会话分别计数。这些限制不跨独立 Kiki 进程,也不设置每分钟请求数、Token 或金额预算。搜索与抓取调用用 nb_search.execution 限制。
模型请求规则计数供应商生成尝试,包括压缩与 OAuth 重放。外部 harness 的模型请求仍未纳管,不是零请求。Agent 执行规则覆盖通过 Kiki 启动的原生和外部执行器,包括 main、subagent 与外部委派的 independent Agent。每个 Agent 在执行期间只占一个名额,工具阶段、等待审批、取消清理和收尾均占用;idle Agent、后台 Shell 任务和子 Agent 的任务回执不额外计数。外部 harness 未提供模型绑定时,模型身份保持未知,不用 Kiki 的原生默认模型填充。
例如,让某个供应商下的所有模型跨会话合计最多同时发出两条请求。把 example-provider 换成 [providers] 中的精确表键:
[request_governance]
schema_version = 1
max_wait_ms = 300000
max_queue_size = 1024
[[request_governance.rules]]
id = "shared-provider"
resource = "model_request"
scope = "global"
providers = ["example-provider"]
max_concurrent = 2
overflow = "queue"
enabled = true若希望使用某个模型的子 Agent 在每个会话内最多同时发出一条请求,可改用下面的规则,也可与供应商规则并用。把 example-model 换成规范的 [models] 表键,不要填显示名、上游 model 值或 aliases 中的其他名称:
[[request_governance.rules]]
id = "session-model-children"
scope = "each_session"
models = ["example-model"]
subagents_only = true
max_concurrent = 1
max_wait_ms = 60000
overflow = "queue"若要限制某个执行器跨会话最多同时运行两个子 Agent,填写该执行器的注册 ID:
[[request_governance.rules]]
id = "executor-children"
resource = "agent_execution"
executors = ["example-executor"]
roles = ["subagent"]
max_concurrent = 2
overflow = "queue"| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
schema_version | integer | 1 | 配置版本,只接受 1 |
max_wait_ms | integer | 300000 | 本地等待预算,单位毫秒,须为正数;模型请求跨重试累计,Agent 按每次启动计 |
max_queue_size | integer | 1024 | 两种资源合计的等待准入数上限,须为正数 |
rules | array<table> | [] | 并发规则,用 [[request_governance.rules]] 编写 |
规则 id | string | 必填 | 非空且唯一的规则标识 |
规则 resource | string | model_request | model_request 计请求,agent_execution 计 Agent |
规则 scope | string | global | 全服务共享容量,或 each_session 按会话分别计数 |
规则 models | array<string> | 全部 | 原生规范模型 ID 或外部已绑定模型字符串;所选 ID 共享一份上限 |
规则 providers | array<string> | 全部 | 精确的原生供应商配置 ID;外部供应商身份未知 |
规则 executors | array<string> | 全部 | Agent 规则:注册的执行器 ID,native 表示 Kiki |
规则 profiles | array<string> | 全部 | Agent 规则:绑定的 profile 名称 |
规则 roles | array<string> | 全部 | Agent 规则:main、subagent、independent;同时限制主与子 Agent 时显式选择前两者 |
规则 subagents_only | boolean | false | 只匹配子 Agent 请求或执行;Agent 规则不包含 independent |
规则 max_concurrent | integer | 不限 | 正整数上限;省略表示不限,零是无效值 |
规则 overflow | string | queue | queue 等待容量;reject 在本规则容量已满时立即拒绝 |
规则 max_wait_ms | integer | 本节上限 | 可选正整数预算;本节与所有匹配且启用的规则取最短等待时间 |
规则 enabled | boolean | true | false 暂停规则,保留内容,但不应用上限或等待预算 |
所有匹配且启用的规则共同生效。同一规则的不同筛选字段取 AND,同字段的 ID 列表取 OR。省略筛选字段表示匹配全部;空列表无效。未知身份不匹配具名筛选。若要给各模型或执行器独立的上限,每个身份写一条规则。未知字段与重复规则 ID 会被拒绝。
在 GUI 保存规则或修改文件后,等待准入会重新判断。调高上限或暂停规则可以释放等待项;调低上限不会终止在飞工作,因此运行数可能暂时高于新上限。模型请求槽在流清理后、工具执行或重试退避前释放;Agent 槽在整个执行期间持有。等待准入不占槽;Stop 取消等待中的执行,不启动供应商或 harness 工作。
排队错误与供应商 429
用错误码区分本地等待与供应商限流:
| 错误 | 含义与处理 |
|---|---|
request.limit_rejected | 匹配的规则已满,且使用 overflow = "reject"。等待在途请求结束,或修改该规则 |
request.queue_full | 全服务队列达到 max_queue_size。等待队列减少后再试 |
request.queue_timeout | 请求或 Agent 启动耗尽本地等待预算。容量空出后重试,或调整并发上限、等待预算 |
request.agent_ancestor_limit | 父 Agent 正占用匹配规则的名额。选择仅限制子 Agent、将 main/subagent 分开配置,或提高报出的规则上限;等待父 Agent 释放可能形成死锁 |
provider.rate_limit / HTTP 429 | 已发出的请求被供应商限流。核对其消息与账户限额;并发上限可减少同时请求,但不能保证每分钟请求数或 Token 速率 |
本地 request.* 错误不会自动重试。供应商瞬时 429 遵循 retry,包括 Retry-After;额度耗尽或余额不足则直接失败,不重试。修改上限前,在「用量 → 实时」展开「请求详情」,核对排队模型、阻塞规则 ID 与等待时间。过期的计数是最后收到的快照,不代表当前容量。
tui.toml
除了 config.toml,CLI 还在同一目录下用一份配套的 tui.toml 保存终端界面与客户端偏好(~/.kiki/tui.toml,或覆盖后的 $KIKI_HOME/tui.toml)。它在首次运行时以默认值创建,交互式命令 /config、/theme、/editor 会自动写入,通常无需手动编辑。文件格式有误时,CLI 会回退到默认值并给出提示,而不是启动失败。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
theme | string | auto | 配色主题:auto(跟随终端)、dark、light,或自定义主题的名字 |
render_latex | boolean | true | 将 Markdown 消息中的 LaTeX 公式($…$、$$…$$)渲染为 Unicode 文本;false 则保留原始源码 |
disable_paste_burst | boolean | false | 禁用非 bracketed paste 的粘贴突发兜底;默认开启,避免快速多行粘贴被逐行提交 |
cache_expiry_hint | boolean | true | resume 长时间未活动的会话、或长时间空闲后发送消息时,若上下文缓存可能已过期则弹出提醒,可选择先压缩或新建会话 |
[editor].command | string | "" | 编写长输入用的外部编辑器命令;留空则回退到 $VISUAL / $EDITOR |
[notifications].enabled | boolean | true | 是否发送桌面通知 |
[notifications].notification_condition | string | unfocused | 何时通知:unfocused(仅终端失去焦点时)或 always(总是) |
[status_line].items | string[] | [] | 底部状态栏第一行展示哪些内置槽位及其顺序:mode、goal、model、tasks、cwd、git、tips。缺省保持默认布局;未知 id 跳过并告警 |
[status_line].command | string | "" | 自定义状态栏命令。其 stdout 第一行替换状态栏第一行,stdin 会收到 JSON 快照(model、cwd、git 分支、permission 模式、plan 模式、上下文用量、session id、版本)。运行上限 300ms、每秒最多一次;失败时回退内置布局 |
# ~/.kiki/tui.toml
theme = "auto" # "auto" | "dark" | "light" | 自定义主题名
render_latex = true # false 表示消息中的 LaTeX 公式保留原始源码
disable_paste_burst = false # true 表示禁用非 bracketed paste 的粘贴突发兜底
cache_expiry_hint = true # false 表示关闭 resume / 空闲提交时的"缓存已过期"提醒弹窗
[editor]
command = "" # 留空则使用 $VISUAL / $EDITOR
[notifications]
enabled = true
notification_condition = "unfocused" # "unfocused" | "always"
# [status_line]
# items = ["mode", "goal", "model", "tasks", "cwd", "git", "tips"]
# command = "~/.kiki/statusline.sh"修改在下次启动时生效,或用 /reload-tui 立即生效(只重载 tui.toml);/reload 会同时重载 config.toml 和 tui.toml。
项目级本地配置
除了 ~/.kiki 下的用户级文件,Kiki 还会读取位于 <项目根目录>/.kiki/local.toml 的项目级本地配置文件。它保存的是与某一个项目检出相关、通常不应与队友共享的设置。旧的 .kimi-code/local.toml 路径不会读取。
该文件会在你通过 /add-dir 添加额外工作目录并选择记入项目时自动创建,通常无需手动编辑。这里记录的目录只在工作区受信任时才会加载:不受信任的检出不读启动时的 additional_dir,写入新目录也要求先信任工作区。
[workspace]
[workspace] 表用于存放项目级的工作区设置:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
additional_dir | array<string> | 否 | 额外工作目录列表,以绝对路径存储。在 /add-dir 中确认"记住此目录"时自动写入;启动时读回,使这些目录在该项目的每个会话中都可用。只对受信任的工作区加载 |
[workspace]
additional_dir = ["/absolute/path/to/shared"]目录以绝对路径存储,与具体机器相关。因此建议把 .kiki/local.toml 加入项目的 .gitignore,避免被提交。