☰
Kun 设计与运行时深度解析:单一 HTTP/SSE 边界的本地优先 AI Agent 工作台
2026/10/10 1:50:00 网站建设 项目流程
  • 人工智能
  • AI Agent
  • 自主智能体
  • 桌面应用
  • MCP Clients

【免费下载链接】Kun

Local-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.

项目地址:https://gitcode.com/gh_mirrors/de/Kun
点击查看免费下载

本文以仓库权威设计文档 docs/design/zh-CN/foundations-and-runtime.md 为核心骨架,深入解读 Kun(前身 DeepSeek GUI)的设计基础(视觉令牌体系、设计原则、布局语法)与核心运行时(Kun runtime)的架构原理、HTTP/SSE 边界、缓存优先的 Agent 循环与持久化模型,并结合 kun/src 源码给出可验证的实现细节。读完本文,你将掌握:Kun 为什么把"一个运行时、一个边界"作为最高原则,kun serve的命令行参数与路由表如何工作,缓存优先的 Agent 循环如何通过不可变前缀与 InflightTracker 保证稳定与可观测,以及线程、审批、沙箱与磁盘持久化之间的完整关系。


1. 如何阅读这份设计文档:双层结构

Kun 的设计文档刻意采用双层结构,这是理解整个项目设计哲学的钥匙:

  • YAML frontmatter(文档顶部的---代码块):机器可读的设计令牌——精确的十六进制色值、字体栈、间距刻度、圆角刻度、阴影、动效时长与组件配方。Stitch、Figma 插件以及未来的代码生成工具会逐字读取并应用这些值。修改任何值都必须同时更新 frontmatter 与src/renderer/src/styles/*.css/src/renderer/src/index.css,保证运行中的应用与设计文档保持同步。
  • Markdown 正文:人类可读的why——设计意图、原则、反模式以及每个屏幕的规则。贡献者在判断一个新屏幕是否符合品牌形象时阅读这部分。

两条原则:frontmatter 是值的唯一事实来源(source of truth),Markdown 是判断的唯一事实来源。二者冲突时,frontmatter 优先,Markdown 必须更新。

2. 项目全貌:三个工作区 + 一个运行时

Kun 是一个围绕同名Kun 运行时构建的本地桌面工作台:桌面外壳是 Electron,运行时是 TypeScript 包并通过 HTTP/SSE 通信,渲染层是 React 19 + Zustand 5,视觉系统是 TailwindCSS 3 之上手工构建的令牌层。

产品不是又一个聊天外壳——它的存在是为了让真正的 Agent 在真实机器的真实项目里做真实工作,而人类对每一次变更型调用保持介入(in the loop)。四个产品面共享同一个运行时与边界:

产品面要完成的工作(Job to be done)
Code绑定本地仓库,通过工具调用、文件变更、命令与审查驱动 Agent。
Design生成并迭代 UI 草稿、交互式 HTML 原型、设计图(design graph)以及可交接给 Code 的共享设计系统。
Work面向 Markdown 及其他文档的办公工作区,支持 FIM 补全和选区级联内联 Agent。
Connect phone(连接手机)后台自动化:飞书/Lark 频道、webhook/中继、定时任务。内部路由与存储名仍用claw以保持兼容。

所有产品面共享同一条 Kun HTTP/SSE 边界、同一套设置(API key、base URL、模型)与同一套视觉系统。

3. 六条设计原则:产品已被如此构建

这六条规则不是愿景,而是产品已经如此构建的方式,新屏幕必须遵循而非重新诠释:

  1. 一个运行时、一条边界。Code(含 Design 任务)、Work、Connect phone 全部通过kun serve运行在127.0.0.1:port上。渲染进程从不内嵌 Agent 循环,也从不讲第二种协议——这让升级与调试保持"无聊"。
  2. 本地优先、可观测、可控。设置、会话与运行时状态都存于操作系统 app-data 目录下的磁盘。每一次工具调用、文件变更、推理步骤都显示在 UI 中,用户可随时打断、批准、拒绝或回滚。
  3. 没有 Agent 切换器,没有运行时控制台。产品刻意不暴露运行时诊断、供应商选择或模型控制面板。重要的运行时细节进 Settings,不进主画布。
  4. 渲染进程映射 HTTP,不实现 Agent 逻辑。批准、转向(steering)、压缩(compaction)、fork、resume、usage 全部来自 Kun 端点,绝不在 React 中重实现。
  5. 稳定的视觉身份,而非视觉新奇。新屏幕应该像现有屏幕的"兄弟",而不是全新实验。新组件靠取代多个现有组件来赢得位置,而非增加一种新样式。
  6. 默认平静(Calm by default)。默认表面是近白(或近黑)画布 + 克制的表面,chrome 中无彩色,唯一的强调色只出现在可操作元素上。状态色、危险色与 skill 色是仅有的其他可选颜色。

4. 视觉系统:令牌、颜色、字体与布局语法

4.1 画布与表面:两层的 4% 对比

渲染进程在 chrome 之后绘制两层:

  • 基础画布(Base canvas)(--ds-bg-canvas,亮色#ffffff/ 暗色#181818):中央工作区,聊天时间线、写作编辑器、文件树都在此。
  • 环绕表面(Surrounding surface)(--ds-bg-main,亮色#f5f7fa/ 暗色#101010):应用外壳,侧边栏、顶栏、检查器落于此。

画布与表面的对比刻意很小——约 4%——让眼睛把二者读作同一个工作区而非两个区域。其上再叠加三层半透明玻璃表面:ds-card(卡片、列表行、popover 触发器)、ds-elevated(对话框、下拉、composer 外壳等必须"抬离页面"的元素)、ds-subtle(安静的次级表面,如未激活的设置页签)。玻璃效果通过backdrop-blur-xl(24px)加微弱inset 0 1px 0 rgba(255,255,255,0.45)高光实现;顶栏携带 3 档垂直渐变(topbar_gradient_light/topbar_gradient_dark),读作一条柔和玻璃带;body::after上的body_glaze_light/body_glaze_dark提供柔和的定向光而不引入新颜色。

4.2 颜色:强调色只做这些事

强调色是电光蓝(#0088ff亮色 /#339cff暗色),只用于:主操作按钮("Send""Allow""Save")、聚焦表单控件的边框 + ring、表示"活跃且正在做事"的状态点、超链接式 chip 标签、选区背景(--ds-selection)。禁止用于:大于 chip 的装饰性背景填充、正文或标题、禁用态(禁用元素是opacity 0.45,不改色)。

其他具名颜色各守语义:

  • --ds-success/--ds-success-soft:完成的工具、缓存读取、OK 健康 ping;
  • --ds-danger/--ds-danger-soft:失败的工具、被拒的批准、错误、重试徽标;
  • --ds-skill/--ds-skill-soft:用户加载的 Skill 相关内容(紫色 = "来自插件");
  • --ds-diff-added/--ds-diff-removed:文件变更 diff 块,是唯一允许并排出现在代码块上的颜色;
  • --ds-warning-soft:非致命警告(token 缓存缺失、待重试等)。

其余一切——文本、边框、画布、侧边栏——保持中性色板。如果一个屏幕需要的颜色超过"强调色 + 这些具名语义色",那大概率意味着信息架构应该先改。

4.3 字体、间距、圆角、阴影与动效

  • 三个字体家族:Sans(正文)为 SF Pro Text → PingFang SC → Noto Sans SC → Helvetica Neue → Arial,覆盖中英双语与 macOS/Windows/Linux;Display(hero、欢迎页)为 SF Pro Display,同 CJK 回退;Mono 为 SF Mono → JetBrains Mono → IBM Plex Mono,用于代码块、行内代码、kbd 提示、命令行、模型 id 与工具结果详情。字号只能用typography.size_rhythm刻度梯。
  • 间距:使用 Tailwind 默认 4px 刻度。卡片 padding 是px-3 py-2(紧凑)或px-4 py-3(常规),px-5 py-4留给 hero 卡与全屏模态;行内元素间距为gap-1到gap-3;区块间距为mt-3到mt-6。三栏布局尺寸本身也是设计系统的一部分(--ds-layout-left-sidebar-width)。
  • 圆角:柔和但不圆。顶栏 pill 控件(rounded-full)、主体rounded-xl/rounded-2xl卡片、composer 的单个超大rounded-[28px]外壳。两条硬规则:可点击表面无直角(最小 6px)、卡片表面不全圆(rounded-xl到rounded-3xl,绝不 pill)。
  • 阴影三级:Card soft(列表行、侧面板、页内 popover,单一微弱阴影)→ Card strong / panel(模态、下拉、composer,更深阴影 +backdrop-blur-xl读作"抬升的玻璃")→ Shell(主外壳、欢迎屏、设置根,最深但极少使用)。chip 与 pill 按钮带 inset 高光(亮色inset 0 1px 0 rgba(255,255,255,0.78))。禁止彩色阴影,所有阴影为黑色或近黑低 alpha。
  • 动效是功能性的:确认点击 140ms、悬停态 150ms、路由/面板切换 200–300ms、活性指示(状态点、流式 shimmer)循环 1.8–2.4s。系统内仅有两个循环动画:状态点与 work logo 的pulse,以及流式助手文本的ds-shiny-text(2.4s 线性 shimmer,不是打字机)。其余均为一次性动画;对话框进出不超过 200ms 的 opacity+scale,不动画含多单元格的行,不动画 composer。

4.4 布局语法:每个屏幕的宏文法

Kun 的每个屏幕遵循同一套宏文法:

  • Topbar:半透明条带,含返回按钮、会话标题、模式切换器与右侧操作簇。顶栏始终可拖拽移动窗口,内部交互元素必须用.ds-no-drag退出拖拽。
  • 左侧边栏:Code 的工作区根 / Connect phone(内部claw)的频道 / Work 的空间。可折叠、可拖拽调宽,默认 268px。
  • 中栏:工作表面——Code/Connect phone 的消息时间线或 Work 的编辑器,绝不允许渗入侧边栏。
  • 右侧检查器:可选的上下文驱动面板——Changes、Todo、Browser、Plan、File、Work Assistant、SDD Assistant,可拖拽调宽,默认 360px。

新屏幕必须适配这套文法;如果适配不了,说明文法需要成长,且变更应先写进这份设计文档。

4.5 文案、主题切换与 on-brand 快速测试

  • 双语:字符串位于src/renderer/src/locales/{zh,en}/,经react-i18next加载,新字符串必须中英双语同时发布。语气直接、有帮助、略带主见;产品自称用第一人称复数("we ship Code, Work, and Connect phone"),对用户用第二人称。无 emoji、无营销语言,错误消息是带标点结尾的完整句子,绝不裸抛堆栈。产品名是 "Kun"(前身 "DeepSeek GUI"),bundled 运行时同名,需要区分时说 "Kun runtime";手机/IM 面英文 "Connect phone"、中文 "连接手机";内部代码可仍叫claw,但对外文案不暴露。
  • 主题切换:system/light/dark三态,在 Settings → General 选择。system监听prefers-color-scheme并实时更新,主题以data-theme应用到<html>,Tailwinddark:变体与 CSS 自定义属性同时生效。UI 字号缩放独立(small / medium / large),作为 CSS--ds-ui-scale缩放因子应用。
  • on-brand 快速测试(合并前逐项勾选):符合三栏 + topbar 文法;只用四族颜色(中性、强调、状态、skill/diff);只用三族字体与字号梯;用圆角梯(无可点击直角、无圆形卡片);用阴影分级而非自定义阴影;所有交互元素有焦点环(ring-1 ring-accent/30);字符串在中英两份 locale 中都存在;无 emoji、无营销文案、无额外运行时表面;无 Agent 切换器、无运行时诊断、无 legacy CodeWhale/Reasonix 导入。

5. 顶层架构:三层分离,谁不做什么

文档给出了四层架构图,三层各自"不做什么"是刻进结构里的三条教训:

┌─────────────────────────────────────────────────────────────┐ │ Renderer (React 19 + Zustand 5) │ │ AppShell → Workbench → (Code with Design tasks | Work | Connect phone) UI│ │ │ │ │ │ window.kunGui.runtimeRequest / startSse │ │ ▼ │ │ Preload (contextBridge, contextIsolated) │ │ kunGui.* IPC surface │ │ │ │ │ ▼ │ │ Main process (Node) │ │ RuntimeHost → kunRuntimeAdapter │ │ Settings / Connect phone runtime / Terminal / Updater / Logger│ │ │ │ │ │ spawn child process + HTTP/SSE │ │ ▼ │ │ Kun (TypeScript package) │ │ serve --host 127.0.0.1 --port 18899 │ │ /health · /v1/* · SSE /v1/threads/{id}/events │ │ cache-first AgentLoop · ports & adapters · append-only log │ │ │ │ │ │ HTTPS to model API │ │ ▼ │ │ DeepSeek (or OpenAI-compatible) chat/completions │ └─────────────────────────────────────────────────────────────┘
  1. 渲染进程只知道 "kun",不知道自己在和哪个运行时说话。切换供应商不是产品表面,而是主进程的关注点。
  2. 主进程不实现 Agent 逻辑。它只负责 spawn 子进程、转发 HTTP、转发 SSE,并拥有 GUI 专属服务(设置、更新器、Connect phone 运行时、工作区文件、外部编辑器、Work 导出/补全),供渲染进程按需请求。
  3. Kun 就是 Agent。循环、工具宿主、存储、模型客户端、服务器——全在一个进程里,躲在一条 HTTP/SSE 边界后面。

6. 核心运行时 Kun:模块布局与六边形架构

Kun 包(kun/)是唯一活跃的 Agent 运行时:一个 TypeScript ESM 包,自带 HTTP 服务器,在 Electron 应用构建之前先构建。模块布局如下(与文档一致,可由 kun/src 目录结构验证):

kun/src/ cli/ # Command-line entrypoints (serve) contracts/ # Zod schemas and inferred types for HTTP/SSE domain/ # Thread, Turn, Item, Event, Approval, Usage entities ports/ # ModelClient, ToolHost, ThreadStore, SessionStore, # ApprovalGate, EventBus, WorkspaceInspector, Clock adapters/ # DeepSeek-compatible model client, local tool host, # in-memory and file-backed stores, workspace inspector services/ # Thread and turn orchestration services loop/ # Cache-first AgentLoop, InflightTracker, # SteeringQueue, ContextCompactor cache/ # ImmutablePrefix, LRU cache, TTL-LRU cache telemetry/ # Usage counter, cache telemetry server/ # HTTP server, router, auth, SSE, response helpers, # runtime-factory, route handlers prompt/ # System prompt for the Kun identity shared/ # Shared types with the GUI

Kun 按ports & adapters(端口与适配器)组织:

  • contracts/是边界——Zod schema 描述每一个 HTTP/SSE DTO,GUI 通过自己的 mapper(src/renderer/src/agent/kun-contract.ts)间接导入;
  • domain/是实体(Thread、Turn、Item、Event、Approval、Usage),无 I/O;
  • ports/是接口——Agent 循环只认识ModelClient、ToolHost、ThreadStore、SessionStore、ApprovalGate、EventBus、WorkspaceInspector、Clock、IdGenerator,这些接口刻意保持很小;
  • adapters/是具体实现——默认CompatModelClient讲POST {baseUrl}/v1/chat/completions形状,默认LocalToolHost在进程内运行工具并做审批门控;
  • services/是编排——ThreadService与TurnService掌握线程与轮次的生命周期,把存储、模型与工具接在一起;
  • loop/是 Agent 循环,纯编排,只依赖端口;
  • server/是暴露一切的薄 HTTP 传输层。

设计规则:新能力应该落为"新端口 + 新适配器",绝不做成直接伸手进循环的新 server handler——边界就是测试。

7. 缓存优先的 Agent 循环:不可变前缀、Inflight 与压缩

文档中的缓存优先循环是围绕 DeepSeek 原生 cache hit/miss 遥测设计的,其原理在 kun/src/loop 与 kun/src/cache 中有完整实现:

  • 不可变前缀 + sha256 指纹。system prompt、工具 schema、固定约束(pinned constraints)与 few-shots 组成前缀;变更只能走setSystemPrompt、setTools、setPinnedConstraints、setFewShots(见 kun/src/cache/immutable-prefix.ts),这些 setter 会使指纹失效。每个模型步开始时调用verifyImmutablePrefix(见 kun/src/loop/model-step-preparation-service.ts),漂移会立即抛错——保证前缀绝对稳定,是缓存命中率的地基。
  • 追加式会话日志。每一轮是一条 JSONL 流,重放时跳过畸形行但保留其余;索引是原子 JSON 写入。
  • 有界 TTL/LRU 缓存。工具、模型响应、计算出的指纹都显式驱逐。
  • Inflight 跟踪与保证清理。kun/src/loop/inflight-tracker.ts 是 SSE 事件对的权威来源——每个begin对应一个tool_call_started/tool_call_finished对。其run(record, work)先注册 id,执行 work,并在finally中删除 id——即使 abort 也会清理,循环绝不泄漏 id。end()与has()支撑起"一事件必有一配对事件"的可观测性契约。
  • 中途转向。SteeringQueue(kun/src/loop/steering-queue.ts)收集轮次运行期间用户发布的消息,在下一个安全的循环边界注入为用户输入。
  • 上下文压缩。ContextCompactor(kun/src/loop/context-compactor.ts)把长历史折叠成单个compaction项,始终保留不可变前缀中的固定约束。软阈值 16k tokens、硬阈值 24k tokens,阈值来自DEFAULT_CONTEXT_THRESHOLDS与contextCompaction.defaultSoftThreshold/defaultHardThreshold,可按模型上下文画像(contextThresholdsForModel)调整。
  • 工具配对修复。发历史给模型前,Kun 丢弃孤儿tool_result与缺结果的工具调用,避免 400/重试风暴。

缓存命中率用 DeepSeek 原生的prompt_cache_hit_tokens/prompt_cache_miss_tokens字段报告为hit / (hit + miss);兼容字段(cached_tokens、cache_read_input_tokens)仅作回退。文档给出一个健康的温线程应保持 ≥ 90% 命中率,并记录了一次实测:2026-06-02,12 个短轮次温跑命中 94.7%;同一温前缀上 24 个短轮次总体 95.2%,最新一轮 98.1%。

8. HTTP/SSE 表面:认证、路由表与 SSE 协议

Kun 的 HTTP 服务器基于手写Router(支持:id参数)。认证用Authorization: Bearer <runtime-token>,--insecure仅限本地开发。完整的 CLI 选项可见 kun/src/cli/serve.ts 的SERVE_USAGE,其中默认端口定义于 kun/src/cli/cli-options.ts(DEFAULT_SERVE_PORT = 18899,schema 校验端口为 0–65535)。parseServeOptions支持--key=value与--key value两种写法,并按"命令行 > 环境变量(KUN_PORT、KUN_HOST、KUN_DATA_DIR、DEEPSEEK_API_KEY等)> 配置文件 > 默认值"的优先级合并。

路由表(与文档一致,由 server 层实现):

MethodPathPurpose
GET/health免认证健康探针
GET/v1/workspace/status?path=…工作区的 git/branch 状态
GET/v1/threads?include=side列出线程(最新在前;side默认隐藏)
POST/v1/threads创建线程
GET/v1/threads/{id}读取线程 + 轮次
PATCH/v1/threads/{id}更新标题/状态/审批/沙箱/关系
DELETE/v1/threads/{id}删除线程
POST/v1/threads/{id}/forkfork(relation 默认fork,或side)
POST/v1/threads/{id}/turns开始一轮
GET/v1/threads/{id}/turns/{turnId}读取一轮
POST/v1/threads/{id}/turns/{turnId}/steer排队转向文本
POST/v1/threads/{id}/turns/{turnId}/interrupt中止一轮
POST/v1/threads/{id}/compact折叠旧历史
GET/v1/threads/{id}/events?since_seq=NSSE 积压 + 实时事件
POST/v1/approvals/{id}allow / deny
POST/v1/user-inputs/{id}与/v1/user-input/{id}提交 / 取消用户输入回答
POST/v1/sessions/{id}/resume-thread将会话恢复进线程
GET/v1/usage累计 token / cache / 轮次计数器

SSE 帧格式:id: <seq>、event: <kind>、JSONdata:。晚加入的客户端传since_seq(或Last-Event-ID),先收积压再收实时事件;每 15 秒一条心跳保持空闲代理存活。事件对的权威来源正是第 7 节的InflightTracker。

9. 线程记录与关系:primary / fork / side

每个线程持久化在{data-dir}/threads/{id}/thread.json,携带relation元数据:

  • primary——顶层线程(默认);
  • fork——手动 fork,把用户切换到新线程;
  • side——继承自父快照的"顺带"侧对话。默认不出现在线程列表,需?include=side才显示;带parentThreadId,提升回primary时清除。

fork与side谱系还记录forkedFromThreadId、forkedFromTitle、forkedAt以及 fork 时的消息/轮次计数,GUI 在侧边栏中呈现这些信息。

10. 审批与沙箱:两层门控与模式限定

ToolHostContext携带approvalPolicy,工具宿主在两层门控:policy: 'never'直接前置拦截;on-request/suggest/untrusted总是提示,除非调用在allowList中。需要限定模式(mode)的工具(如create_plan只在plan线程内可用)声明shouldAdvertise(ctx)谓词,同时过滤工具列表与执行。

SandboxMode(read-only/workspace-write/danger-full-access/external-sandbox)由工作区检查器与文件/工具适配器强制执行。对应的 CLI 参数在SERVE_USAGE中:--approval-policy <p>(on-request | untrusted | never | auto | suggest)、--sandbox-mode <mode>、--approval-reviewer <r>(user | agent)。

11. 持久化:--data-dir与原子写入

--data-dir是运行时拥有的一切的磁盘根目录(必填,缺省时serve直接报错退出码 78,见 kun/src/cli/serve.ts 的parseServeOptionsSafe):

{data-dir}/ threads/ index.json {threadId}/ thread.json # ThreadRecord messages.jsonl # TurnItem append-only events.jsonl # RuntimeEvent append-only session.json # latest AgentSession projection

index.json、thread.json、session.json使用原子 JSON 写入;JSONL 流容忍畸形行(下次重放跳过)。此外serve还支持--storage-backend hybrid|file与--sqlite-path切换混合存储后端,以及--observability系列参数(JSONL 或 OTLP HTTP/JSON 导出器)输出脱敏的 OpenTelemetry 风格 Agent span。

12. 结语:一份"既规范又描述实现"的权威文档

Kun 的 docs/design/zh-CN/foundations-and-runtime.md 的特殊之处在于:它既是设计规范(YAML 令牌 + 视觉规则 + on-brand 检查表),又是运行时架构文档(模块布局、六边形边界、缓存优先循环、路由表、持久化布局),且与 kun/src 源码一一对应。开发者若想深入,可以从 kun/src/cli/serve.ts(CLI 与参数解析)、kun/src/loop/inflight-tracker.ts(SSE 事件配对契约)、kun/src/cache/immutable-prefix.ts(缓存命中率地基)与 kun/src/loop/context-compactor.ts(上下文压缩)四条路径切入,结合kun serve的SERVE_USAGE与DEFAULT_SERVE_PORT = 18899,即可在本地复现文档描述的完整运行时。

  • 人工智能
  • AI Agent
  • 自主智能体
  • 桌面应用
  • MCP Clients

【免费下载链接】Kun

Local-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.

项目地址:https://gitcode.com/gh_mirrors/de/Kun
点击查看免费下载

相关推荐

上一篇:ao doctor 健康检查命令全解析:用 agent-orchestrator 排查 AO 环境配置问题
下一篇:Bunyan无阻塞日志写入:Node.js事件循环优化

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询