Features: - PromptService enhancement: enhanceWithKnowledge(), loadFullKnowledge(), ragSearch() - FULL mode: Load entire knowledge base content - RAG mode: Vector search based on user query - Knowledge config API: PUT /:code/knowledge-config - Test render with knowledge injection support - Frontend: Knowledge config UI in Prompt editor Bug fixes: - Fix knowledge config not returned in getPromptDetail - Fix publish button 400 error (empty request body) - Fix cache not invalidated after publish - Add detailed logging for debugging Documentation: - Add development record 2026-01-28 - Update ADMIN module status to Phase 4.6 - Update system status document to v4.5 Co-authored-by: Cursor <cursoragent@cursor.com>
165 lines
5.6 KiB
JavaScript
165 lines
5.6 KiB
JavaScript
/**
|
||
* 端到端测试 PromptService.get() 知识库注入
|
||
*
|
||
* 使用方法:
|
||
* cd backend
|
||
* node src/common/prompt/__tests__/test-prompt-get.cjs
|
||
*/
|
||
|
||
const { PrismaClient } = require('@prisma/client');
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
// 模拟 PromptService.get() 的逻辑
|
||
async function testPromptServiceGet(code, variables = {}) {
|
||
console.log(`\n🎯 测试 promptService.get("${code}", ${JSON.stringify(variables)})\n`);
|
||
console.log('='.repeat(60));
|
||
|
||
// 1. 获取模板
|
||
const template = await prisma.prompt_templates.findUnique({
|
||
where: { code },
|
||
});
|
||
|
||
if (!template) {
|
||
console.log(`❌ Prompt 模板 ${code} 不存在!`);
|
||
return;
|
||
}
|
||
|
||
console.log(`\n📝 Prompt 模板: ${template.name}`);
|
||
console.log(` 知识库配置: ${JSON.stringify(template.knowledge_config, null, 2)}`);
|
||
|
||
// 2. 获取版本
|
||
const version = await prisma.prompt_versions.findFirst({
|
||
where: { template_id: template.id, status: 'ACTIVE' },
|
||
orderBy: { version: 'desc' },
|
||
});
|
||
|
||
if (!version) {
|
||
console.log(`❌ 没有 ACTIVE 版本!`);
|
||
return;
|
||
}
|
||
|
||
console.log(`\n📄 Prompt 内容 (v${version.version}):`);
|
||
console.log(' ' + version.content.substring(0, 200).replace(/\n/g, '\n ') + '...');
|
||
|
||
// 3. 知识库增强
|
||
const config = template.knowledge_config;
|
||
if (!config || !config.enabled) {
|
||
console.log('\n⚠️ 知识库增强未启用');
|
||
return;
|
||
}
|
||
|
||
console.log('\n📚 知识库增强配置:');
|
||
console.log(` 启用: ${config.enabled}`);
|
||
console.log(` 知识库: ${config.kb_codes?.join(', ')}`);
|
||
console.log(` 模式: ${config.injection_mode}`);
|
||
console.log(` 目标变量: ${config.target_variable || 'context'}`);
|
||
|
||
// 4. 加载知识库内容 (FULL 模式)
|
||
if (config.injection_mode === 'FULL') {
|
||
console.log('\n🔄 FULL 模式: 加载知识库全文...');
|
||
|
||
// 获取 system_knowledge_bases ID
|
||
const systemKbs = await prisma.system_knowledge_bases.findMany({
|
||
where: { code: { in: config.kb_codes || [] }, status: 'active' },
|
||
select: { id: true, code: true, name: true },
|
||
});
|
||
|
||
console.log(` 找到 ${systemKbs.length} 个系统知识库:`, systemKbs.map(kb => kb.code));
|
||
|
||
const kbIds = systemKbs.map(kb => kb.id);
|
||
console.log(` 系统知识库 IDs: ${kbIds.join(', ')}`);
|
||
|
||
// 检查 EKB 知识库
|
||
const ekbKbs = await prisma.ekbKnowledgeBase.findMany({
|
||
where: { id: { in: kbIds } },
|
||
select: { id: true, name: true },
|
||
});
|
||
console.log(` EKB 知识库: ${ekbKbs.length} 个`, ekbKbs.map(kb => kb.id));
|
||
|
||
// 查询分块
|
||
const chunks = await prisma.ekbChunk.findMany({
|
||
where: {
|
||
document: {
|
||
kbId: { in: kbIds },
|
||
},
|
||
},
|
||
select: { content: true },
|
||
take: 5,
|
||
});
|
||
|
||
console.log(` 找到 ${chunks.length} 个分块`);
|
||
|
||
if (chunks.length === 0) {
|
||
console.log('\n❌ 问题定位: ekbChunk 表中没有找到匹配的分块!');
|
||
console.log(' 这可能是因为 ekbChunk.document.kbId 与 system_knowledge_bases.id 不匹配');
|
||
|
||
// 检查 ekbDocument 的 kbId
|
||
console.log('\n 📋 检查 ekbDocument 表...');
|
||
const docs = await prisma.ekbDocument.findMany({
|
||
take: 5,
|
||
select: { id: true, kbId: true, fileName: true },
|
||
});
|
||
console.log(` ekbDocument 样本:`, docs.map(d => ({ id: d.id.substring(0, 8), kbId: d.kbId.substring(0, 8), name: d.fileName })));
|
||
|
||
console.log('\n 📋 检查 ekbKnowledgeBase 表...');
|
||
const allEkb = await prisma.ekbKnowledgeBase.findMany({
|
||
take: 5,
|
||
select: { id: true, name: true },
|
||
});
|
||
console.log(` ekbKnowledgeBase 样本:`, allEkb.map(kb => ({ id: kb.id.substring(0, 8), name: kb.name })));
|
||
|
||
console.log('\n 📋 检查 system_knowledge_bases 表...');
|
||
const allSystemKbs = await prisma.system_knowledge_bases.findMany({
|
||
take: 5,
|
||
select: { id: true, code: true, name: true },
|
||
});
|
||
console.log(` system_knowledge_bases 样本:`, allSystemKbs.map(kb => ({ id: kb.id.substring(0, 8), code: kb.code, name: kb.name })));
|
||
|
||
return;
|
||
}
|
||
|
||
// 合并内容
|
||
const knowledgeContent = chunks.map(c => c.content).join('\n\n');
|
||
console.log(`\n✅ 知识库内容加载成功,长度: ${knowledgeContent.length} 字符`);
|
||
console.log(` 预览: ${knowledgeContent.substring(0, 200).replace(/\n/g, ' ')}...`);
|
||
|
||
// 5. 注入到变量
|
||
const targetVariable = config.target_variable || 'context';
|
||
const enhancedVariables = { ...variables };
|
||
enhancedVariables[targetVariable] = knowledgeContent;
|
||
|
||
console.log(`\n📊 增强后的变量: { ${Object.keys(enhancedVariables).join(', ')} }`);
|
||
console.log(` ${targetVariable} 长度: ${enhancedVariables[targetVariable]?.length || 0} 字符`);
|
||
|
||
// 6. 渲染模板
|
||
const rendered = version.content.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
||
return enhancedVariables[key] || '';
|
||
});
|
||
|
||
console.log('\n📄 渲染后的 Prompt:');
|
||
console.log(' ' + rendered.substring(0, 500).replace(/\n/g, '\n ') + '...');
|
||
|
||
// 检查 {{context}} 是否被替换
|
||
if (rendered.includes('{{context}}')) {
|
||
console.log('\n❌ 问题: {{context}} 未被替换!');
|
||
} else {
|
||
console.log('\n✅ 成功: {{context}} 已被知识库内容替换!');
|
||
}
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
console.log('🧪 PromptService.get() 端到端测试\n');
|
||
|
||
// 测试已配置知识库的 Prompt
|
||
await testPromptServiceGet('AIA_SCIENTIFIC_QUESTION', {});
|
||
|
||
console.log('\n' + '='.repeat(60));
|
||
console.log('测试完成');
|
||
}
|
||
|
||
main()
|
||
.catch(console.error)
|
||
.finally(() => prisma.$disconnect());
|