第 1 章 · 01 Reasonix 定位与 SPEC §1 六条设计原则 本节摘要:本节是契约驱动之旅的起点。先澄清 Reasonix 到底是什么——一款 DeepSeek 原生调优的终端 AI coding agent(非 DeepSeek 官方模型仓库),MIT 协议,版本 1.20.0,作者以中国开发者为主的社区(esengine 等);它的核心定位是"由配置与插件驱动的极薄 harness"。随后逐条精读 §1 六条设计原则(配置+插件驱动核心、单静态二进制 CGOENABLED=0、精简依赖、两层扩展、接口优先与注册表、演进不过度工程),并解读开篇那句贯穿全书的工程契约——"This document is the contract — code follows it.
本节摘要:本节是契约驱动之旅的起点。先澄清 Reasonix 到底是什么——一款 DeepSeek 原生调优的终端 AI coding agent(非 DeepSeek 官方模型仓库),MIT 协议,版本 1.20.0,作者以中国开发者为主的社区(esengine 等);它的核心定位是"由配置与插件驱动的极薄 harness"。随后逐条精读
docs/SPEC.md§1 六条设计原则(配置+插件驱动核心、单静态二进制 CGO_ENABLED=0、精简依赖、两层扩展、接口优先与注册表、演进不过度工程),并解读开篇那句贯穿全书的工程契约——"This document is the contract — code follows it. Change the contract first, then the code."
内容来源:原项目源码
docs/SPEC.md§1(Design Principles)与cmd/reasonix/main.go、internal/provider/provider.go、internal/tool/tool.go关键定义。
⚠️ 注意:Reasonix 不是 DeepSeek 官方模型,也不是 DeepSeek 官方代码仓库,而是一个第三方构建、以 DeepSeek 为首选 provider 的通用 coding agent 框架。理解这一点,才不会被"DeepSeek 原生调优"的字面意思误导。
阅读完本节,你应当能够:
CGO_ENABLED=0)为何是硬约束,以及它如何反推依赖选型。init() 自注册 vs 运行时 stdio JSON-RPC 插件)。Reasonix 是一款 DeepSeek 原生调优的终端 AI coding agent——Claude Code、Gemini CLI 的同类产品。关键事实如下:
DeepSeek-Reasonix-main-v2,2026-08)。esengine 等贡献者),README 双语(README.md 英文 + README.zh-CN.md 中文)。darwin|linux|windows × amd64|arm64),终端 CLI 为主入口,另提供 HTTP/SSE、Wails 桌面、IM 机器人等前端。最关键的认知校准:Reasonix 不是 DeepSeek 官方模型仓库。DeepSeek 官方提供的是模型权重与 API;Reasonix 是把 DeepSeek(以及任何 OpenAI 兼容端点)当作首选 provider 接入的第三方 coding agent 框架。"DeepSeek 原生调优"指的是它围绕 DeepSeek 的前缀缓存(prefix cache)做了专门优化——这是第 6 章的主题,本节先记住这个定位即可。
Reasonix 的核心定位,被一句话写在 SPEC 开头(docs/SPEC.md:3-5):
Reasonix is a coding agent: a thin harness driving multiple models, with all capabilities supplied by configuration and plugins.
翻译过来:Reasonix 是一个 coding agent——一个驱动多个模型的"薄 harness",所有能力都由配置和插件提供。"薄 harness"(thin harness)是本书反复出现的核心隐喻,下一节专门展开,本节先从它的"骨头"——六条设计原则——切入。
在讲六条原则之前,必须先理解 SPEC 这份文档的特殊地位。docs/SPEC.md 不是普通的"设计说明",它是项目的工程契约。SPEC 开篇明义(docs/SPEC.md:1-5):
This document is the contract — code follows it. Change the contract first, then the code.
这份文档就是契约,代码跟随它。先改契约,再改代码。
这句话不是修辞,而是可执行的工程纪律:
internal/boot/、internal/tool/、internal/provider/ 等缓存敏感路径,PR body 必须带 Cache-impact: 与 Cache-guard: 两行元数据(见 REASONIX.md 的 Cache-impact PR metadata)。internal/config/、internal/memory/、internal/skill/ 等影响系统提示的路径,还要加 System-prompt-review: 一行。n/a、none、todo、tbd 会被 CI 直接拒绝——必须写出真实理由。💡 契约要点:"契约先行"不是文档习惯,而是 CI 强制约束。SPEC 把"想清楚再动手"从口头倡导变成可机器检查的 PR 元数据,这是 Reasonix 工程文化最值得借鉴的一点。
docs/SPEC.md:7-20 给出了六条设计原则。下面逐条精读。
The core knows only interfaces. Concrete models and tools are resolved by name from registries, declared in config, or injected by plugins. No hardcoded
switch model.
要义:核心只懂 interface,具体模型和工具按"名字"从注册表解析、在 config 中声明、或由插件注入。绝无硬编码的 switch model。
这是"薄 harness"的代码体现。看 internal/provider/provider.go:970-977 的 Provider interface:
type Provider interface { Name() string Stream(ctx context.Context, req Request) (<-chan Chunk, error) }
核心只认这两个方法,不知道 DeepSeek、不知道 OpenAI、不知道 Anthropic。具体 provider 通过 Register(kind, Factory) 在 init() 里自注册,运行时用 New(kind, cfg) 按名字实例化。第 3 章会详细展开。
CGO_ENABLED=0; cross-compile with one command; CLI works out of the box.
要义:一个命令交叉编译,产出单静态二进制,开箱即用。
CGO_ENABLED=0 是硬约束。SPEC §8 给出构建命令(docs/SPEC.md:863):
CGO_ENABLED=0 go build -ldflags "-s -w -X main.version=$(VERSION)" -o reasonix ./cmd/reasonix
交叉矩阵是 darwin|linux|windows × amd64|arm64 共六个平台。这条约束会反推所有依赖选型——任何需要 cgo 的库(如某些数据库驱动、GUI 绑定)都直接被排除。注意:tree-sitter 代码索引是 cgo 绑定,所以它走 //go:build treesitter && cgo 的可选构建标签,默认编译没有它(见第 4 章第 3 节)。
Standard library by default. A third-party dependency must be pure-Go, lightweight, and must not compromise the single-binary / cross-platform / distribution story. TOML parsing is the one accepted dependency.
要义:默认标准库。第三方依赖必须纯 Go、轻量、不破坏单二进制与跨平台故事。TOML 解析是唯一被接受的依赖。
这条原则把"加新依赖"的门槛设得极高。看 SPEC §2 Layout 注释(docs/SPEC.md:30):
go.mod / go.sum # module reasonix; require BurntSushi/toml
整个项目对外部依赖的容忍度极低:BurntSushi/toml(配置解析)、mvdan.cc/sh(shell 解析)、santhosh-tekuri/jsonschema/v6(工具参数校验)、tree-sitter(可选 cgo)等少数纯 Go 库。每个都经过"是否破坏单二进制"的审视。
Compile-time built-ins (self-register via
init()), and runtime external plugins (stdio JSON-RPC subprocesses, MCP-compatible).
要义:两层扩展——编译期内置(通过 init() 自注册),以及运行时外部插件(stdio JSON-RPC 子进程,兼容 MCP)。
init() 里调用 tool.RegisterBuiltin(t) 或 provider.Register(kind, f)。见 internal/tool/builtin/bash.go:34:func init() { tool.RegisterBuiltin(bash{}) }。[[plugins]] 配置里。第 7 章详讲。两层结合,既有编译期的性能与类型安全,又有运行时的灵活——加新工具不必重编译。
ProviderandToolare interfaces.
要义:Provider 和 Tool 都是 interface。
这条看似简单,实则是原则 1 的技术底座。正因为 Provider/Tool 是 interface,才能做到"核心只懂接口、具体按名解析"。internal/tool/tool.go:19-33 的 Tool interface:
type Tool interface { Name() string Description() string Schema() json.RawMessage Execute(ctx context.Context, args json.RawMessage) (string, error) ReadOnly() bool }
第 3、4 章会分别精读这两个 interface 与它们的注册表。
要义:不要过度工程。
这条没有代码对应,却贯穿全书。SPEC §9 Roadmap 明确列出"暂不做"的事:OAuth 2.0、list_changed 实时更新、Anthropic 原生 provider 等——理由都是"无消费者/无基础"。Reasonix 选择"先把契约走通、把缓存走稳",再考虑长尾功能。
六条原则不是并列清单,而是一张互相支撑的网:
| 原则 | 支撑谁 | 被谁支撑 |
|---|---|---|
| 1 配置插件驱动 | — | 5 接口+注册表(技术底座) |
| 2 单静态二进制 | — | 3 精简依赖(选型约束) |
| 4 两层扩展 | 1 配置插件驱动 | 5 接口+注册表 |
| 6 演进不过度 | 全部 | — |
原则 5(接口+注册表)是原则 1(配置插件驱动)的技术实现;原则 3(精简依赖)是原则 2(单静态二进制)的反推结果;原则 4(两层扩展)把原则 1 拆成"编译期"与"运行时"两个时机;原则 6 是给前五条画边界——能不做就不做。
💡 契约要点:六条原则不是"风格偏好",而是可验证的工程约束。
CGO_ENABLED=0能在go build时检查;No hardcoded switch model能在 code review 时检查;依赖是否纯 Go 能在go.mod里检查。SPEC 把设计原则写成可执行的句子。
下一节,我们从六条原则落到代码与目录——展开"薄 harness"哲学的具体含义,并巡视
cmd/internal/sdk/desktop/workers顶层布局,最后与 Claude Code 做一次定位对比,预告"三前端共用单 Controller"这条贯穿后五章的主线。