Skip to content

Conversation

@ocetars
Copy link
Member

@ocetars ocetars commented Jan 25, 2026

Fixes #4427:启用长期记忆后,同一条“当前用户消息”会同时出现在 system(历史)与 user(当前输入)中,导致一次请求内重复注入,影响模型理解且占用 token 。

Modifications / 改动点

  • This is NOT a breaking change. / 这不是一个破坏性变更。

  • astrbot/builtin_stars/astrbot/long_term_memory.py

    • 结构化存储:引入 ChatRecord(msg_id/role/text/created_at)session_chats 存储为 ChatRecord 列表。
    • 稳定标识:新增 _get_event_msg_id(),优先使用 event.message_obj.message_id,缺失时使用 event.extra 缓存生成的 ID,保证同一事件链路一致。
    • 精准过滤on_req_llm() 构造聊天历史时,过滤 msg_id == current_msg_id 的记录,确保当前轮消息只作为 user prompt 发送,不再被重复写入 system 历史。
    • 兼容保留:保留原有 max_cnt 截断、图片描述(可选)与 active reply 分支逻辑。

Screenshots or Test Results / 运行截图或测试结果

66c32e87980a84440f89c67fa59a86b9

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Summary by Sourcery

为长期聊天记忆记录建立结构化格式,以避免在单次 LLM 请求中将当前消息同时重复出现在历史记录和用户提示中。

Bug Fixes:

  • 通过基于稳定的消息 ID 将当前用户消息从长期记忆历史中排除,防止其在单次请求中被注入两次。

Enhancements:

  • 将长期聊天历史存储为结构化的 ChatRecord 条目,包含稳定的消息 ID、角色和时间戳,以支持精确过滤和未来的可扩展性。
Original summary in English

Summary by Sourcery

Structure long-term chat memory records to avoid duplicating the current message in both history and user prompt within a single LLM request.

Bug Fixes:

  • Prevent the current user message from being injected twice in a single request by excluding it from the long-term memory history based on a stable message ID.

Enhancements:

  • Store long-term chat history as structured ChatRecord entries with stable message IDs, roles, and timestamps to support precise filtering and future extensibility.

@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jan 25, 2026
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我在这里给出一些整体性的反馈:

  • ChatRecord 中的 created_at 字段使用了没有时区信息的 datetime.now().isoformat();建议改为使用显式的 UTC 时间戳(例如 datetime.datetime.now(datetime.timezone.utc)),以避免在不同环境中检查或比较记录时产生歧义。
  • _ltm_msg_id 这个用于 event.get_extra/set_extra 的魔法字符串目前是直接内联写死的;建议提升为模块级常量,以避免拼写错误,并让未来查找和修改更加方便。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- `ChatRecord` 中的 `created_at` 字段使用了没有时区信息的 `datetime.now().isoformat()`;建议改为使用显式的 UTC 时间戳(例如 `datetime.datetime.now(datetime.timezone.utc)`),以避免在不同环境中检查或比较记录时产生歧义。
- `_ltm_msg_id` 这个用于 `event.get_extra`/`set_extra` 的魔法字符串目前是直接内联写死的;建议提升为模块级常量,以避免拼写错误,并让未来查找和修改更加方便。

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈改进后续的评审。
Original comment in English

Hey - I've left some high level feedback:

  • The created_at field in ChatRecord uses datetime.now().isoformat() without timezone info; consider switching to an explicit UTC timestamp (e.g., datetime.datetime.now(datetime.timezone.utc)) to avoid ambiguity when inspecting or comparing records across environments.
  • The _ltm_msg_id magic string used in event.get_extra/set_extra is currently inlined; consider lifting it to a module-level constant to avoid typos and make it easier to find and change in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `created_at` field in `ChatRecord` uses `datetime.now().isoformat()` without timezone info; consider switching to an explicit UTC timestamp (e.g., `datetime.datetime.now(datetime.timezone.utc)`) to avoid ambiguity when inspecting or comparing records across environments.
- The `_ltm_msg_id` magic string used in `event.get_extra`/`set_extra` is currently inlined; consider lifting it to a module-level constant to avoid typos and make it easier to find and change in the future.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@dosubot dosubot bot added the area:core The bug / feature is about astrbot's core, backend label Jan 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 长期记忆功能导致同一条消息在 system 与 user 中重复注入

1 participant