LobeHub 调试日志规范:debug 包的 lobe-* 命名空间、DEBUG 开关与格式说明符详解
本文基于 LobeHub 仓库内的调试技能文档 SKILL.md 展开,完整继承其中的基本用法、命名空间约定、格式说明符与三种运行时(浏览器 / Node.js / Electron)的 DEBUG 开关方式,并结合仓库源码中数百处 debug('lobe-*') 的真实调用,补充说明当前代码库中实际采用的命名空间分布、多级子模块划分与“日志 + 计时”双命名空间等实战模式,帮助你在为 LobeHub 各应用添加可开关的诊断日志时做到风格统一、便于过滤。
基本用法
在 LobeHub 中,诊断日志统一使用 debug 包:导入后以 lobe-[模块]:[子模块] 的格式创建 logger 实例,之后即可直接以函数形式输出日志。
import debug from 'debug';
// 格式:lobe-[模块]:[子模块]
const log = debug('lobe-server:market');
log('Simple message');
log('With variable: %O', object);
log('Formatted number: %d', number);
这一用法在仓库中已被大规模采用。以 Agent Runtime 协调器为例,AgentRuntimeCoordinator.ts 在模块顶层创建单例 logger:
const log = debug('lobe-server:agent-runtime:coordinator');
将 debug() 放在模块顶层、以常量形式导出,是 LobeHub 的固定写法——这样每个文件只解析一次命名空间,且同一子模块在多处文件中的日志可以被同一个 DEBUG 过滤条件统一命中。
命名空间约定
技能文档中给出的基础约定按运行端划分:
| 端 | 命名空间前缀 | 示例 |
|---|---|---|
| Desktop(Electron 桌面端) | lobe-desktop:[module] |
lobe-desktop:chat-terminal |
| Server(服务端) | lobe-server:[module] |
lobe-server:agent-runtime:coordinator |
| Client(浏览器客户端) | lobe-client:[module] |
lobe-client:[module] |
| Router(路由层) | lobe-[type]-router:[module] |
lobe-edge-router:market |
从源码实际使用看,各应用已经演化出一套更大范围的 lobe-* 前缀集合。对当前仓库全部 .ts/.tsx 源码做统计后,使用次数最多的两级前缀包括:
lobe-server:workflows 29 处
lobe-server:messenger 17 处
lobe-server:agent-runtime 16 处
lobe-server:agent 13 处
lobe-server:ai-agent-service 12 处
lobe-image:comfyui 10 处
lobe-server:bot 9 处
lobe-server:agent-signal 6 处
lobe-desktop:chat-terminal 3 处
lobe-chat:service 3 处(历史前缀)
此外还有 lobe-store:*(状态层)、lobe-video:*(视频生成服务)、lobe-trpc:*、lobe-task:*、lobe-usage:* 等前缀。可以推断,仓库的命名空间实践比文档中的四条基础规则更宽泛:以运行端或业务域作为第一级前缀,以功能模块作为后续层级,例如 lobe-store:group-orchestration 表示浏览器状态层中群聊编排逻辑的日志,lobe-video:webhook 表示视频服务的 webhook 回调日志。
命名空间支持任意深度。仓库中最典型的三级、四级用法出现在工作流(Upstash Workflow)体系中,例如 lobe-server:workflows:verify:sweep、lobe-server:workflows:task:on-topic-complete、lobe-server:workflows:agent-signal:nightly-review 等,前两级标明“服务端 + 工作流”,末级标明具体工作流步骤,便于按工作流粒度单独开启调试。
格式说明符
debug 包支持 printf 风格的格式说明符,技能文档明确列出四个常用项:
| 说明符 | 含义 | 适用场景 |
|---|---|---|
%O |
对象展开(推荐用于复杂对象) | 入参、返回体等嵌套结构 |
%o |
对象 | 简单对象 |
%s |
字符串 | 普通文本 |
%d |
数字 | 数量、状态码、耗时 |
文档建议:打印复杂对象时优先使用 %O 以获得展开输出。这与源码中的实际写法一致。技能文档给出的示例:
// apps/server/src/routers/edge/market/index.ts
import debug from 'debug';
const log = debug('lobe-edge-router:market');
log('getAgent input: %O', input);
需要注意:该示例引用的 apps/server/src/routers/edge/market/index.ts 在当前仓库布局中已不存在(路由层已迁移为 router-hono 结构),但示例本身的写法仍是标准范式。当前等价写法可参考 botCallback.ts:
const log = debug('lobe-server:agent:bot-callback');
启用调试输出
debug 包默认静默,只有命中过滤条件时才输出。LobeHub 的日志几乎都以 lobe- 开头,因此一条 lobe-* 即可打开全局调试。技能文档给出三种运行环境的开启方式:
浏览器
在 DevTools Console 中设置:
localStorage.debug = 'lobe-*';
之后刷新页面,所有命中 lobe-* 的客户端日志(如 lobe-store:*、lobe-client:*)都会输出到 Console。
Node.js
通过环境变量 DEBUG 控制,在启动命令前缀中设置:
DEBUG=lobe-* npm run dev
DEBUG=lobe-* pnpm dev
LobeHub 是 pnpm monorepo,服务端开发一般使用 pnpm dev;如需只观察某个模块,可把过滤条件收窄,例如 DEBUG='lobe-server:agent-runtime:*' 只开启 Agent Runtime 相关日志,减少输出噪音。
Electron
桌面端主进程通过 process.env.DEBUG 注入:
process.env.DEBUG = 'lobe-*';
桌面端的渲染进程与浏览器端一致,可用 localStorage.debug 覆盖。
源码实证:Agent Runtime 中的日志组织方式
结合 AgentRuntime 模块 的源码,可以看到 LobeHub 在真实业务中如何组织调试日志:
-
每个核心组件一个末级子模块。AgentStateManager.ts 使用
lobe-server:agent-runtime:agent-state-manager,GatewayStreamNotifier.ts 使用lobe-server:agent-runtime:gateway-notifier,factory.ts 使用lobe-server:agent-runtime:factory。这样DEBUG='lobe-server:agent-runtime:*'可整体打开,而DEBUG='lobe-server:agent-runtime:redis'能单独聚焦 redis.ts 中的缓存交互日志。 -
“功能日志 + 计时日志”双命名空间模式。多个文件同时创建两个 logger:一个记录业务事件,一个专门记录耗时与时序。例如 StreamEventManager.ts:
const log = debug('lobe-server:agent-runtime:stream-event-manager'); const timing = debug('lobe-server:agent-runtime:timing');同样的
lobe-server:agent-runtime:timing命名空间也出现在 executorHelpers.ts 与 redis.ts 中。由于debug的过滤是按前缀匹配的,多个文件共享同一个:timing末级子模块,使得“只看性能计时日志”成为可能:DEBUG='lobe-server:agent-runtime:timing' pnpm dev这是技能文档未显式写明、但从源码结构中可以确认的一种团队惯例:把计时日志汇聚到专属命名空间,与功能日志分离,避免性能数据淹没业务事件。
-
历史前缀仍会存在。GitHub/index.ts 仍在使用
lobe-chat:module:github这类早期lobe-chat:前缀。从源码结构看,lobe-chat:属于项目早期(v0/v1 时期单体应用)遗留的命名空间,与文档约定的lobe-server:/lobe-client:并存。新增代码建议遵循技能文档中列出的端前缀,避免继续引入第三种前缀风格。
实践建议小结
- 新增日志时先确定代码所处运行端(server / desktop / client / 路由层),再选择对应的
lobe-前缀,末级子模块取组件或工作流步骤名; - 复杂入参、返回体用
%O,数字用%d,字符串用%s; - logger 实例放在模块顶层并复用,不要在函数体内反复
debug(); - 需要观测性能时,复用或新增
:timing类专属命名空间,使计时日志可被单独过滤; - 开启调试时优先用
lobe-*全量开关,定位问题后再收窄到具体模块前缀,如lobe-server:agent-runtime:*或lobe-server:workflows:*。
以上所有约定与示例均可在仓库中直接查证:规范原文见 .agents/skills/debug-package/SKILL.md,实际调用可在全仓库中检索 debug('lobe- 快速定位。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00