添加了记忆功能

This commit is contained in:
1600822305
2025-04-13 23:34:58 +08:00
parent e9347337b2
commit 51fc167b2a
5 changed files with 95 additions and 42 deletions
+28 -2
View File
@@ -81,8 +81,34 @@ export class MemoryFileService {
// 如果文件不存在或读取失败,使用空对象
}
// 合并数据,优先使用新数据
const mergedData = { ...existingData, ...data }
// 合并数据,注意数组的处理
const mergedData = { ...existingData }
// 处理每个属性
Object.entries(data).forEach(([key, value]) => {
// 如果是数组属性,需要特殊处理
if (Array.isArray(value) && Array.isArray(mergedData[key])) {
// 对于 memories 和 shortMemories,需要合并而不是覆盖
if (key === 'memories' || key === 'shortMemories') {
// 创建一个集合来跟踪已存在的记忆ID
const existingIds = new Set(mergedData[key].map(item => item.id))
// 将新记忆添加到现有记忆中,避免重复
value.forEach(item => {
if (item.id && !existingIds.has(item.id)) {
mergedData[key].push(item)
existingIds.add(item.id)
}
})
} else {
// 其他数组属性,使用新值
mergedData[key] = value
}
} else {
// 非数组属性,直接使用新值
mergedData[key] = value
}
})
// 保存合并后的数据
await fs.writeFile(memoryDataPath, JSON.stringify(mergedData, null, 2))
+20
View File
@@ -1070,6 +1070,26 @@
"enable": "启用智能优先级管理",
"enableTip": "启用后,系统将根据重要性、访问频率和时间因素自动排序记忆",
"decay": "记忆衰减",
"decayRate": "衰减速率",
"decayRateTip": "值越大,记忆衰减越快。0.05表示每天衰减5%",
"freshness": "记忆鲜度",
"freshnessTip": "考虑记忆的创建时间和最后访问时间,优先显示较新的记忆",
"updateNow": "立即更新",
"updateNowTip": "立即更新所有记忆的优先级排序",
"update": "更新"
},
"contextualRecommendation": {
"title": "上下文感知记忆推荐",
"description": "根据当前对话上下文,智能推荐相关的记忆内容。",
"enable": "启用上下文感知记忆推荐",
"enableTip": "启用后,系统将根据当前对话上下文自动推荐相关记忆",
"autoRecommend": "自动推荐记忆",
"autoRecommendTip": "启用后,系统将定期自动分析当前对话并推荐相关记忆",
"threshold": "推荐阈值",
"thresholdTip": "设置记忆推荐的相似度阈值,值越高要求越严格",
"clearRecommendations": "清除当前推荐",
"clearRecommendationsTip": "清除当前的记忆推荐列表",
"clear": "清除",
"decayTip": "随着时间推移,未访问的记忆重要性会逐渐降低",
"decayRate": "衰减速率",
"decayRateTip": "值越大,记忆衰减越快。0.05表示每天衰减5%",
@@ -9,7 +9,7 @@ import {
import { useTheme } from '@renderer/context/ThemeProvider'
import { TopicManager } from '@renderer/hooks/useTopic'
import { analyzeAndAddShortMemories, useMemoryService } from '@renderer/services/MemoryService'
import store, { useAppDispatch, useAppSelector } from '@renderer/store'
import { useAppDispatch, useAppSelector } from '@renderer/store'
import {
addMemory,
clearMemories,
@@ -19,7 +19,8 @@ import {
setAnalyzing,
setAutoAnalyze,
setMemoryActive,
setShortMemoryAnalyzeModel
setShortMemoryAnalyzeModel,
saveMemoryData
} from '@renderer/store/memory'
import { Topic } from '@renderer/types'
import { Button, Empty, Input, List, message, Modal, Radio, Select, Switch, Tabs, Tag, Tooltip } from 'antd'
@@ -260,18 +261,9 @@ const MemorySettings: FC = () => {
dispatch(setAnalyzeModel(modelId))
console.log('[Memory Settings] Analyze model set:', modelId)
// 手动保存到JSON文件
// 使用Redux Thunk保存到JSON文件
try {
const state = store.getState().memory
await window.api.memory.saveData({
analyzeModel: modelId,
shortMemoryAnalyzeModel: state.shortMemoryAnalyzeModel,
vectorizeModel: state.vectorizeModel,
// 确保其他必要的数据也被保存
memoryLists: state.memoryLists || [],
memories: state.memories || [],
shortMemories: state.shortMemories || []
})
await dispatch(saveMemoryData({ analyzeModel: modelId })).unwrap()
console.log('[Memory Settings] Analyze model saved to file successfully:', modelId)
} catch (error) {
console.error('[Memory Settings] Failed to save analyze model to file:', error)
@@ -283,18 +275,9 @@ const MemorySettings: FC = () => {
dispatch(setShortMemoryAnalyzeModel(modelId))
console.log('[Memory Settings] Short memory analyze model set:', modelId)
// 手动保存到JSON文件
// 使用Redux Thunk保存到JSON文件
try {
const state = store.getState().memory
await window.api.memory.saveData({
analyzeModel: state.analyzeModel,
shortMemoryAnalyzeModel: modelId,
vectorizeModel: state.vectorizeModel,
// 确保其他必要的数据也被保存
memoryLists: state.memoryLists || [],
memories: state.memories || [],
shortMemories: state.shortMemories || []
})
await dispatch(saveMemoryData({ shortMemoryAnalyzeModel: modelId })).unwrap()
console.log('[Memory Settings] Short memory analyze model saved to file successfully:', modelId)
} catch (error) {
console.error('[Memory Settings] Failed to save short memory analyze model to file:', error)
+21 -12
View File
@@ -899,33 +899,42 @@ export const analyzeAndAddShortMemories = async (topicId: string) => {
// 构建短期记忆分析提示词,包含已有记忆和新对话
const prompt = `
请对以下对话内容进行详细分析和总结,提取对当前对话至关重要的上下文信息。
请对以下对话内容进行非常详细分析和总结,提取对当前对话至关重要的上下文信息。请注意,这个分析将用于生成短期记忆,帮助AI理解当前对话的完整上下文。
分析要求:
1. 详细总结用户的每一句话中表达的关键信息、需求和意图
2. 分析AI回复中的重要内容和对用户问题的解决方案
3. 识别对话中的重要事实、数据和具体细节
4. 捕捉对话的逻辑发展转折点
1. 非常详细总结用户的每一句话中表达的关键信息、需求和意图
2. 全面分析AI回复中的重要内容和对用户问题的解决方案
3. 详细记录对话中的重要事实、数据、代码示例和具体细节
4. 清晰捕捉对话的逻辑发展转折点和关键决策
5. 提取对理解当前对话上下文必不可少的信息
6. 记录用户提出的具体问题和关注点
7. 捕捉用户在对话中表达的偏好、困惑和反馈
8. 记录对话中提到的文件、路径、变量名等具体技术细节
与长期记忆不同,短期记忆应该关注当前对话的具体细节和上下文,而不是用户的长期偏好。每条短期记忆应该是对对话片段的精准总结,确保不遗漏任何重要信息。
与长期记忆不同,短期记忆应该非常详细地关注当前对话的具体细节和上下文。每条短期记忆应该是对对话片段的精准总结,确保不遗漏任何重要信息。
请注意,对于长对话(超过5万字),您应该生成至少15-20条详细的记忆条目,确保完整捕捉对话的所有重要方面。对于超长对话(超过8万字),应生成至少20-30条记忆条目。
${
existingMemoriesContent
? `以下是已经提取的重要信息:
${existingMemoriesContent}
请分析新的对话内容,提取出新的重要信息,避免重复已有信息。确保新提取的信息与已有信息形成连贯的上下文理解。`
: '请对对话进行全面分析,确保不遗漏任何重要细节。每条总结应该是完整的句子,清晰表达一个重要的上下文信息。'
请分析新的对话内容,提取出新的重要信息,避免重复已有信息。确保新提取的信息与已有信息形成连贯的上下文理解。对于新的对话内容,请提供非常详细的分析。`
: '请对对话进行非常全面和详细的分析,确保不遗漏任何重要细节。每条总结应该是完整的句子,清晰表达一个重要的上下文信息。请确保总结足够详细,以便在没有原始对话的情况下也能理解完整的上下文。'
}
输出格式:
- 提供完整的上下文总结,数量不限,确保覆盖所有重要信息
- 每条总结应该是一个完整的句子
- 提供非常详细的上下文总结,数量不限,确保覆盖所有重要信息
- 每条总结应该是一个完整的句子,包含充分的上下文信息
- 确保总结内容精准、具体且与当前对话直接相关
- 按重要性排序,最重要的信息放在前面
- 对于复杂的对话,提供足够多的条目(至少5-10条)以确保上下文的完整性
- 如果对话内容简单,可以少于5条,但必须确保完整捕捉所有重要信息
- 对于复杂的对话,必须提供足够多的条目(至少15-20条)以确保上下文的完整性
- 对于技术内容,请包含具体的文件名、路径、变量名、函数名等技术细节
- 对于代码相关的对话,请记录关键的代码片段和实现细节
- 如果对话内容简单,可以少于15条,但必须确保完整捕捉所有重要信息
请记住,您的分析应该非常详细,不要过于简化或概括。对于8万字的对话,100字的总结是远远不够的,应该提供至少500-1000字的详细总结,分成多个条目。
如果没有找到新的重要信息,请返回空字符串。
+19 -4
View File
@@ -1,6 +1,7 @@
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'
import { nanoid } from 'nanoid'
import log from 'electron-log'
import store from '@renderer/store'
// 记忆列表接口
export interface MemoryList {
@@ -851,12 +852,26 @@ export const saveMemoryData = createAsyncThunk(
'memory/saveData',
async (data: Partial<MemoryState>) => {
try {
// log.info('Saving memory data to file...') // Removed direct log call from renderer
const result = await window.api.memory.saveData(data)
// log.info('Memory data saved successfully') // Removed direct log call from renderer
console.log('[Memory] Saving memory data to file...', Object.keys(data))
// 确保数据完整性
const state = store.getState().memory
const completeData = {
...data,
// 如果没有提供这些字段,则使用当前状态中的值
memoryLists: data.memoryLists || state.memoryLists,
memories: data.memories || state.memories,
shortMemories: data.shortMemories || state.shortMemories,
analyzeModel: data.analyzeModel || state.analyzeModel,
shortMemoryAnalyzeModel: data.shortMemoryAnalyzeModel || state.shortMemoryAnalyzeModel,
vectorizeModel: data.vectorizeModel || state.vectorizeModel
}
const result = await window.api.memory.saveData(completeData)
console.log('[Memory] Memory data saved successfully')
return result
} catch (error) {
console.error('Failed to save memory data:', error) // Use console.error instead of log.error
console.error('[Memory] Failed to save memory data:', error)
return false
}
}