LobeHub 仓库开发指南解读:面向 AI 编码 Agent 的架构约定、命令工作流与 Skill 体系
2026/9/8 17:25:57 网站建设 项目流程

LobeHub 仓库开发指南解读:面向 AI 编码 Agent 的架构约定、命令工作流与 Skill 体系

【免费下载链接】lobehub🤯 LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub

导读

LobeHub 是一个将 AI 团队编排为 7×24 小时自动化运营的 Agent 平台,其开源仓库规模庞大(src/features/下数千个文件、apps/packages/承载桌面端、CLI、服务端与共享包)。为了让人类开发者与 AI 编码 Agent 在同一套约束下高效协作,仓库根目录的 AGENTS.md 定义了一套仓库级的开发宪章:它规定了技术栈、目录分层、SPA 路由拆分方式、开发命令、Git 工作流、质量检查与 i18n 流程。阅读本文后,你将掌握 LobeHub 仓库的分层架构心智模型、可复现的本地开发与质量验证命令,以及"仓库级规则 + Skill 级细节"的 Agent 协作范式。

AGENTS.md 在仓库中的定位:规则单一事实源

在 LobeHub 中,AGENTS.md 并不是一份摆设,它是"为在本开源仓库中工作的 AI 编码 Agent 准备的开发准则"(文档自述Guidelines for using AI coding agents in this opensource LobeHub repository)。它与根目录的 CLAUDE.md 一类文档共同构成了 Agent 的上下文入口,但分工明确:

AGENTS.md 拥有仓库级(repository-wide)的架构与工作流定义;详细的实现规则下沉到 skills 中,让每个规则只有一处事实来源。

也就是说,AGENTS.md 只回答"仓库长什么样、规则是什么、命令怎么跑",而"怎么写一个符合规范的 React 组件、怎么拆分重领域页面"这类具体实现细节,被收敛到.agents/skills/目录下独立的 skill 文件中。仓库中实际维护着 60+ 个 skill(如reactcompose-atomsspa-routesdeep-reviewzustandtrpc-router等),每个 skill 都自带 front-matter(name/description),description 明确描述了该 skill 的适用触发场景,方便 Agent 按需检索加载。这种"顶层少而稳、细节多而专"的分层,正是该仓库 Agent 协作体系的核心设计。

技术栈一览:一份可验证的选型清单

AGENTS.md 开篇即给出技术栈速览,而这些声明都能在仓库中逐一印证:

关注点选型仓库佐证
框架与语言Next.js + React + TypeScriptpackage.json 根依赖
前端形态Next.js 内部承载 SPA,路由由react-router-dom负责src/spa/router
UI 实现@lobehub/ui、antd、antd-stylereact skill 中组件选型优先级
国际化react-i18nextpackages/locales/src/default 下的 namespace 文件
状态管理zustandsrc/store
数据请求 / 类型安全后端SWR + TRPCsrc/services
ORM / 测试Drizzle ORM + PostgreSQL;Vitestpackages/database、各包vitest.config.mts

这套选型的核心意图是类型安全贯穿前后端:TRPC 提供端到端类型安全的 RPC 边界,Drizzle ORM 让数据库 schema 与代码保持同构,Vitest 则支撑起从单测到回归测试的统一验证。

Agent Skills 体系:何时必须"先读再改"

AGENTS.md 明确要求,在改动特定类型代码前必须先读取对应 skill,避免 Agent 凭泛化经验行事:

  • React 与 TSX:在编辑组件、组件状态、渲染边界或做 memoization 优化之前,必须先读 .agents/skills/react/SKILL.md。该 skill 拥有组件选型、样式、状态局部化与渲染性能规则的"所有权"。
  • 重领域功能:当需要把一个臃肿的 Viewer/Page 拆成可复用的片段(page、portal、share、micro-app 等宿主)时,先读 .agents/skills/compose-atoms/SKILL.md。它的拆分原则是"按可挂载能力拆分,而不是按视觉区块拆分",并且不得用readOnly/mode标志去隐藏未使用的工作——因为被隐藏的模块仍然会随宿主被导入并打包。

以 react skill 为例,其 组件优先级 是:src/components项目内组件 →@lobehub/ui/base-ui无头原语(若有同名根导出,禁止绕道 import 根导出)→@lobehub/ui根导出 → antd → 自定义实现(最后手段)。它还特别提醒一个常见坑:import { Select } from '@lobehub/ui'表面正常,实际拿到的是 antd 背书的 Select,应改用 base-ui。

compose-atoms skill 则提出了"模块图拆分"(module-graph split)的判据:一个 atom 是"宿主被允许不挂载的最小单元"。判断粒度时自问"是否会有某个宿主想要其余部分却跳过这一块?"如果是,它就该是 atom;如果否,就留在父组件里。其状态下沉原则(sink state)强调:imports follow the hook——如果useStore/handleAccept还留在页面装配器上,那么该模块及其全部依赖仍会被每个挂载此页面的宿主打包带走。需要强调的是,若只是把单个组件切成更小的文件,不应使用该 skill,而应回归 react skill。

目录结构:四层清晰的职责划分

AGENTS.md 给出了仓库级目录地图(节选自其 Project Structure),可归纳为四个层次:

lobehub/ ├── apps/ # 可独立运行的端 │ ├── desktop/ # Electron 桌面应用 │ ├── cli/ # LobeHub CLI │ └── server/ # 后端服务(Hono 应用 + 服务端路由/服务) ├── packages/ # 共享包(@lobechat/*) │ ├── database/ # 数据库 schema、模型、仓储 │ ├── agent-runtime/ # Agent 运行时 │ ├── locales/ # i18n 源:packages/locales/src/default/ │ ├── env/ # env schema(@/envs/* 指向 packages/env/src/*) │ └── ... ├── src/ # Web 应用壳层 │ ├── app/ # Next.js App Router(路由壳 + 鉴权) │ ├── routes/ # SPA 页面段(薄层,委托给 features) │ ├── spa/ # SPA 入口与路由配置 │ ├── store/ # Zustand stores │ ├── services/ # 客户端服务 │ ├── libs/ # 应用壳共享的客户端/服务端助手 │ └── ... └── e2e/ # E2E 测试(Cucumber + Playwright)

需要特别留意的是src/app/src/的分工。前端业务并不全部走 Next.js 的页面路由,而是采用Next.js 承载 SPA的混合形态:src/app/(backend)只放后端路由壳,src/app/spa/负责 SPA 的 HTML 模板服务,src/app/spa-auth/提供 SSR 的鉴权 HTML 壳。真正的 SPA 页面段在src/routes/,业务逻辑在src/features/

SPA 路由架构:roots vs features 的拆分纪律

这是 AGENTS.md 着墨最深、也是本次解读最值得展开的架构章节。LobeHub 明确采用roots vs features拆分:路由树只放页面段,业务逻辑与 UI 全部落在 features 中。要理解这一拆分,需先认识三个目录各自的"被允许内容":

src/spa/:SPA 入口与路由配置

src/spa 存放 SPA 入口文件(entry.web.tsxentry.mobile.tsxentry.desktop.tsxentry.popup.tsx,另有entry.auth.tsx)以及 React Router 配置目录 src/spa/router。路由配置放在入口旁,正是为了避免与src/routes/混淆。router 目录中除了各平台的desktopRouter.config.*mobileRouter.config.tsxpopupRouter.config.tsx,还包含运行时支撑:routePreloadRegistry.ts(路由预加载注册表)、useRouteSkeleton.ts(路由骨架屏)与tabRouter.tsx(Electron 多标签的内存路由)。

src/routes/:只允许薄页面段

src/routes/(roots)下仅允许三类文件:

  • _layout/index.tsxlayout.tsx:该段的布局(配合<Outlet />);
  • index.tsxpage.tsx:该段页面入口;
  • [param]/index.tsx(如[id][cronId]):动态段页面。

这些文件必须保持薄:只能从@/features/*import 并做组合,不允许携带业务逻辑或重型 UI。仓库实际分组与 AGENTS.md 描述一致:src/routes 下存在(main)(mobile)(desktop)(popup)以及auth/onboarding/等特殊流目录。

src/features/:按领域的业务组件

业务组件按领域(domain)组织(如PagesHomePageEditor),而非按路由路径组织。布局块(sidebar、header、body)、hooks、领域特有 UI 都放在这里,每个 feature 通过index.ts(或index.tsx)暴露清晰的公开导出。由于一个路由可使用多个 feature,一个 feature 也可被多个路由复用,因此不允许在src/routes/内新建features/文件夹

新增/变更 SPA 路由的标准流程

AGENTS.md 给出了四条操作步骤,结合 spa-routes skill 可以还原为完整动作:

  1. src/routes/中只添加委托给 features 的路由段文件(layout + page);
  2. src/features/<Domain>/下实现布局与页面内容并从该目录导出;
  3. 路由文件中用import { X } from '@/features/<Domain>'(或import Y from '@/features/<Domain>/...')引入;
  4. 共享的桌面内容路由只注册一次:公共 Web/Electron 路径、嵌套、metadata、懒加载器与preloadId值都放在 src/spa/router/desktopRouter.shared.tsx。

在此基础上,薄的 desktopRouter.config.tsx 与desktopRouter.config.desktop.tsx只承载运行时差异:Web 直接挂载内容树,而 Electron 保留精简根桩,并通过 tabRouter.tsx 在每个标签页的内存 router 中挂载同一棵树。只有路由真正与平台相关时,才把代码放进平台适配器。由 desktopRouter.sync.test.tsx 守护这一共享行为与显式差异——修改路由时保持该测试通过。

从设计动机看,这套"薄 roots + 厚 features + 单一共享桌面路由"约束,本质上是为了让页面段只承担组合职责:任何新增页面都无需复制逻辑,也避免了同一段路由在 Web 与 Electron 两套配置中重复维护导致漂移。

启动开发环境:三套命令与 Debug Proxy 原理

AGENTS.md 给出了三种启动方式,按需选择:

# SPA dev 模式(纯前端,API 代理到 localhost:3010) bun run dev:spa # 全栈开发(Next.js + Vite SPA 并行) bun run dev # 独立 Hono 后端服务 pnpm --filter @lobechat/server dev
  • dev:spa在根 package.json 中定义为vite,即直接启动 Vite dev server 作为纯前端;同一脚本族还有dev:spa:authdev:spa:mobile等变体,通过环境变量切换形态。
  • dev定义为tsx scripts/devStartupSequence.mts,由 scripts/devStartupSequence.mts 编排 Next.js 与 Vite SPA 的并行启动。
  • 后端独立运行时走 pnpm workspace filter,指向apps/server@lobechat/server),其运行时代码都位于apps/server/src,通过@/server/*导入。

值得展开的是Debug Proxy机制。dev:spa启动后,终端会打印一条形如下面的 URL:

Debug Proxy: https://app.lobehub.com/_dangerous_local_dev_proxy?debug-host=http%3A%2F%2Flocalhost%3A9876

这条 URL 对应仓库中的 public/_dangerous_local_dev_proxy.html:该页面从查询参数读取debug-host(默认回退到http://localhost:9876),并通过sessionStorage记住调试目标。打开此 URL 后,线上环境(app.lobehub.com)会把你的本地 Vite dev server 的 SPA 加载进在线页面,从而让你带着真实的服务器配置获得 HMR——即"用本地代码开发、用线上后端调试"。

后端架构约束:业务代码不进路由壳

AGENTS.md 对后端代码放置有三条硬约束:

  • 后端运行时代码位于apps/server/src,通过@/server/*导入;
  • src/app/(backend)只放 Next.js 路由壳,不得在其中添加后端业务逻辑;
  • Web 壳层的辅助代码属于src/libs/*或相应的src/app段,而不是src/server

换言之,Next.js 在这里扮演的是"接线员"而非"业务宿主":路由壳只负责把 HTTP 请求转交给apps/server中真正的 Hono 服务与 server routers/services。理解这一点对 Agent 尤其重要——否则很容易把业务逻辑写进 App Router 的 route handler,破坏后续将 SPA 与后端分离部署的结构。

Git 工作流与包管理约定

仓库的协作节奏由分支模型与提交规范约束:

  • 分支策略canary是开发分支(对应云端生产);main是发布分支(定期从 canary cherry-pick)。
  • 新分支应从canary创建;PR 应指向canary
  • git pull使用 rebase。
  • 提交信息以 gitmoji 表情前缀开头。
  • 分支格式:<type>/<feature-name>

包管理方面采用双工具分工:pnpm 管依赖,bun 跑 npm scripts,bunx 跑可执行的 npm 包。这与根 package.json 的 scripts 实际定义一致(如"check": "bun run .agents/scripts/check/cli.ts")。配套的 commitlint.config.mjs 与 renovate.json 分别约束提交规范与依赖自动化。

质量检查:bun run check的纪律

AGENTS.md 规定了唯一的质量入口,并反复强调"别乱跑全量测试":

bun run check [changed-files...]

该命令对应根 package.json 中"check": "bun run .agents/scripts/check/cli.ts",实际执行体是 .agents/scripts/check 下的一组脚本(cli.tslint.tscollect.tsexec.tsrouting.ts等),其质量纪律包括:

  • 回归测试是硬要求:每个 bug 修复必须附带一个"修复前失败、修复后通过"的回归测试。唯一豁免是纯样式/CSS 修复(选择器、hover、遮罩、间距、颜色)——此时唯一可行的断言只能是对样式源码做字符串匹配,这种断言不算是值得交付的回归测试,可以跳过。
  • 单次单遍:无选择器时,lint + test应在同一次check中完成,不要为每个选择器分别开一遍。--lint/--test/--type用于收窄范围,且可在一次运行内自由组合。
  • 默认文件集合 = 工作区全部改动(staged + unstaged + untracked);显式传入路径会覆盖默认集合。
  • --lint会自动修复给定文件并把修复内容以 diff 形式打印,方便审查改动。
  • --test会为给定源文件自动发现相关测试,并在最近的所属 vitest 配置下运行(例如packages/database),无需手动cd进包目录。
  • --type运行全量类型检查。
  • 严禁直接bun run test——全量套件需要约 10 分钟。需要手动跑单测(如单个文件或特殊 flag)时,先cd进所属包再执行,例如:cd packages/database && bunx vitest run --silent='passed-only' '[file-path]'

i18n 工作流:人机分工的翻译管线

LobeHub 的国际化采用"源文件 + 两个手写语言 + CI 兜底其余语言"的三段式:

  1. 加 key:在 packages/locales/src/default 下的 namespace 文件中添加(如agent.tsauth.ts)。
  2. 手写 en-US 与 zh-CN:在同一个 PR内完成——先在packages/locales/src/default/*.ts编写英文源,镜像到locales/en-US/,再手工翻译locales/zh-CN/
  3. 其余语言交给 CI:每日 CI 工作流 .github/workflows/auto-i18n.yml 会运行bun run i18n并自动开启翻译 PR。在翻译 PR 合并前,缺失的语言 key 会回退到英文。

只有当"立刻需要"翻译后的语言而非等待每日工作流时,才手动运行bun run i18n(根 package.json 中定义为npm run workflow:i18n && lobe-i18n && prettier -c --write "locales/**")。AGENTS.md 特别强调:该命令很慢且需要OPENAI_API_KEY,且不要手工翻译生成的 locales——因为下一个 CI 周期会覆盖它们。

代码风格与代码审查:给 Agent 与人类的共同尺子

文件尺寸红线

AGENTS.md 建议:单个文件超过约 800 行时,考虑拆分为多个文件(抽取子组件、hooks、helpers 或 types)。理由并非玄学,而是"更小、更聚焦的文件对人类和 Agent 都更友好"——这与compose-atomsreact两个 skill 共同构成了对抗巨型文件的完整方案:react skill 负责把小组件拆小,compose-atoms 负责把重领域按可挂载能力切分。

deep-review skill 与设计价值观

审查 PR / diff / 分支改动之前,应先读deep-reviewskill。普通审查请求使用其轻量模式(一名独立评审者对照各维度的快速检查清单);完整的多子 Agent 深度模式只在显式调用时启用。仓库中可见该 skill 的维度清单,包括逻辑、安全性、性能、可观测性、发布风险、复用架构、AI 编码坏习惯等(见 .agents/skills/deep-review/references/dimensions),且按 reviewer 场景区分 claude-code / codex。

同时,在设计或评审用户可见流程(空态/加载态/错误态、确认、异步反馈、按钮层级、大规模列表、选择器)时,应遵循 LobeHub 的设计价值观Natural / Meaningful / Certainty / Growth(自然 / 意义感 / 确定性 / 成长),完整定义见 DESIGN.md 与配套的 DESIGN.dark.md。这套价值观不只是口号:仓库中 ux skill 对四个维度逐一展开,例如 Growth(生长性)被定位为更长周期的视角,在塑造一个功能如何演进的体验时用来权衡。DESIGN.md 本身则是一份主题化设计规范——主色与中性色均可由用户配置并解析为 CSS 变量(lobe-vars)。

总结:从 AGENTS.md 看 LobeHub 的工程化方法论

纵观全文,AGENTS.md 的价值不在于罗列规则,而在于其分层治理的思路:

  1. 规则有明确的归属层:仓库级架构/工作流留在 AGENTS.md,实现细节下沉到 60+ 个按需加载的 skill,避免上下文膨胀与规则互相打架;
  2. 架构分层服务于"可挂载能力":SPA 采用 Next.js 承载 + roots/features 拆分 + 单一共享桌面路由,使 Web、Electron、移动端、popup 等宿主各取所需;
  3. 验证链路刻意收窄:用bun run check单命令 + 自动发现相关测试替代"全量跑一遍",把 10 分钟的全量套件变成日常开发的禁区;
  4. i18n 采用人机分工:英文与中英双语由开发者手写保证质量,其余语种交给每日 CI 的自动翻译 PR 兜底。

对于要在本仓库中工作的开发者与 Agent 而言,AGENTS.md 就是第一份必读文档——它决定了你在哪个目录放代码、用哪条命令验证、以何种纪律提交。

【免费下载链接】lobehub🤯 LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub

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

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

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

立即咨询