Skip to content

[Feature] 后台 LLM 开销可见性:实体抽取与 Sleep Mode 未计入审计表 #250

Closed

Description

@davidekingsss

使用场景

我用面板状态页的「LLM 消耗」卡判断 mneme 到底花了多少、哪条链路最费。现在它只覆盖 autoDream 与 autoSummarize,实体抽取和 Sleep Mode 的调用不计入,所以我没法从面板回答「关掉实体抽取能省多少」这类问题——而实体抽取恰恰是每次写入记忆都会跑的那条链路。

已查现状声明

查过 README、CHANGELOG、路线图与已有 issue:

我理解只记这两条可能是刻意收窄口径(避免审计表膨胀、避免把每条写入路径都拖上记账),如果是有意为之,这个 feature 就当记录一下需求。

期望的行为变化

希望面板能反映 mneme 后台 LLM 开销的全貌。做成开关、单独一张卡还是别的形式,由你定,我不指定实现方案。

Activity

  1. modusensus commented on Sep 19, 2026

    @modusensus
    Member

    @davidekingsss 查过了:不是有意收窄口径,是这两条链路结构上缺这个钩子。

    • 实体抽取:src/index.js 的 createEntityStreamAdapter({ llm, agentDefaultModel, logger }) 只拿到 llm 句柄,没有 service —— 写审计要走 service.saveLlmAudit,所以它从来没有这个能力。
    • Sleep Mode:src/dream/sleep.js 有一份自己的 streamText(ctx, options, onStreamError),签名里没有 onUsage;dream.js 那份是有的(Bug8 给 dream 与 summarize 接记账时漏了 sleep 这份副本)。

    所以这条需求是成立的,不是「记录一下」。

    顺带把一个真实取舍摆出来:实体抽取是每次写入记忆都会跑的链路,计入审计会让 llm_audit_logs 的行数随写入量线性增长(默认 90 天保留期只约束上界,不约束增速)。实现上倾向沿用现有 llmAudit.enabled 一个闸门、不新增配置键;若实测行数增长过快,再考虑按 operation_type 采样或单独保留期。

    这条要不要你自己接?你在 #248 / #253 上已经把审计这条线跑通了,接起来最快。我们这边也能做,先问一声。

  2. z2Ace0107 commented on Sep 22, 2026

    @z2Ace0107
    Contributor

    我想接这条 issue。

    先说一下我看到的情况:你上面点了 @davidekingsss 的名,而 #248 / #253 也正好是他在做,所以如果他已经准备接这条,那我就不占了,等他来做更顺。

    你当时还补了一句「我们这边也能做,先问一声」,所以我冒昧问一下:要是没别人接,我想来做这条。

    计划如下,都按 upstream/main 核对过:

    sleep 这边比较直接。 src/dream/sleep.js:53 的 streamText(ctx, options, onStreamError) 比 src/dream.js:230 那份少一个 onUsage,看着像 Bug8 接记账时漏掉了这份副本。补上之后,:235 的 conflict 调用和 :386 的 pattern 调用各包一层记账就够了——phaseConflicts 和 phasePatterns 的签名里本来就有 service,调用链不用动。trigger_source 记 sleep,operation_type 分别记 sleep_conflict 和 sleep_pattern。

    实体抽取这边稍微麻烦一点。 src/index.js:46 的 createEntityStreamAdapter 只拿了 llm / agentDefaultModel / logger,没有 service,所以一直写不了审计。我打算给它加一个 service 入参,在 usage chunk 那里把 token 收下来;src/entities/extractor.js 的 callLLM(messages, options) => Promise<string> 契约保持不变,token 由适配器侧汇总后写审计。trigger_source 记 entityExtract,operation_type 记 entity_extract。

    文档跟着改。 dsh-mneme/README.md 的「LLM 消耗审计」那一节现在只写了 autoDream 和 autoSummarize,把这两条补上;src/config.js 里 llmAudit 的注释也同步一下。

    有两个点我按你的意见定了:

    • 不加新配置键,就沿用 llmAudit.enabled 一个闸门。
    • 审计写失败仍然只 warn 不反噬,跟 runAuditedLlm 现在的口径一致。entityExtractionEnabled 和 sleep 默认都是关的,所以默认路径零行为变化。

    关于你提的行数增长,我倾向先不做采样。retentionDays 已经兜住上界,而且采样之后求和就不是真实开销了,「关掉实体抽取能省多少」这个问题会重新变得答不了。真要是实测增速过快,再按 operation_type 单独给保留期,那是后置的事。

    验证会跑 node --test test/llm-audit.test.js test/entities.test.js test/sleep.test.js,然后 npm test、npm run sync、node scripts/check-sync.js、git diff --check。

    这样行吗?如果 davidekingsss 那边先开口,我就撤。

  3. modusensus commented on Sep 22, 2026

    @modusensus
    Member

    给 @z2Ace0107 :批了,这条归你。

    计划核对过,sleep.js 的 streamText 缺 onUsage、createEntityStreamAdapter 缺 service、README 审计节的口径缺口,都和 main 现状一致,没有虚引用。davidekingsss 被点名后没有回声,他手上的 #248/#253 早已合并,不构成占用——按「先到先接」走,如果稍后他想参与,这两条链路还有别的边角(比如面板侧的 source 过滤展示)可以再开单。

    两个点你定的都对,维持:

    • 不加新配置键,沿用 llmAudit.enabled 一个闸门;
    • 审计写失败只 warn,不反噬功能本体。

    关于 operation_type 取值:sleep_conflict / sleep_pattern / entity_extract 按你的方案记,trigger_source 记 sleep / entityExtract——这两列是自由 TEXT,写进去就行,但面板的 source 过滤下拉要不要跟着加这两项,你顺手看一眼,能一行带上就带上,不能就留到面板批次。

    验收线(合并前置):

    1. 新增/改动的记账行为有回归测试:sleep 两条链路(conflict / pattern)各断言到「审计行落库 + token 数值正确」,实体抽取断言到「usage chunk 被汇总落库」;审计写失败路径至少一条测试(warn 不抛错);
    2. npm test 全绿 + npm run sync + check-sync 平价;
    3. README「LLM 消耗审计」节与 config.js 的 llmAudit 注释同步改;
    4. api.test.js 的 effective 旗标计数锁不受影响(你不加键就不该动它);
    5. PR 正文按仓库惯例写清改动面,Refs #250 引用(覆盖全部验收点后再改 Closes)。

    做完直接开 PR,我们按流程审。

  4. added 2 commits that reference this issue on Sep 22, 2026
  5. modusensus commented on Sep 22, 2026

    @modusensus
    Member

    三条链路(sleep_conflict / sleep_pattern / entity_extract)已由 #286 计入 llm_audit_logs,审计失败 warn 不反噬、README 覆盖表同步。感谢 @z2Ace0107 的快速实现与 @davidekingsss 最初的盘点。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions