【免费下载链接】maki
An efficient AI coding agent extendable by neovim-like Lua plugins
Maki(maki)是一个高效、可用类 Neovim Lua 插件扩展的 AI 编程代理(AI coding agent)。它的 compaction(上下文压缩)机制,负责在会话变长时自动摘要历史、守住上下文窗口,是它最核心的 Token 经济学设计之一。本文带你彻底看懂这套机制的触发条件、摘要流程与可配置项。
为什么 AI 编程代理需要上下文压缩?
长会话是 AI 编程代理的常态:
- 每一轮对话、每一次工具调用(读文件、跑命令)都会把结果原样追加进上下文;
- 模型有固定的上下文窗口(context window),塞满后请求直接失败;
- 工具输出动辄几十 KB 的构建日志、grep 结果,是最快的"膨胀源"。
Maki 的答案不是"截断历史",而是compaction:把旧对话摘要成一段简短总结,让会话带着"记忆"继续。它由三种方式触发:
| 触发方式 | 说明 | 代码位置 |
|---|---|---|
| 自动压缩 | 每轮开始前检查:上下文 token 数 ≥ 窗口 − 预留缓冲,就自动摘要 | try_auto_compact |
| 溢出抢救 | 服务端真的拒绝提示(prompt too long)时,压缩是唯一出路,立即执行并重试 | recover_from_overflow |
| 手动命令 | 输入/compact,可附引导语,如/compact keep the repro steps | BUILTIN_COMMANDS |
自动压缩还可通过环境变量关闭:MAKI_DISABLE_AUTOCOMPACT=1(定义于 auto_compact_enabled),此时只有手动/compact生效。
触发阈值如何计算:20% 缓冲与 50% 上限
压缩的时机由"预留缓冲"(reserved buffer)决定,核心逻辑在 reserved:
可用空间 usable = 上下文窗口 − 预留 reserved 当 上下文 token ≥ usable 时,判定溢出,触发压缩预留值的三层规则(见 is_overflow 与测试用例 overflow_detection):
compaction_buffer:可配置,默认20%,支持"30%"这样的百分比或50000这样的固定 token 数;- 下限:不低于模型单次输出所需的最低预算(
min_output),保证窗口里永远塞得下"提示 + 一次回答"; - 上限:预留最多占窗口的50%(
MAX_RESERVED_PERCENT),否则小窗口模型(如n_ctx 4096的 llama.cpp 服务器)会在每轮都"压缩自己",陷入死循环。
配置项写在 agent 段,字段定义见 maki-config:
| 配置项 | 默认值 | 作用 |
|---|---|---|
compaction_buffer | 20% | 为压缩预留的上下文比例或 token 数 |
compaction_instructions | 无 | 附加到每次摘要提示词的额外指令 |
post_compaction_instructions | 无 | 压缩完成后追加给代理的指令(如"重读 plan.md") |
压缩的五个阶段:从准备到无缝续写
真正的压缩逻辑集中在 compact_history。整个过程像一次"外科手术":
第 1 步:准备摘要输入(瘦身)
- 剔除孤儿工具结果(没有对应工具调用的孤立 result,会直接导致请求报错);
- 图片统一替换为占位文本
IMAGE_PLACEHOLDER(图片最烧 token); - 剥离 thinking 块;
- 折叠旧工具结果:最近的工具输出在 64 KB 预算(RECENT_TOOL_RESULT_BUDGET)内原样保留,超预算的部分折叠为占位符
[tool result]——预算从最新的往回扣,避免"三个巨大结果挤掉三十个小结果"的旧毛病。
第 2 步:让模型写摘要
摘要请求使用专门的系统提示词 compaction.md("只输出总结,不要回答对话中的问题"),用户侧提示词 compaction_user.md 则规定了固定模板:
## Goal / ## Instructions / ## Discoveries / ## Accomplished ## Relevant files / directories / ## Todo list摘要输出预算被限制在 16384 tokens(SUMMARY_OUTPUT_BUDGET)——给足整个轮次预算反而会在"上下文压力最大的那一次请求"上白白预留数万 token。
第 3 步:溢出重试策略
如果摘要请求本身也超窗(会话极端长),最多重试 3 次,每次从前面削:先折叠工具结果为[tool result];没有可折叠的就整轮删掉最老的一轮(truncate_oldest_round),保证重试一定有进展。
第 4 步:替换历史,保留"未回答尾巴"
摘要成功后,历史被替换为:
[用户消息] What did we do so far? [助手消息] <摘要内容> [原样保留] 尚未得到回答的最新输入(carry)这个"carry"设计很关键:还没被回答的用户输入绝不进入摘要,原文保留并重新追加,避免"你说的需求在我还没回答时就丢了"(见 compact_history_carries_the_tail_past_the_summary 测试)。
第 5 步:续写提示 + 仪表盘复位
- 若没有未回答输入,追加一条合成消息(CONTINUE_AFTER_COMPACT),提醒代理:"若有下一步就继续;若摘要里有 todo list,用 todo_write 恢复并持续更新;学到的重要项目上下文,考虑存进 memory";
- 上下文仪表盘(ContextGauge)立即按新历史重置,避免用已被删掉的旧转录去衡量新会话;
- 发送
CompactionDone事件,UI 展示压缩前后的上下文大小变化。
整个流程还带"失败安全":摘要为空则不替换历史、直接报错;压缩中途取消则转录和仪表盘原封不动。
手动 /compact:一次带引导语的压缩
/compact命令(注册处)支持参数,例如:
/compact 保留失败的测试名引导语与配置指令合并而非互相覆盖:compaction_instructions(作用于每次压缩)+ 命令参数(只作用于这一次)+ 插件层追加的指令,三者按序拼接(summary_prompt)。压缩完成后还会按post_compaction_instructions追加后续指令,适合"压缩后重读 plan.md"这类场景。
用 Lua 插件定制压缩行为
Maki 的卖点之一是可扩展性:压缩的每一步都开放了 Lua 钩子,插件可以"只动选择权,不动执行权"——宿主仍负责实际改写历史,插件不会弄坏对话结构。
| 钩子 | 时机 | 可做的事 |
|---|---|---|
agent.compact.before | 压缩开始前 | 返回skip(仅自动压缩可跳过)、追加instructions、提供continue文案 |
agent.compact.prepare | 转录送进摘要器之前 | 审阅每个工具结果(工具名、输入、字节数、截断文本),修改collapse列表决定折叠哪些结果 |
钩子定义见 steer_compaction 与 prepare_collapse,插件机制总览见 AGENTS.md。
另外,摘要可以交给更便宜的模型:Maki 的模型档位(model tier)中有专门的compaction档,摘要调用按该模型的单价计费并计入账本,不拖累主模型成本(见 ModelTier)。
实战配置建议与快速清单
- 窗口较大的模型(128K+):保持默认
compaction_buffer = "20%"即可; - 小窗口 / 本地模型(llama.cpp、Ollama):可调小缓冲(如
"10%")推迟压缩,但下限规则会自动抬高到"输得出一次回答"的安全值; - 重视长任务连续性:设置
post_compaction_instructions = "重读 plan.md 和 AGENTS.md",让摘要后的代理立刻找回项目状态; - 想控制摘要内容:用
compaction_instructions固定要求(如"必须记录所有改过的文件名"),临时需求则用/compact <引导语>。
核心要点回顾:
- 触发:达到
窗口 − compaction_buffer自动压缩,服务端拒绝时兜底抢救,/compact手动触发; - 摘要输入先瘦身:去图片、去 thinking、折叠超大工具结果(64KB 尾部预算);
- 摘要按固定模板输出,最多重试 3 次并逐次裁剪;
- 未回答的最新输入原文保留,绝不进摘要;
- 压缩后仪表盘复位、自动注入"继续"提示,会话无缝续写。
想了解更多上下文管理细节,可查阅项目文档:context 文档、hooks 文档 与 configuration 文档。
【免费下载链接】maki
An efficient AI coding agent extendable by neovim-like Lua plugins
相关推荐
thClaws如何压缩超长对话?Compaction上下文管理机制全解析
thClaws如何压缩超长对话?Compaction上下文管理机制全解析 thClaws 是一款用 Rust 编写的开源 AI agent 框架,支持 GUI、
OpenClaw 如何理解并调整会话压缩 Compaction,让长对话不超上下文?
OpenClaw 如何理解并调整会话压缩 Compaction,让长对话不超上下文? 每个模型都有上下文窗口(context window),即一次能处理的最大
AI 应用AI Agent交互助手后端即时通讯网关Lucky 完整教程:5分钟给家里NAS开通外网访问,端口转发、DDNS、远程唤醒全搞定
Lucky 完整教程:5分钟给家里NAS开通外网访问,端口转发、DDNS、远程唤醒全搞定 想象一下:晚上十一点在公司,你想搬回存在家里 NAS 上的电影,却怎么
后端网络通信
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考