5.9 KiB
5.9 KiB
服务子系统设计 — 会话记忆与上下文
元数据
- 项目名称: free-code
- 文档类型: 服务子系统设计
- 原始代码来源:
../../src/utils/memory/ - 关联总览: 服务子系统设计总览
- 原始映射: 原始代码映射
- 相关模块: 核心模块设计 — 查询引擎
- 相关模块: 基础设施设计 — 后台任务管理
- 相关模块: 基础设施设计 — 特性开关
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,防止把密钥、令牌或隐私数据外发。
- 该子系统与查询引擎联动,用于补充局部上下文,而不是替代主对话历史。