fix: 修复 recall 和 learn 的 bug

This commit is contained in:
sean
2025-06-19 15:25:48 +08:00
parent 734f1f2bee
commit 11d8c9a75e
3 changed files with 131 additions and 15 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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