状态:Draft
范围:v0.1 项目规格
MiniCode-go 是一个使用 Go 从零实现的、以 CLI 为主要交互入口的轻量级 Coding Agent,可以理解为一个面向原理学习的“迷你版 Pi”。
用户通过命令行向 Agent 描述编码任务,Agent 通过大语言模型理解任务,并在用户授权的前提下使用本地工具浏览代码、修改文件、运行测试,最后返回任务执行结果。
项目希望实现的核心闭环是:
理解任务
↓
检查代码
↓
制定下一步动作
↓
调用工具
↓
读取工具结果
↓
修改或继续分析
↓
运行验证
↓
总结结果
MiniCode-go 的主要目的不是打造一个功能最全的商业 Coding Agent,而是通过一个规模可控的项目学习以下内容:
- 模型如何调用工具;
- Agent Loop 如何工作;
- 模型、Agent 和工具之间如何分工;
- 如何让模型观察代码并采取行动;
- 如何将工具错误反馈给模型并继续恢复;
- 如何控制文件修改和命令执行权限;
- 如何验证 Agent 是否真的完成了任务。
项目会尽量减少外部框架、复杂抽象和非必要功能,但不会只实现一个“调用模型然后打印答案”的聊天程序。
首版至少应包含:
- 模型适配器;
- Agent Loop;
- 工具注册和分发;
- 文件浏览和搜索;
- 文件修改;
- 命令执行;
- 人工审批;
- 错误处理;
- 停止条件;
- 基础测试和运行日志。
CLI 是项目首版唯一需要重点支持的交互方式。
CLI 既支持一次性任务,也支持同一会话内的多轮交互,例如:
> 先分析一下这个项目的结构
> 重点看看 parser 相关代码
> 按照刚才的分析修复问题
> 运行测试验证一下
首版不考虑 Web UI、IDE 插件或后台常驻服务。
Agent 主要服务于本地代码仓库:
- 一次处理一个工作区;
- 文件操作限制在工作区范围内;
- 命令默认在工作区中执行;
- 不自动访问其他项目或远程环境。
实现一个可以完成以下任务链的最小可用 Agent:
用户提出任务
→ Agent 阅读相关代码
→ Agent 找到需要修改的位置
→ 用户批准后修改文件
→ Agent 运行测试或检查命令
→ 根据结果继续修复
→ Agent 汇报修改和验证结果
通过项目理解:
- 对话上下文和任务状态;
- 工具定义和结构化参数;
- 模型调用与工具结果回传;
- 宿主程序对模型行为的控制;
- 代码编辑策略;
- 测试驱动的 Agent 工作流;
- 安全边界和权限审批;
- Agent 的可观测性和评测方法。
首版版本暂定为 v0.1。
CLI 需要支持:
- 从命令行参数接收一次性任务;
- 从标准输入接收任务;
- 启动交互式多轮会话;
- 指定工作区路径;
- 指定模型名称和模型服务地址;
- 设置最大 Agent 轮数;
- 设置任务超时;
- 用户主动取消任务;
- 输出过程事件和最终结果。
截至 2026-10-13,标准输入和标准输出都连接终端时,CLI 使用整段会话共用的全屏备用屏幕,只展示本次运行的消息,输入区固定在底部。交互输入支持多行编辑、自动折行、光标移动和随光标滚动;Shift+Enter / Ctrl+J 插入换行,Enter 提交整段输入,上下键只移动当前草稿光标,不浏览历史记录。等待任务输入或工具审批时,滚轮、触控板及 PageUp / PageDown 可滚动上方会话,滚轮每次移动三行;鼠标点击等非滚动事件不会写入输入或提交审批。窗口尺寸变化时重新排版,退出会话后恢复主屏幕和终端模式。管道输入保持逐行提交。
模型生成回答或工具执行期间,底部输入区仍保持显示,当前尚不支持滚动上方会话。操作说明见 全屏会话与滚动。
工作区始终是启动目录。本项目以 apps/ 为完整运行工作区,根目录记忆对应 apps/MiniCode.md,本地详情和 Session 位于 apps/.minicode/;程序不会因为配置路径或目录名称而自动切换工作区。
Ctrl+C 在输入阶段退出且不提交草稿,在运行阶段取消底层操作并退出整个会话。用户取消显示「任务已中断」,任务达到时限显示「任务执行超时」,普通失败保留具体错误;上述状态不代表本节其他规划项均已完成。
首版需要在单次进程运行期间保留当前会话上下文,包括:
- 用户消息;
- Agent 的阶段性回答;
- 模型工具调用;
- 工具执行结果;
- 工具错误;
- 当前工作区信息。
当前实现会为新会话生成 UUID,并默认将历史自动保存到工作区内的 .minicode/sessions/<id>.json。CLI 启动时显示该 ID;后续可在同一工作区使用 --session <id> 跨进程恢复。存档包括用户消息、Agent 回复、工具调用与结果、工作区和上一轮状态;恢复时重新生成系统 Prompt,不恢复运行中的进程、审批状态或文件读取缓存。
Session v2 保存完整原始消息 messages,并独立保存压缩检查点 compaction,包含摘要 summary 和近期消息起点 first_kept_message_index。压缩只更新检查点,内存和存档中的原始历史继续保留;模型请求临时构造摘要与近期原文。手动 /compact 成功后立即保存,自动压缩和超限恢复沿用本轮结束时的保存流程。存档继续受 64 MiB 文件大小限制。
读取 v1 存档时会迁移到 v2;旧摘要移入独立检查点,现存原始消息继续保留。旧版已经被摘要替换而丢弃的原文无法恢复。恢复时校验完整原始历史和检查点,再构造模型上下文。
该能力属于显式恢复的会话历史;跨会话项目记忆由根目录 MiniCode.md 提供,见 4.11 项目长期记忆。
上下文压缩属于 Coding Agent 的基础能力之一,但首版只实现轻量级方案,不引入向量数据库或复杂记忆系统。
上下文压缩的目标是:在多轮读取文件、执行测试和修改代码之后,控制发送给模型的历史消息和工具输出大小,同时保留继续完成任务所需的信息。
当前实现(Day 13、Day 14 已完成):
- 系统 Prompt 保持原样,固定
KeepRecentTokens = 20000,从后向前估算 token,并按完整消息或完整工具批次选择接近预算的保留边界。始终至少保留最新的一个整体,因此单条消息或工具批次很大时,近期原文可能超过 20k;该常量不可配置。 - 旧历史完整序列化为带角色标记的文本,包括工具名称、参数、调用 ID 和结果。摘要输入不做额外字符截断;工具执行阶段原有的输出大小限制继续生效。
- 使用当前模型的独立、无工具、非流式
Provider.Chat请求,借用 pi 的首次摘要和更新摘要 Prompt。首次生成摘要,再次压缩时把已有摘要与新增旧历史一起输入,生成更新后的摘要。 - 摘要按目标、约束与偏好、进度(已完成、进行中、阻塞)、关键决策、下一步和关键上下文组织。修改文件、测试状态和错误等信息由 LLM 归纳,暂未提供独立的结构化元数据字段。
- 摘要请求单独计算预算,扣除摘要指令、已有摘要和固定余量;超预算时按 UTF-8 边界分块,各块依次更新摘要。分块可以跨序列化消息或参数文本,所有剩余内容继续进入下一块;服务端报上下文超限时,拆小当前块继续处理。
- 完整摘要成功后,候选检查点通过边界和消息序列校验才提交。模型上下文为“系统 Prompt → 项目记忆 user 消息(如有)→ 带
<context-summary>标记的 user 消息 → 保留的近期原文”,完整原始历史继续保留。独立注入的项目记忆块不进入摘要输入,压缩后仍根据当前文件构造。清空旧预算校准,后续主对话回复重新校准。 - 没有可压缩旧消息时跳过模型调用。摘要失败、为空、返回工具调用、结束原因不完整、校验失败或请求取消时,保留旧检查点和原始历史;输出达到长度限制产生的半截摘要不能保存。
provider.ValidateMessages统一校验压缩输入、候选模型上下文、Agent 与流式/非流式 Provider 请求,以及存档消息。校验角色字段、调用 ID、工具类型、名称、完整 JSON 对象参数和每批工具结果配对。批次未完成时不能插入其他角色消息;工具结果可按任意顺序返回,连续 user 消息及批次之外的 system 指令合法。同批次重复 ID、孤立或缺失结果等错误在本地返回,并包含消息索引和相关调用 ID。Session 存档继续禁止保存 system 消息。
关键上下文的保留目标包括:
- 用户的明确约束;
- 当前任务目标;
- 已经执行过的关键操作;
- 当前工作区和修改文件;
- 测试失败原因;
- 尚未完成的工作。
Day 14 已接入压缩后、发送模型前的统一消息序列校验,并通过连续压缩的逐项语义验收。语义验收只在测试阶段运行,不为每次生产请求增加判定模型调用;具体结果见下文。摘要是 LLM 生成的有损归纳,固定场景验收通过不保证任意任务都能完整保留信息;需要精确信息时,仍应重新读取工作区文件。
当前压缩入口:
- 自动触发:固定
ContextWindow = 256 * 1024、ReservedTokens = 16 * 1024,估算占用严格超过245760token 时触发。使用最近一次主对话 usage 校准已有占用,再计入新增消息、工具调用、结果和工具声明;项目记忆正文及包装也计入完整请求。缺少 usage 时使用本地粗估。新用户输入追加后、每次模型请求前检查,工具批次全部完成后再检查下一次请求。 - 手动触发:用户在输入循环执行
/compact。命令不进入对话历史,成功后立即保存原始历史和独立压缩检查点;没有可压缩旧内容时提示并跳过模型调用。只支持命令本身,未提供附加摘要指令参数。 - 超限恢复:模型服务明确返回上下文窗口超限时,调用同一压缩函数,仅重试当前主对话请求一次。保留已完成的工具结果和临时附加指令,不重放工具;输出长度限制和普通限流错误不触发该恢复。
普通主对话、轮数上限后的总结和摘要请求均固定使用 max_tokens = 8192,不提供输出上限配置。摘要调用和返回的 usage 计入实际任务统计;摘要请求的 usage 不用于校准主对话预算,本地估算也不计入用量统计。
256k 是代码中的窗口假设,程序未自动识别所用模型的实际上下文窗口。最新用户输入或最新工具批次本身过大时,压缩旧历史仍可能无法使请求放入模型窗口。
实现位于 apps/internal/compaction/,三个入口的接入位于 apps/internal/agent/compact.go 和 run.go。pi Prompt 的来源与 MIT 许可保留在 apps/internal/compaction/prompt.go 中。
压缩只处理当前会话的历史。跨会话项目记忆作为 Day 15 扩展独立加载;向量检索、全仓库 Embedding 和复杂记忆召回仍未纳入当前实现。
测试使用同一固定任务,实际连续压缩三次,并在每轮保存、恢复独立检查点。场景依次为:修改配置后测试失败、修复后全量测试通过、再次修改代码但尚未复测。每轮必须推进保留起点,检查点构造的对话上下文仅包含摘要与近期原文。
- 逐项检查任务目标、不新增依赖及不修改文档的约束、当前工作区、累计修改文件、测试命令、最新测试状态和下一步;路径、命令与当前失败信息要求准确保留。
- Fake Provider 验证事实输入、旧摘要传递、检查点恢复和 Agent 续接;其参考输出用于流程回归。
- 真实模型生成摘要后,使用同一配置模型的独立请求验收含义,允许同义改写,但要正确判断否定方向、历史与最新状态。每个通过项必须引用摘要中的连续原文,报告不能缺项、重复 ID 或使用不存在的证据。
- 真实模型负例包含遗漏目标、反转依赖约束和把尚未复测的最新修改写成已通过。报告格式、证据和截断处理另有本地测试。
入口为 apps/test/compaction/semantic_test.go 和 semantic_live_test.go。普通 go test 默认跳过真实模型测试;显式启用时,测试先切换到仓库根目录,优先读取 config/config.toml,不存在时读取本项目通常使用的 apps/config/config.toml。从仓库根目录执行:
MINICODE_TEST_LLM=1 go -C apps test ./test/compaction -run '^TestCompact_LiveSemanticAcceptance$' -count=1 -v -timeout=10m2026-10-13 的本地回归、全量 race 测试及 go vet 已通过。同日使用配置模型 gpt-5.6-sol 完成真实模型验收:三轮连续压缩分别通过 8、7、8 项事实检查,每轮推进保留起点并保存、恢复检查点;遗漏目标、反转依赖约束和过时测试状态三个负例均被正确拒绝。测试整体通过,验收耗时 54.46 秒,Day 14 已完成。此前两次上游 do_request_failed 属于较早的未完成尝试,历史记录保留在开发计划中。本次结果对应固定场景和当时配置模型;模型或摘要提示变化后可重新执行。
模型适配层负责与模型服务通信:
- 将 Agent 提供的消息历史和系统规则转换为模型请求;
- 随请求发送工具名称、描述和参数结构;
- 接收普通文本回答;
- 接收结构化工具调用;
- 在后续请求中发送 Agent 提供的工具执行结果;
- 处理鉴权、网络、超时和响应解析错误,并转换为统一响应与错误结构。
Agent 维护多轮消息历史,并负责工具审批、执行及记录工具结果。模型适配层负责模型服务通信和协议转换。
当前实现(Day 13):Agent 依赖 Provider 抽象,主对话自动使用可选的 StreamingProvider.ChatStream 能力,摘要调用非流式 Chat;CLI 通过 provider.New 按配置创建实现。公共数据包括 ChatRequest、ChatResponse、消息、工具调用、流式事件与可选用量;服务 HTTP / SSE 业务错误统一为 APIError,网络和取消错误保留原有错误链。
目前实际适配器仅支持 OpenAI 兼容 Chat Completions 协议。model.provider 可省略或留空,默认为 "openai";当前可显式指定的协议名也只有 "openai"。兼容服务可以通过地址、密钥和模型名切换;新增专用协议需实现 Provider 并接入配置工厂,Agent Loop 和工具系统无需随之修改。
配置优先读取启动目录内的 config/config.toml,仅文件名确实不存在时兼容 apps/config/config.toml。首选文件不可读、是目录、符号链接断开、解析失败或缺少必填字段时返回错误,不使用旧配置掩盖错误;不搜索父目录,不通过环境变量或 CLI flag 覆盖模型配置。从本项目的 apps/ 启动时,现有 apps/config/config.toml 正好对应首选路径。
当前模型配置和 ChatRequest 均未提供思考强度字段,流式与非流式请求都不发送 reasoning_effort,因此由模型服务或网关决定默认值。GPT-5.6 Sol 官方模型说明 标明默认强度为 medium;兼容网关可能覆盖该默认值,不能据此确认当前网关的实际设置。配置解析会拒绝未知字段,当前不能通过在 TOML 中添加思考强度字段来设置它;上述真实模型验收也未显式指定强度。
OpenAI 兼容实现已支持 SSE 流式请求,发送 stream: true 和 stream_options.include_usage: true,要求响应类型为 text/event-stream。解析器按空行读取事件,合并多行 data,支持 LF、CRLF、CR、BOM、注释和心跳,并限制单个事件大小。只接受一个索引为 0 的候选回复,收到 [DONE] 后返回正常结束;finish_reason 后仍继续接收可能单独出现的用量事件。
Agent 按工具索引累积名称与 JSON 参数,流正常结束并校验全部调用后才执行工具。流式错误、提前断线、超时或取消会关闭响应体,不执行该次未完成回复中的工具,也不将半截 assistant 消息写入历史。任务统计和 Langfuse 追踪继续记录完整调用中的用量、耗时与错误。
主对话和轮数上限后的总结自动使用流式能力,无需用户配置,也不提供 CLI 或 Session 开关。Provider 未实现流式能力或明确返回 ErrStreamingUnsupported 时,Agent 使用 Chat;其他 API、网络和解析错误直接返回,不自动重发非流式请求。上下文摘要使用独立的非流式 Chat 请求,不向终端预览摘要文本。Fake Provider 仍可只实现 Chat,测试不依赖真实模型服务。
标准输入和标准输出都连接终端时,CLI 在会话全屏界面累计文本并实时渲染 Markdown,按 50 毫秒间隔合并后续更新。跨分片或未闭合的 Markdown 格式随新文本重新排版;渲染失败时回退原文。生成期间视口跟随新内容,窗口尺寸变化时自动重排。每次流结束、错误、超时或取消时清理当次预览,成功完成的回答以完整 Markdown 加入会话展示记录;流结束不退出全屏界面,仅退出会话时恢复主屏幕和终端模式。历史滚动的可用阶段见 4.1。
非交互模式不输出增量预览和过程状态,完整回答保留 Markdown 原文并写入 stdout,会话标识、统计和错误写入 stderr;副作用工具的审批说明和参数仍按现有规则展示。
Agent Loop 是项目的核心功能,负责以下流程:
- 接收用户任务;
- 构造并校验模型上下文,检查预算,必要时生成并校验新检查点,发送前再次校验消息序列,再调用模型;
- 判断模型是直接回答还是请求工具;
- 校验工具名称和参数;
- 判断工具权限;
- 必要时请求用户批准;
- 执行工具;
- 将工具结果或错误返回模型;
- 重复执行,直到任务完成或停止。
必须支持以下停止条件:
- 模型返回最终回答;
- 用户主动取消;
- 达到最大模型轮数;
- 达到任务超时;
- 模型 API 发生不可恢复错误;
- Agent 内部发生不可恢复错误。
首版计划提供以下只读工具:
| 工具 | 功能 |
|---|---|
list_files |
列出工作区中的文件和目录 |
read_file |
按文件和行范围读取文本 |
search_text |
在文件或目录中搜索文本或正则表达式 |
git_status |
查看当前 Git 工作区状态 |
git_diff |
查看当前未提交修改 |
文件浏览工具需要支持:
- 工作区相对路径;
- 文件大小限制;
- 单次输出大小限制;
- 大文件分段读取;
- 明显二进制文件过滤;
- 路径穿越检查;
- 符号链接边界检查。
首版计划提供:
| 工具 | 功能 | 权限 |
|---|---|---|
edit_file |
精确替换已有文件中的唯一文本块 | 需要审批 |
write_file |
创建新文件或完整写入文件 | 需要审批 |
首版的 edit_file 应要求旧文本满足以下条件:
- 旧文本不能为空;
- 旧文本必须存在;
- 旧文本只能出现一次;
- 修改前文件内容必须与读取结果匹配;
- 写入过程尽量采用原子替换。
后续可以增加更强的 apply_patch 工具,但不作为 v0.1 的必要条件。
当前提供 bash{command},通过 bash -c 执行;后续可增加接收 argv 的 run_command。命令工具用于运行:
- 单元测试;
- 集成测试;
- 构建命令;
- 格式化命令;
- 静态检查命令。
命令工具需要支持:
- argv 参数数组;
- 指定工作目录;
- 超时控制;
- 退出码获取;
- 标准输出和错误输出捕获;
- 输出大小限制;
- 用户审批;
- 命令失败结果回传模型。
当前接入 shell 字符串并通过 bash -c 执行,继承启动 CLI 时的工作目录。bash、write、edit 默认在执行前逐次请求用户确认,拒绝后不执行并将结果回传模型;--yes 可自动批准。项目不提供 shell 命令内容黑名单、危险命令硬拦截、细粒度命令权限或 argv 模式,当前工作目录也不是文件系统沙箱。
工具分为只读工具和副作用工具。
默认可以自动执行:
- 列目录;
- 读取文件;
- 搜索代码;
- 查看 Git 状态;
- 查看 Git diff。
默认需要用户确认:
- 修改文件;
- 创建文件;
- 删除文件;
- 运行命令;
- 其他可能改变工作区或系统状态的操作。
审批提示应至少展示:
- 工具名称;
- 目标文件或工作目录;
- 命令或参数摘要;
- 允许和拒绝选项。
CLI 需要让用户能够观察 Agent 当前行为,包括:
- 当前任务;
- 当前模型轮次;
- 当前工具调用;
- 工具参数摘要;
- 审批结果;
- 工具执行成功或失败;
- 最终修改和测试结果。
后续可以增加 JSONL 事件日志,用于调试、恢复和评测,但不作为首版阻塞项。
当前交互终端使用整段会话共用的备用屏幕,输入区固定在底部;用户提交、模型预览、完整回答、工具状态、审批信息、统计及运行错误都显示在上方会话区域。流结束只清理当次预览,退出会话时恢复主屏幕、光标和终端模式;历史滚动的可用阶段见 4.1。工具原始结果回传模型并记录在会话中。每项任务结束时汇总耗时、模型调用次数、工具调用次数,以及完整模型响应提供的输入、输出和总 token,包含上下文摘要请求。模型未提供 usage 时明确显示不可用,只有部分响应提供时标记为部分统计。非交互模式不展示预览和过程状态,完整回答写入标准输出,会话标识、任务统计和错误写入标准错误;审批信息仍按现有规则展示。展示方式不改变会话保存流程;压缩后的存档按 4.2 和 4.3 保存完整原始历史与独立检查点,模型读取摘要与近期原文。
项目长期记忆用于同一工作区的新会话复用稳定知识,例如项目约定、常用命令和技术结论;临时任务目标和进度仍由 Session 历史及摘要承载。根目录 MiniCode.md 保存常驻约定与简短目录,专题正文位于 .minicode/memory/*.md;不依赖 --session,不扫描父目录或全局目录。本项目已迁移到 apps/MiniCode.md 和 apps/.minicode/memory/,运行时从 apps/ 启动。
- 使用普通 UTF-8 文本文件,不解析条目 ID、Frontmatter 或专用 JSON 格式;原文及换行保持不变。
- 文件名确实不存在时视为无记忆,不自动创建;已有空文件同样不注入记忆消息。
- 根目录文件最多
64 * 1024字节,必须是合法 UTF-8 且不含 NUL;正文和目录合计原文预算最多4 * 1024个本地估算 token,两项限制均须满足。 - 共用
token.EstimateText:ASCII 字符数除以 4 向上取整,每个非 ASCII 字符按 2 token 粗估。这不是模型实际分词或 usage;记忆消息包装开销由完整请求预算另计。 - 路径、文件类型、读取、编码或预算检查失败明确返回错误,不截断、不返回部分内容;符号链接不能逃出工作区。
目录使用普通 Markdown 链接,包含专题名称、适用场景及相对工作区的路径,例如:
- [会话恢复](.minicode/memory/session-compaction.md):修改 Session 保存或恢复时参考。宿主只自动加载根目录文件;模型根据任务选择相关目录项,使用现有 read 读取详情。系统 Prompt 要求无关任务不预读全部专题,未读正文不能声称已了解详情,文件缺失或过时时核对当前代码。模型负责选择,宿主不解析目录条目、扫描详情目录、执行关键词匹配或向量召回。
memory.IsDetailPath 识别规范化后位于 .minicode/memory/ 内的相对 Markdown 路径,可包含子目录;相邻目录和非 Markdown 文件沿用普通文件规则。memory.ValidateFile 共用完整 UTF-8、NUL 和 64 KiB 检查;详情不受常驻 4,096 token 限制。显式读取的正文通过普通工具结果计入上下文预算,写入参数等已记录的工具消息也照常计入。
详情读取沿用文件工具的分页和输出截断规则。未选择的缺失、损坏或超限详情不阻断启动;显式读取错误作为工具结果回传。根目录与 apps/ 下的 .minicode/ 都被 Git 忽略,专题正文目前是本地资料,不随仓库共享。
新建和恢复 Session 时加载当前文件,每个用户轮次在追加新输入前重新加载,手动 /compact 前也重新加载。已有记忆失效时清除旧缓存并返回错误,不发送该次模型请求;修正文件后可以重试。
当前整个 MiniCode.md 常驻上下文,以带 <project-memory> 标记的独立 user 消息放在系统 Prompt 后、摘要及近期原文前;不会自动附加详情正文。参考消息说明:与系统规则或本次用户明确要求冲突时,以系统规则和本次要求为准。文件内容、包装及其他消息一起接受发送前结构校验和上下文预算检查。
记忆缓存独立于 Session.messages 与 compaction.State,不增加 Session v2 快照字段。自动注入的记忆块不加入原始历史或摘要输入;连续压缩后仍单独构造,恢复会话时使用磁盘上的最新文件。普通用户消息、读取文件的工具结果和写入参数仍可在历史中包含记忆内容,删除项目记忆不会清除这些历史记录或已有摘要。
模型复用现有 read / write / edit 工具,用户可以直接要求“记住”“更新项目记忆”“忘记指定约定”或“清空全部项目记忆”。查询和维护统一走普通对话,按用户约定不提供 /memory、/forget 专用命令。
系统 Prompt 要求只在用户明确提出维护记忆时修改,只记录稳定、可复用的事实,不保存密钥或临时进度;先读取完整文件并保留无关内容,相同结论不重复追加,冲突约定替换旧内容,删除后未经重新授权不从旧历史写回。这些属于模型执行约定,宿主未实现语义意图识别、条目去重或冲突解析。
| 操作 | 工具流程(顺序由模型遵循提示) |
|---|---|
| 创建或完整写入 | write 提供完整文件内容;文件不存在时创建 |
| 更新约定 | read 后使用 edit 替换对应内容 |
| 删除指定内容 | edit 将匹配的旧内容替换为空字符串 |
| 保存或更新专题 | 先成功保存详情,再添加或更新根目录项 |
| 忘记整个专题 | 先清空详情,再移除目录项,保留空文件 |
| 清空全部记忆 | 先读取并清空目录列出的详情,再清空根文件 |
写入和编辑沿用副作用工具审批,拒绝时不执行,--yes 自动批准。write 和 edit 在落盘前共用 memory.ValidateFile 校验完整候选文件:根目录委托 memory.NewDocument 检查常驻预算,详情检查文本和大小。失败作为工具错误返回且保留原文件,成功沿用既有原子写入。edit 保留先读或先写、唯一匹配与外部变更检查;write 仍允许完整覆盖,先读再写由 Prompt 要求。目录与详情分别原子写入,不提供多文件事务;同步顺序和失败报告由模型遵循提示执行。
成功修改根目录记忆后,在整批工具结果完成配对时重新读取,下一次模型请求即可使用最新内容。刷新失败保留已完成工具历史并停止当前任务。此即时刷新识别现有 write / edit 的规范化根目录路径;通过 shell 或其他路径间接修改没有新增专用检测,由下个用户轮次或手动压缩前的重新加载读取。
常驻约定、简短目录和按需详情已接入,本地建立代码组织、会话与上下文压缩、项目记忆、终端交互四个专题。宿主不自动划分内容或建立索引库;目录选择、语义去重和同步依赖模型提示。pi 参考及阶段收尾记录见 Day 15 开发计划。
实现位于 apps/internal/memory/load.go、files.go、apps/internal/token/estimate.go、apps/internal/agent/memory.go、prompt.go 和现有 Session、压缩、文件工具及配置接入点。测试覆盖常驻与详情校验、未读正文不注入、按需读取、压缩后重读、专题与目录维护、apps 启动、配置优先级与错误不回退;2026-10-13 全量 race 测试、go vet 和编译通过。Fake Provider 验证宿主流程。2026-10-18 按用户决定跳过真实模型的专题选择、去重、冲突更新及删除行为验收,Day 15 以“功能已实现,真实模型验收跳过”收尾;跳过项未执行,不记为验收通过。
- 单 Agent;
- 单任务;
- 单工作区;
- CLI 交互;
- 多轮上下文;
- 轻量级上下文压缩;
- 基础文件工具;
- 命令执行;
- 人工审批;
- 基础安全和资源限制;
- 测试与结果总结。
Day 15 已扩展本地项目长期记忆,见 4.11;项目记忆、后续 Subagent 和运行观测增强仍不作为 Day 0~Day 14 的 v0.1 验收条件。
- Web UI;
- IDE 插件;
- 多 Agent 和子 Agent;
- 全局用户记忆和跨项目记忆召回;
- 向量数据库和全仓库索引;
- 自动 Git commit、push 和 Pull Request;
- 自动部署;
- 复杂任务编排;
- 多工作区并行操作;
- 操作系统级沙箱;
- 后台常驻服务。
首版不是生产级安全沙箱,但必须具备基础防护:
- 文件操作限制在工作区内;
- 拒绝绝对路径和路径穿越;
- 检查符号链接是否指向工作区外;
- 限制文件、请求和工具输出大小;
- 限制模型最大调用轮数;
- 限制命令执行时间;
- 副作用工具默认需要审批;
- 不将未经用户批准的模型命令交给 shell 执行;
- 不在日志中输出 API Key;
- 明确提示:批准执行的命令和构建脚本仍可能执行任意代码,项目不提供危险命令硬拦截。
v0.1 至少应完成以下任务:
- 解释一个陌生仓库的目录结构和启动流程;
- 找到指定代码并完成一个小型修改;
- 运行测试并根据失败信息继续修复;
- 在工具参数错误时能够重新观察和调整;
- 用户拒绝写入或命令执行后,操作确实不会发生;
- 最终准确说明修改内容和真实验证结果;
- 长任务上下文接近限制时能够进行轻量级压缩;
- 超过最大轮数或任务超时后能够安全停止。
本文只描述项目定位、功能范围、设计边界和验收标准,不记录开发进度。 开发计划和完成状态请参阅
docs/plan.md。