fix: 修复 recall 和 learn 的 bug
This commit is contained in:
@ -24,6 +24,9 @@ class LearnCommand extends BasePouchCommand {
|
||||
return '智能学习指定协议的资源内容,支持thought、execution、memory等DPML协议以及角色组件,支持@引用的语义渲染'
|
||||
}
|
||||
|
||||
/**
|
||||
* 学习指定资源并返回结果
|
||||
*/
|
||||
async getContent (args) {
|
||||
const [resourceUrl] = args
|
||||
|
||||
@ -31,22 +34,30 @@ class LearnCommand extends BasePouchCommand {
|
||||
return this.getUsageHelp()
|
||||
}
|
||||
|
||||
// 复用ActionCommand的成功资源加载逻辑
|
||||
return await this.loadLearnContentUsingActionLogic(resourceUrl)
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用ActionCommand的成功逻辑加载学习内容
|
||||
* 这个方法复用了ActionCommand.loadLearnContent的逻辑
|
||||
*/
|
||||
async loadLearnContentUsingActionLogic(resourceUrl) {
|
||||
try {
|
||||
// 解析协议信息
|
||||
const urlMatch = resourceUrl.match(/^(@[!?]?)?([a-zA-Z][a-zA-Z0-9_-]*):\/\/(.+)$/)
|
||||
if (!urlMatch) {
|
||||
return this.formatErrorResponse(resourceUrl, '无效的资源URL格式')
|
||||
}
|
||||
|
||||
const [, loadingSemantic, protocol, resourceId] = urlMatch
|
||||
|
||||
// 使用ResourceManager解析资源
|
||||
const result = await this.resourceManager.resolve(resourceUrl)
|
||||
|
||||
|
||||
if (!result.success) {
|
||||
return this.formatErrorResponse(resourceUrl, result.error.message)
|
||||
}
|
||||
|
||||
// 解析协议信息
|
||||
const urlMatch = resourceUrl.match(/^(@[!?]?)?([a-zA-Z][a-zA-Z0-9_-]*):\/\/(.+)$/)
|
||||
if (!urlMatch) {
|
||||
return this.formatErrorResponse(resourceUrl, "无效的资源URL格式")
|
||||
}
|
||||
|
||||
const [, loadingSemantic, protocol, resourceId] = urlMatch
|
||||
|
||||
// 检查内容是否包含@引用,如果包含则进行语义渲染
|
||||
let finalContent = result.content
|
||||
|
||||
@ -337,4 +348,4 @@ ${divider}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LearnCommand
|
||||
module.exports = LearnCommand
|
||||
@ -23,11 +23,28 @@ class RecallCommand extends BasePouchCommand {
|
||||
const memories = await this.getAllMemories(query)
|
||||
|
||||
if (memories.length === 0) {
|
||||
return `🧠 AI记忆体系中暂无内容。
|
||||
if (query) {
|
||||
// 针对特定查询的优化提示
|
||||
return `🔍 记忆检索结果:未找到匹配"${query}"的相关记忆
|
||||
|
||||
💡 优化建议:
|
||||
1. **扩大查询范围**:尝试使用更通用的关键词
|
||||
2. **换个角度查询**:尝试相关词汇或概念
|
||||
3. **检查拼写**:确认关键词拼写正确
|
||||
4. **查看全部记忆**:不使用查询参数,浏览所有记忆寻找灵感
|
||||
|
||||
🔄 下一步行动:
|
||||
- 不带参数再次使用 recall 工具查看全部记忆
|
||||
- 使用 remember 工具记录新的相关知识
|
||||
- 使用 learn 工具学习相关资源后再检索`
|
||||
} else {
|
||||
// 无记忆的情况
|
||||
return `🧠 AI记忆体系中暂无内容。
|
||||
💡 建议:
|
||||
1. 使用 MCP PromptX remember 工具内化新知识
|
||||
2. 使用 MCP PromptX learn 工具学习后再内化
|
||||
3. 开始构建AI的专业知识体系`
|
||||
}
|
||||
}
|
||||
|
||||
const formattedMemories = this.formatRetrievedKnowledge(memories, query)
|
||||
@ -242,12 +259,80 @@ ${formattedMemories}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查记忆是否匹配查询
|
||||
* 检查记忆是否匹配查询 - 增强版匹配算法
|
||||
*/
|
||||
matchesMemory (memory, query) {
|
||||
const lowerQuery = query.toLowerCase()
|
||||
return memory.content.toLowerCase().includes(lowerQuery) ||
|
||||
memory.tags.some(tag => tag.toLowerCase().includes(lowerQuery))
|
||||
const lowerContent = memory.content.toLowerCase()
|
||||
|
||||
// 1. 完全匹配 - 最高优先级
|
||||
if (lowerContent.includes(lowerQuery) ||
|
||||
memory.tags.some(tag => tag.toLowerCase().includes(lowerQuery))) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 2. 分词匹配 - 支持多关键词组合查询
|
||||
const queryWords = lowerQuery.split(/\s+/).filter(word => word.length > 1)
|
||||
if (queryWords.length > 1) {
|
||||
const matchedWords = queryWords.filter(word =>
|
||||
lowerContent.includes(word) ||
|
||||
memory.tags.some(tag => tag.toLowerCase().includes(word))
|
||||
)
|
||||
// 如果匹配了一半以上的关键词,认为相关
|
||||
return matchedWords.length >= Math.ceil(queryWords.length / 2)
|
||||
}
|
||||
|
||||
// 3. 模糊匹配 - 支持常见同义词和缩写
|
||||
const synonyms = this.getSynonyms(lowerQuery)
|
||||
for (const synonym of synonyms) {
|
||||
if (lowerContent.includes(synonym) ||
|
||||
memory.tags.some(tag => tag.toLowerCase().includes(synonym))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询词的同义词和相关词
|
||||
*/
|
||||
getSynonyms (query) {
|
||||
const synonymMap = {
|
||||
'mcp': ['model context protocol', '工具'],
|
||||
'promptx': ['prompt-x', '提示词'],
|
||||
'测试': ['test', 'testing', 'qa', '质量保证'],
|
||||
'工具': ['tool', 'mcp', '功能'],
|
||||
'记忆': ['memory', 'recall', '回忆'],
|
||||
'学习': ['learn', 'study', '学会'],
|
||||
'角色': ['role', 'character', '专家'],
|
||||
'产品': ['product', 'pm', '产品经理'],
|
||||
'开发': ['develop', 'dev', 'coding', '编程'],
|
||||
'前端': ['frontend', 'fe', 'ui'],
|
||||
'后端': ['backend', 'be', 'api', '服务端'],
|
||||
'github': ['git', '代码仓库', '版本控制'],
|
||||
'issue': ['问题', 'bug', '需求'],
|
||||
'敏捷': ['agile', 'scrum', '迭代']
|
||||
}
|
||||
|
||||
const result = [query] // 包含原查询词
|
||||
|
||||
// 查找直接同义词
|
||||
if (synonymMap[query]) {
|
||||
result.push(...synonymMap[query])
|
||||
}
|
||||
|
||||
// 查找包含关系的同义词
|
||||
for (const [key, values] of Object.entries(synonymMap)) {
|
||||
if (key.includes(query) || query.includes(key)) {
|
||||
result.push(key, ...values)
|
||||
}
|
||||
if (values.some(v => v.includes(query) || query.includes(v))) {
|
||||
result.push(key, ...values)
|
||||
}
|
||||
}
|
||||
|
||||
return [...new Set(result)] // 去重
|
||||
}
|
||||
|
||||
matchesQuery (content, query) {
|
||||
|
||||
@ -179,6 +179,26 @@ class ResourceManager {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理URL格式(如 thought://systematic-testing)
|
||||
const urlMatch = resourceId.match(/^([a-zA-Z][a-zA-Z0-9_-]*):\/\/(.+)$/)
|
||||
if (urlMatch) {
|
||||
const [, protocol, id] = urlMatch
|
||||
const resourceData = this.registryData.findResourceById(id, protocol)
|
||||
if (!resourceData) {
|
||||
throw new Error(`Resource not found: ${resourceId}`)
|
||||
}
|
||||
|
||||
// 通过协议解析加载内容
|
||||
const content = await this.loadResourceByProtocol(resourceData.reference)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
content,
|
||||
resourceId,
|
||||
reference: resourceData.reference
|
||||
}
|
||||
}
|
||||
|
||||
// 处理传统格式(如 role:java-developer)
|
||||
let reference = null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user