free-code-dotnet/docs/服务子系统设计/服务子系统设计-会话记忆与上下文.md
应文浩wenhao.ying@xiaobao100.com e25ac591a7 init easy-code
2026-04-06 07:24:24 +08:00

5.9 KiB
Raw Blame History

服务子系统设计 — 会话记忆与上下文

元数据

1. 设计目标

会话记忆与上下文子系统负责把长会话中的关键内容压缩、沉淀、同步,并在需要时为查询引擎提供可控、低成本的上下文补充。该子系统强调阈值触发、轻量模型处理、以及在写入团队知识库前的安全校验。

2. 核心数据结构

public enum MemoryType
{
    Session,
    Dream,
    Team
}

public sealed record MemoryEntry(
    string Id,
    MemoryType Type,
    string SessionId,
    string Content,
    DateTimeOffset CreatedAt,
    IReadOnlyList<string> Tags);

MemoryType 用于区分会话记忆、自动梦境摘要与团队共享记忆。MemoryEntry 记录统一承载记忆内容、来源会话、创建时间和标签,便于检索与同步。

3. 会话记忆服务

public interface ISessionMemoryService
{
    Task<MemoryEntry?> ExtractAsync(
        string sessionId,
        int tokenCount,
        int toolCallCount,
        CancellationToken cancellationToken = default);

    Task SaveAsync(MemoryEntry entry, CancellationToken cancellationToken = default);

    Task<IReadOnlyList<MemoryEntry>> GetRecentAsync(
        string sessionId,
        CancellationToken cancellationToken = default);
}

ISessionMemoryService 使用阈值触发提取:当 token 数或 tool call 数超过阈值时,触发一次记忆抽取,生成摘要型 MemoryEntry

public sealed class SessionMemoryService : ISessionMemoryService
{
    private readonly int _tokenThreshold = 12000;
    private readonly int _toolCallThreshold = 24;

    public async Task<MemoryEntry?> ExtractAsync(
        string sessionId,
        int tokenCount,
        int toolCallCount,
        CancellationToken cancellationToken = default)
    {
        var shouldExtract = tokenCount >= _tokenThreshold || toolCallCount >= _toolCallThreshold;
        if (!shouldExtract)
        {
            return null;
        }

        return await Task.FromResult(new MemoryEntry(
            Id: Guid.NewGuid().ToString("N"),
            Type: MemoryType.Session,
            SessionId: sessionId,
            Content: "基于会话上下文生成的压缩记忆。",
            CreatedAt: DateTimeOffset.UtcNow,
            Tags: new[] { "session", "summary" }));
    }

    public Task SaveAsync(MemoryEntry entry, CancellationToken cancellationToken = default) => Task.CompletedTask;

    public Task<IReadOnlyList<MemoryEntry>> GetRecentAsync(string sessionId, CancellationToken cancellationToken = default)
        => Task.FromResult<IReadOnlyList<MemoryEntry>>(Array.Empty<MemoryEntry>());
}

4. 自动梦境服务

public interface IAutoDreamService
{
    Task<MemoryEntry?> GenerateAsync(
        string sessionId,
        TimeSpan idleDuration,
        int sessionCount,
        CancellationToken cancellationToken = default);
}

IAutoDreamService 在两类条件触发:会话空闲超过 24 小时,或会话累计次数达到设定阈值。它用于生成更高层级的长期偏好、主题趋势和待办线索。

public sealed class AutoDreamService : IAutoDreamService
{
    private readonly TimeSpan _idleThreshold = TimeSpan.FromHours(24);
    private readonly int _sessionCountThreshold = 10;

    public async Task<MemoryEntry?> GenerateAsync(
        string sessionId,
        TimeSpan idleDuration,
        int sessionCount,
        CancellationToken cancellationToken = default)
    {
        if (idleDuration < _idleThreshold && sessionCount < _sessionCountThreshold)
        {
            return null;
        }

        return await Task.FromResult(new MemoryEntry(
            Id: Guid.NewGuid().ToString("N"),
            Type: MemoryType.Dream,
            SessionId: sessionId,
            Content: "基于空闲周期与会话积累生成的自动梦境摘要。",
            CreatedAt: DateTimeOffset.UtcNow,
            Tags: new[] { "dream", "long-term" }));
    }
}

5. 团队记忆同步服务

public interface ITeamMemorySyncService
{
    Task PushAsync(MemoryEntry entry, CancellationToken cancellationToken = default);
    Task<MemoryEntry?> PullAsync(string memoryId, CancellationToken cancellationToken = default);
}

ITeamMemorySyncService 支持推送与拉取团队记忆。推送前必须执行 secret scanning避免把敏感信息写入共享知识库。

public sealed class TeamMemorySyncService : ITeamMemorySyncService
{
    public Task PushAsync(MemoryEntry entry, CancellationToken cancellationToken = default)
    {
        var hasSecret = false;
        if (hasSecret)
        {
            throw new InvalidOperationException("检测到敏感信息,禁止推送团队记忆。");
        }

        return Task.CompletedTask;
    }

    public Task<MemoryEntry?> PullAsync(string memoryId, CancellationToken cancellationToken = default)
        => Task.FromResult<MemoryEntry?>(null);
}

6. 设计说明

  • 记忆相关操作使用轻量模型 claude-haiku-4-5,优先保证低延迟与低成本。
  • 记忆抽取优先走阈值触发,避免每轮上下文都进行重处理。
  • 团队记忆同步前必须进行 secret scanning防止把密钥、令牌或隐私数据外发。
  • 该子系统与查询引擎联动,用于补充局部上下文,而不是替代主对话历史。