Files
AIclinicalresearch/backend/src/common/prompt/__tests__/test-prompt-get.cjs
HaHafeng aaa29ea9d3 feat(admin): Implement Prompt knowledge base integration
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>
2026-02-01 20:26:20 +08:00

165 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 端到端测试 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());