news 2026/9/19 19:13:12

gbrain 设计系统解析:从 Voice 规则、设计 Token 到服务端 SVG 图表的完整设计规范

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gbrain 设计系统解析:从 Voice 规则、设计 Token 到服务端 SVG 图表的完整设计规范

gbrain 设计系统解析:从 Voice 规则、设计 Token 到服务端 SVG 图表的完整设计规范

【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain

gbrain 的DESIGN.md是管理后台(admin SPA)与校准(Calibration)体系的设计系统事实来源(source of truth),它诞生于 v0.26.0 admin SPA 工作中沉淀下来的事实 Token,并在 v0.36.1.0 Hindsight 校准波次的设计评审中被正式化。本文以该文档为骨架,结合仓库源码与测试,完整拆解 gbrain 的语音(Voice)规则、颜色/字体/间距 Token、布局约束、服务端渲染 SVG 图表的 XSS 防护姿态,以及如何在新增 UI 时正确使用这份规范。

文档定位:一切 UI 问题的校准目标

DESIGN.md在仓库中的作用非常明确:它是/plan-design-review/design-review流程的校准目标。当出现"这个 UI 是否符合系统风格"的疑问时,答案就在这里,而不是散落在各个页面组件里。文档开篇即说明其来源:

  • v0.26.0 期间 admin SPA 工作时,设计 Token 以事实(de facto)形态落在 admin/src/index.css 的:root变量中;
  • v0.36.1.0 Hindsight 校准波次的设计评审(design review)中,这些事实 Token 被正式整理为文档;
  • 此后该文档成为所有 UI 变更评审的"靶子"(calibration target)。

这一"先有事实代码、后有规范文档"的演进路径意味着:文档中的每一个 Token 都可以在源码中找到对应实现,两者必须保持同步。

Voice:像懂你过去的聪明朋友,而不是临床评分系统

gbrain 对用户可见文案有一个统一过滤器:所有用户可见字符串都必须以"懂你的聪明朋友"的口吻表达,而不是临床式的评分系统。这体现在五个具体规则上:

  1. 第二人称,允许缩写——用 "you / your",允许 "you're / it's";
  2. 落地于用户可验证的具体数据——"2 of 3 missed" 胜过 "Brier 0.31";
  3. 绝不居高临下——禁止 "we recommend"、"according to your data" 这类措辞;
  4. ——叙述性文字 25 词以内,状态类文字一行以内;
  5. 数字必须翻译成真实结果——不能抛出未经翻译的抽象指标。

五个使用该 Voice 的 UI 表面(v0.36.1.0+)

表面(Surface)用途
pattern_statement校准画像中的模式陈述,复盘你在某领域的历史表现
nudge同步提交 take 后触发的实时轻推
forecast_blurb新 take 上的内联预测短句
dashboard_caption仪表盘图表标题
morning_pulse每日早间脉搏一行

gateVoice():单一入口、五表面共用

所有五个表面都通过 src/core/calibration/voice-gate.ts 中的gateVoice()单一函数把关。设计决策(源码注释中标注为 D24)是:五个表面共享一个 gate,模式相关的微调放在 gate 下发给评判模型的 rubric 里,而不是 fork 出多个 gate 实现——fork 会让 voice 规范漂移(改了一个表面,漏了另外四个)。

gateVoice()的核心接口如下:

export interface VoiceGateOpts<S> { mode: VoiceGateMode; // 表面类型,驱动 rubric 微调 generate: VoiceGateGenerator; // 每次生成一个候选字符串 templateFallback: { fn: VoiceGateTemplate<S>; slots: S }; // 兜底模板 maxAttempts?: number; // 默认 2(D11 决策) judge?: VoiceGateJudge; // 测试注入桩;生产用 Haiku rubric?: string; // 按模式覆盖 rubric(很少用) }

执行流程(voice-gate.ts):

  1. 调用generate()生成一个候选字符串;
  2. 由 Haiku 评判模型根据该模式的 rubric 判定conversational(通过)或academic(驳回),并附上不超过 80 字符的理由;
  3. 若驳回,最多重试maxAttempts(默认 2)次,每次把上一条驳回理由作为feedback传给生成器,引导下一次生成避开失败模式;
  4. 若两次均失败(或生成器抛异常、输出为空),回退到 src/core/calibration/templates.ts 中的手写模板,绝不静默隐藏表面——那样会让 voice 质量无声劣化。

每个模式的 rubric 也定义在 voice-gate.ts 中(DEFAULT_RUBRICS),例如nudge模式要求"像朋友拍你肩膀,而不是警报系统""始终以具体下一步收尾(CLI 命令或提问)""30 词以内,绝不居高临下";dashboard_caption则要求"每个标题一句、只陈述一个具体事实、禁止营销腔"。

手写模板回退:可预测输出胜过语音质量轮盘

当两个候选都被驳回时,templates.ts 提供确定性回退。源码注释(D11,CEO review 决策)说明:预测性输出胜过语音质量轮盘——回退模板刻意听起来"有点机械"(可接受,因为用户在双次重生成失败时看到的是相同的形状,而不是随机的质量退化)。真实会话感来自 LLM 路径,模板只是安全网。

例如patternStatementTemplate

export function patternStatementTemplate(s: PatternStatementSlots): string { const total = s.nRight + s.nWrong; if (total === 0) { return `Not enough resolved ${s.domain} calls yet to spot a pattern.`; } const direction = s.direction ?? (s.nWrong > s.nRight ? 'mixed' : 'mostly right'); return `Your ${s.domain} calls have a ${direction} record — ${s.nRight} of ${total} held up.`; }

注意它遵守了 Voice 规则——"nRight of total held up" 是可验证的具体数字,而不是抽象 Brier 值。nudgeTemplate还有一个重要的历史修正(issue #3697):曾引导用户执行不存在的gbrain takes nudge --hush <pattern>子命令,现已改为说明 14 天自动静默机制(fireNudge写入take_nudge_log,冷却探针按(take_id, pattern)抑制重复)。

模板与模式之间存在契约约束:VOICE_GATE_MODES常量(templates.ts)固定了五种模式,测试套件以此校验"每个 Mode 必须有对应模板条目"(模式对等性)。

评判模型与测试接缝

生产环境的评判走gatewayChat调用,使用TIER_DEFAULTS.utility档位模型(Haiku)、maxTokens: 100;判定输出是 JSON:{"verdict":"conversational"|"academic","reason":"…"}parseJudgeOutput()对结果做了健壮性处理:容忍代码围栏包裹与前置散文,解析失败一律按academic处理(reason=parse_failed),从而走模板回退而不是放行劣质 voice。

测试接缝是opts.judge——测试注入一个返回 verdict + reason 的桩函数,使 gate 可以完全在密闭环境(hermetically)运行,无需真实模型调用。这也是gateVoice的通用性体现:生成与评判分离,调用方只需提供generatetemplateFallback

颜色 Token:暗色主题是唯一主题

颜色 Token 定义在 admin/src/index.css 的:root中,SVG 渲染器在 src/core/calibration/svg-renderer.ts 中内联了与之一致的字面量(必须同步)。

Token用途
--bg-primary#0a0a0f页面背景
--bg-secondary#14141f侧边栏、卡片
--bg-tertiary#1e1e2e次级表面、边框
--text-primary#e0e0e0正文
--text-secondary#888标题、标签
--text-muted#777三级文本——TD2 从#555提升而来,为达 WCAG AA 对比度(约 5.5:1)
--accent#3b82f6激活态、链接、主 CTA
--success#22c55e健康 / 正常状态
--warning#f59e0bDoctor 警告
--error#ef4444失败、破坏性确认

暗色主题与 WCAG 对比度

admin 是仅暗色主题,无亮色模式切换计划——因为 admin 是运维工具而非营销页面,用户本就长期在终端暗色环境中工作。源码注释记录了一次关键的可达性修复(v0.36.1.0 TD2):--text-muted#555提升到#777,对比度从 4.0(低于 WCAG AA 对正文要求的 4.5)提升到约 5.5,通过 AA。该改动全局作用于 Dashboard、Agents、RequestLog 与新增的 Calibration 页。

文档给出的完整对比度核算:

  • 正文#e0e0e0#0a0a0f上 → 约 14:1,达 AAA;
  • 三级文本#777#0a0a0f上 → 约 5.5:1,达 AA(修复前 4.0 / 不达标);
  • 强调链接#3b82f6#0a0a0f上 → 约 5.7:1,达 AA。

Token 的实际使用方式

index.css 中 Token 被大量用于语义化类:.nav-item.activeborder-left-color: var(--accent)标记激活项;.metric-value使用var(--font-mono)渲染数字;.badge-read/.badge-write/.badge-admin/.badge-success/.badge-error用 15% 透明度的同色系底色加前景色构成徽章;.status-active/.status-warning/.status-inactive用状态点表达健康状态;.warning-barrgba(245,158,11,0.15)底色 +var(--warning)边框呈现告警条。这些模式共同构成了"暗色 + 语义色"的视觉语言。

排版:Inter 负责 UI,JetBrains Mono 负责数字

变量用途
--font-sansInter, system-ui, sans-serifUI 文本、标题、正文
--font-monoJetBrains Mono, monospace数字、slug、代码、终端风格数据

类型字号刻度目前仍是事实标准(de facto,尚未正式化):

  • 18px:侧边栏 Logo / 页面标题;
  • 14px:正文;
  • 13px:导航项;
  • 12px:图表标题、次级标签;
  • 11px:高密度图表中的三级标签。

关键规则:表格与指标中的数字必须用 JetBrains Mono,这样列对齐是机械性的(等宽字体天然对齐);同时避免在同一行内混排 Inter 与 JetBrains Mono。在 index.css 中可以看到具体落地——.metric-value以 28px 等宽字体渲染核心指标,表格th用 11px 大写字母 + 0.5px 字距的 muted 色。

间距与密度:4 / 8 / 16 / 24 / 32 刻度

间距采用 4 的倍数刻度:4 / 8 / 16 / 24 / 32px。密度风格是 Linear-app 式:主区块之间 24–32px,行组之间 16px,行内 8px。文档指定Calibration 页(已批准的 variant-B 线框)是这一密度的典范示例——从 Calibration.tsx 的实现看,页面用padding: 32、章节间marginBottom: 32、标题下方marginBottom: 8~24,与刻度严格对应。

布局:侧边栏 + 内容区 + 内容宽度上限

  • 左侧 200px 侧边栏;激活项以--accent色 3px 左描边标记(见 index.css 的.nav-item.active);
  • 主内容区占据剩余宽度;
  • 文本密集型页面(Calibration)最大内容宽度 720px,数据表格页面(Request Log)最大 960px;
  • 禁止三列特性网格、彩色圆圈图标、装饰性 blob;
  • 卡片必须"配得上存在"——大多数场景下"标题 + 内容"直接呈现即可,无需卡片边框包装。

侧边栏结构可在 App.tsx 中直接看到:sidebar-logo(GBrain)+sidebar-nav(Dashboard / Agents / Request Log / Calibration / Jobs Watch 五个导航项)+ 底部 "Sign out everywhere" 按钮,主区根据 hash 路由渲染对应页面。移动端(≤768px)侧边栏隐藏、主区 padding 收窄,这是布局规则对响应式的补充。

图表:服务端渲染 SVG,纯函数,零图表库

gbrain 的图表架构是本文档最具技术特色的部分:由服务端渲染 SVG,通过 src/core/calibration/svg-renderer.ts 中的纯函数实现(数据 → SVG 字符串),无 DOM、无 React 组件、无图表库。选择该架构的理由(设计文档中标注为 D23):

  • 图表逻辑贴近数据计算(chart logic stays close to the data math);
  • 零新增客户端图表库依赖;
  • SVG 可访问(含文本标签)、可缩放、可直接复制粘贴进 PR 描述与文档;
  • 为未来的 admin 图表(contradictions trend、takes scorecard 等)确立了先例。

四个图表渲染器(v0.36.1.0)

渲染器输出
renderBrierTrend({ series })迷你趋势线 + 0.25 基线参考线(Brier 0.25 是"始终 50% 下注"的基准)
renderDomainBars({ bars })按领域横向准确率条
renderAbandonedThreadsCard(threads)文本行 + "revisit now" 链接
renderPatternStatementsCard(statements)可点击下钻锚点

各渲染器的实现细节值得注意:

  • renderBrierTrend(svg-renderer.ts):默认 600×180,y 轴固定 [0, 0.4](0 = 完美,0.25 = 50% 基线),0.25 处以虚线stroke-dasharray="2,3"绘制基线,折线用--accent色;空数据时渲染svgEmpty()提示文案("No Brier-trend data yet (need 5+ resolved takes)");
  • renderDomainBars(L137-L165):每行 28px 高,条宽按accuracy钳制在 [0,1],右侧标注accuracy% · n=样本量
  • renderAbandonedThreadsCard(L180-L207):声明文本超过 70 字符截断加省略号(服务端无法测量文本宽度),每行带 conviction、静默月数及默认指向/admin/calibration/revisit/<takeId>的 "revisit now" 链接;
  • renderPatternStatementsCard(L217-L238):90 字符截断,锚点默认指向/admin/calibration/pattern/<index>支持点击下钻。

XSS 防护姿态

由于 SVG 通过dangerouslySetInnerHTML注入 admin SPA,安全姿态是三层防御(svg-renderer.ts 与 Calibration.tsx 均有注释说明):

  1. 服务端转义:所有调用方可控字符串经escapeXml()(转义& < > " ')后才进入 SVG;
  2. 数值强转:数字输入统一.toFixed()强制转换;
  3. 端点鉴权:SVG 端点由requireAdmin中间件门控,admin SPA 通过TrustedSVG包装器渲染。

admin 端ChartSvg组件通过api.calibrationChart(type)拉取image/svg+xml,加载中显示ariaLabel + "loading...",出错则渲染role="alert"的错误块——这正好呼应下文"加载态/错误态"的交互规范。

Calibration 页的空状态即特性

Calibration.tsx 是空状态设计的教科书实现:当还没有校准画像时,页面不是显示 "no data available",而是给出具体的下一步——"No calibration profile yet. Builds after 5+ resolved takes.",并直接内联一段可复制的命令gbrain dream --phase calibration_profile,告诉用户如何构建画像。这正是 DESIGN.md 中"空状态 IS 特性:温暖 + 主行动 + 上下文"规则的最佳示例。

交互模式

  • 键盘导航是 CLI 交互表面的硬性要求:propose-queue 评审使用 J/K/空格/u/q 快捷键(gmail 风格);
  • 加载态:显示 "Loading...";200ms 以内的操作不显示 spinner;
  • 错误态:说出失败对象 + 给出下一步,绝不写 "an error occurred — please try again"。

路线图:v0.37+ 还未落地的部分

文档如实列出了尚未完成的部分,避免将现状当作最终形态:

  • 类型字号刻度的正式化(当前值为事实标准,未强制);
  • 动画 Token(admin SPA 目前刻意零动画,v0.37 可能增加细微的进度/加载过渡);
  • 打印样式表;
  • 亮色模式(未计划——见上文"暗色主题是唯一主题");
  • 组件库抽取(React 组件目前内联在admin/src/pages/下,尚无<Button>/<Card>抽象层)。

如何使用这份文档:新增 UI 的四步检查

当为 gbrain 新增 UI 表面时,文档给出明确的四条纪律:

  1. 先复用现有 Token,再谈新 Token——新 Token 必须走/plan-design-review评审;
  2. 匹配 Voice 规则——校准表面的任何用户可见字符串上线前都要过gateVoice()
  3. 匹配间距刻度与密度——"Linear 式的平静清晰"优先于"仪表盘卡片马赛克";
  4. 匹配排版——Inter 用于 UI,JetBrains Mono 用于数字。

文档本身也强调它是一个活的目标(living target)而非冻结规格:重大变更需要经过/plan-design-review以保持系统整体一致。这与仓库中 docs/designs 目录下的设计提案文档互为表里——前者沉淀已落地的设计决策,后者承载进行中的设计探讨。

小结

gbrain 的DESIGN.md用一份精炼文档同时锁定了"怎么说"(Voice 规则与gateVoice()流水线)、"长什么样"(颜色/字体/间距/布局 Token)、"怎么画图"(服务端 SVG 纯函数 + XSS 三层防护)和"怎么演进"(评审流程 + 路线图)。它不是抽象的视觉规范,而是与 admin/src/index.css、src/core/calibration/voice-gate.ts、src/core/calibration/svg-renderer.ts、src/core/calibration/templates.ts、admin/src/pages/Calibration.tsx 一一对应的可执行规范——任何"这 UI 是否符合系统"的疑问,都能在这份文档及其源码落地点中找到答案。

【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 19:12:52

STM32+ESP8266通过AT指令稳定接入OneNet MQTT实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 19:12:45

通达信麟龙四量图指标:多周期均线共振原理与实战过滤技巧

简介&#xff1a;这是一份CSDN下载频道提供的麟龙四量图通达信指标公式源码解析文档&#xff0c;面向股票技术分析爱好者&#xff0c;尤其是使用通达信软件、希望深入了解四量图指标构成与用法的投资者。文档为单个doc文件&#xff0c;压缩包仅196KB&#xff0c;轻量便携&#…

作者头像 李华
网站建设 2026/9/19 19:12:33

API 报错 401?TaoToken + Continue 这样验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 19:09:04

Ubuntu 20.04安装PyCharm快速配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 19:08:25

BIOS设置详解:从开机自检到U盘启动、TPM与来电自启实操指南

不知道你有没有遇到过这样的场景&#xff1a;辛辛苦苦做好了U盘启动盘&#xff0c;插到电脑上开机&#xff0c;结果屏幕一闪&#xff0c;还是老老实实进了Windows。去网上搜“BIOS设置U盘启动”&#xff0c;跟着教程点了半天&#xff0c;发现自己的BIOS界面跟教程里长得完全不一…

作者头像 李华
网站建设 2026/9/19 19:08:10

OpenCV安装全攻略:pip、离线、源码编译到CUDA加速

先聊个反直觉的事&#xff1a;OpenCV的安装包&#xff0c;恰恰是整个OpenCV学习路上最不值得你花时间找的东西。我做过不少图像处理项目&#xff0c;也带过新人&#xff0c;几乎每周都能在群里看到有人问“谁有OpenCV安装包”&#xff0c;然后下载下来一个来路不明的压缩包&…

作者头像 李华