fix: 修复记忆系统rule/preference不生效的问题
- searchMemoriesByKeyword: rule和preference类型始终注入,不再依赖关键词匹配 - 只有fact类型保留关键词匹配逻辑 - buildMemoryContext: 区分三类记忆的system prompt措辞 - rule: 【必须严格遵守的规则】无条件执行 - preference: 【用户偏好】请遵循 - fact: 【参考信息】无关可忽略
This commit is contained in:
@@ -180,7 +180,18 @@ function searchMemoriesByKeyword(query: string, limit: number): MemorySearchResu
|
|||||||
const queryLower = query.toLowerCase();
|
const queryLower = query.toLowerCase();
|
||||||
const queryWords = queryLower.split(/[\s,,。!?、;:""''()\[\]{}<>`~@#$%^&*+=|\\/.]+/).filter(w => w.length > 1);
|
const queryWords = queryLower.split(/[\s,,。!?、;:""''()\[\]{}<>`~@#$%^&*+=|\\/.]+/).filter(w => w.length > 1);
|
||||||
|
|
||||||
const scored = memoryCache.map(entry => {
|
// rule 和 preference 类型的记忆全局生效,始终注入
|
||||||
|
const alwaysInclude: MemorySearchResult[] = [];
|
||||||
|
const scored: MemorySearchResult[] = [];
|
||||||
|
|
||||||
|
for (const entry of memoryCache) {
|
||||||
|
if (entry.type === 'rule' || entry.type === 'preference') {
|
||||||
|
// 规则和偏好:始终包含,按重要性排序
|
||||||
|
alwaysInclude.push({ ...entry, score: 100 + entry.importance });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fact 类型:按关键词匹配
|
||||||
let score = 0;
|
let score = 0;
|
||||||
const contentLower = entry.content.toLowerCase();
|
const contentLower = entry.content.toLowerCase();
|
||||||
const tagsLower = entry.tags.map(t => t.toLowerCase());
|
const tagsLower = entry.tags.map(t => t.toLowerCase());
|
||||||
@@ -211,13 +222,22 @@ function searchMemoriesByKeyword(query: string, limit: number): MemorySearchResu
|
|||||||
// 使用频率加权
|
// 使用频率加权
|
||||||
score *= (1 + Math.min(entry.useCount, 10) / 50);
|
score *= (1 + Math.min(entry.useCount, 10) / 50);
|
||||||
|
|
||||||
return { ...entry, score };
|
if (score > 0) {
|
||||||
});
|
scored.push({ ...entry, score });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return scored
|
// 合并:全局规则/偏好 + 关键词匹配的事实,去重后按分数排序
|
||||||
.filter(s => s.score > 0)
|
const seen = new Set<string>();
|
||||||
.sort((a, b) => b.score - a.score)
|
const merged: MemorySearchResult[] = [];
|
||||||
.slice(0, limit);
|
for (const item of [...alwaysInclude, ...scored.sort((a, b) => b.score - a.score)]) {
|
||||||
|
if (!seen.has(item.id)) {
|
||||||
|
seen.add(item.id);
|
||||||
|
merged.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged.slice(0, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 记忆添加 ──
|
// ── 记忆添加 ──
|
||||||
@@ -380,19 +400,38 @@ export function buildMemoryContext(memories: MemorySearchResult[]): string {
|
|||||||
grouped[m.type].push(m);
|
grouped[m.type].push(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = '【关于用户的重要信息】\n';
|
let context = '';
|
||||||
context += '以下是你之前记住的关于用户的信息,在回答时请参考:\n\n';
|
|
||||||
|
|
||||||
for (const [type, items] of Object.entries(grouped)) {
|
// 规则类:强制约束,放在最前面
|
||||||
const typeName = TYPE_NAMES[type] || type;
|
if (grouped['rule']) {
|
||||||
context += `— ${typeName} —\n`;
|
context += '【必须严格遵守的规则】\n以下规则是用户明确要求的,必须无条件执行:\n';
|
||||||
for (const item of items) {
|
for (const item of grouped['rule']) {
|
||||||
context += ` • ${item.content}\n`;
|
context += ` - ${item.content}\n`;
|
||||||
|
}
|
||||||
|
context += '\n';
|
||||||
|
delete grouped['rule'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 偏好类:用户偏好
|
||||||
|
if (grouped['preference']) {
|
||||||
|
context += '【用户偏好】\n在回答时请遵循以下偏好:\n';
|
||||||
|
for (const item of grouped['preference']) {
|
||||||
|
context += ` - ${item.content}\n`;
|
||||||
|
}
|
||||||
|
context += '\n';
|
||||||
|
delete grouped['preference'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 事实类:参考信息
|
||||||
|
if (grouped['fact']) {
|
||||||
|
context += '【关于用户的参考信息】\n以下信息供参考,与当前对话无关时可忽略:\n';
|
||||||
|
for (const item of grouped['fact']) {
|
||||||
|
context += ` - ${item.content}\n`;
|
||||||
}
|
}
|
||||||
context += '\n';
|
context += '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
context += '请自然地利用这些信息,不要生硬地列举。如果信息与当前对话无关,忽略即可。';
|
context += '请自然地利用以上信息,不要生硬地列举。';
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user