feat: RAG回复显示知识库来源,含文件名和相似度分数
This commit is contained in:
@@ -2009,3 +2009,43 @@ body::before {
|
|||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RAG 知识库来源 */
|
||||||
|
.rag-sources {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: rgba(0, 245, 212, 0.05);
|
||||||
|
border: 1px solid rgba(0, 245, 212, 0.15);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.rag-sources-header {
|
||||||
|
color: var(--accent-cyan);
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
.rag-source-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 3px 0;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.rag-source-item + .rag-source-item {
|
||||||
|
border-top: 1px solid rgba(255,255,255,0.05);
|
||||||
|
}
|
||||||
|
.rag-source-name {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.rag-source-score {
|
||||||
|
color: var(--accent-green);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-left: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -193,6 +193,21 @@ export function appendMessageDOM(msg, index) {
|
|||||||
contentHtml += `<div class="msg-stats">${stats.map(s => `<span>${s}</span>`).join(' · ')}</div>`;
|
contentHtml += `<div class="msg-stats">${stats.map(s => `<span>${s}</span>`).join(' · ')}</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RAG 知识库来源
|
||||||
|
if (msg.role === 'assistant' && msg.ragSources && msg.ragSources.length > 0) {
|
||||||
|
const sourcesHtml = msg.ragSources.map((s, i) => {
|
||||||
|
const scorePercent = s.score ? `${(s.score * 100).toFixed(0)}%` : '';
|
||||||
|
return `<div class="rag-source-item">
|
||||||
|
<span class="rag-source-name">📄 来源 ${i + 1}: ${escapeHtml(s.filename)}</span>
|
||||||
|
${scorePercent ? `<span class="rag-source-score">${scorePercent}</span>` : ''}
|
||||||
|
</div>`;
|
||||||
|
}).join('');
|
||||||
|
contentHtml += `<div class="rag-sources">
|
||||||
|
<div class="rag-sources-header">🧠 基于知识库回答</div>
|
||||||
|
${sourcesHtml}
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<div class="msg-avatar">${avatar}</div>
|
<div class="msg-avatar">${avatar}</div>
|
||||||
<div class="msg-body">
|
<div class="msg-body">
|
||||||
|
|||||||
@@ -402,12 +402,19 @@ export async function sendMessage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// RAG 检索增强
|
// RAG 检索增强
|
||||||
|
let ragSources = null;
|
||||||
if (isRagEnabled()) {
|
if (isRagEnabled()) {
|
||||||
const ragResult = await performRagRetrieval(text);
|
const ragResult = await performRagRetrieval(text);
|
||||||
if (ragResult && ragResult.ragPrompt) {
|
if (ragResult && ragResult.ragPrompt) {
|
||||||
chatParams.system = chatParams.system
|
chatParams.system = chatParams.system
|
||||||
? chatParams.system + '\n\n' + ragResult.ragPrompt
|
? chatParams.system + '\n\n' + ragResult.ragPrompt
|
||||||
: ragResult.ragPrompt;
|
: ragResult.ragPrompt;
|
||||||
|
// 保存检索来源信息
|
||||||
|
ragSources = ragResult.results.map(r => ({
|
||||||
|
filename: r.filename,
|
||||||
|
score: r.score,
|
||||||
|
text: truncate(r.text, 100)
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +441,8 @@ export async function sendMessage() {
|
|||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
...(modelName && { model: modelName }),
|
...(modelName && { model: modelName }),
|
||||||
...(thinkContent && { think: thinkContent }),
|
...(thinkContent && { think: thinkContent }),
|
||||||
...(finalStats && { eval_count: finalStats.eval_count, total_duration: finalStats.total_duration })
|
...(finalStats && { eval_count: finalStats.eval_count, total_duration: finalStats.total_duration }),
|
||||||
|
...(ragSources && { ragSources })
|
||||||
};
|
};
|
||||||
currentSession.messages.push(assistantMsg);
|
currentSession.messages.push(assistantMsg);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user