fix(query): 知识库更新
- 修复切换知识库之后,检索结果没有刷新 - 修复文件上传模块 UI的边距、配色有问题
This commit is contained in:
parent
f1098f0c7d
commit
b23bbe023f
@ -13,9 +13,11 @@
|
|||||||
|
|
||||||
🐛**BUGs**
|
🐛**BUGs**
|
||||||
- [x] 智能体的工具切换有问题
|
- [x] 智能体的工具切换有问题
|
||||||
- [ ] 知识图谱可视化页面的效果有点问题
|
- [x] 知识图谱可视化页面的效果有点问题
|
||||||
- [x] 处理失败的文件,在特定情况下会一直处于 processing 状态,且无法删除
|
- [x] 处理失败的文件,在特定情况下会一直处于 processing 状态,且无法删除
|
||||||
- [ ] 与最新的 LightRAG 版本兼容性存在问题 #233
|
- [x] 与最新的 LightRAG 版本兼容性存在问题 #233
|
||||||
|
- [x] 切换知识库之后,检索结果没有刷新
|
||||||
|
- [x] 文件上传模块 UI的边距、配色有问题
|
||||||
|
|
||||||
# 💯 More:
|
# 💯 More:
|
||||||
|
|
||||||
@ -23,21 +25,6 @@
|
|||||||
|
|
||||||
- [ ] 封装现有工具为 mcp(stdio)调用
|
- [ ] 封装现有工具为 mcp(stdio)调用
|
||||||
- [ ] 支持额外 mcp 配置(代码端)
|
- [ ] 支持额外 mcp 配置(代码端)
|
||||||
- [ ] 添加用户日志与用户反馈模块,可以在 AgentView 中查看信息(🌟🌟)
|
- [ ] 添加用户日志与用户反馈模块,可以在 AgentView 中查看信息
|
||||||
- [ ] 对话页面支持文档/图片临时上传(🌟🌟🌟🌟)
|
- [ ] 对话页面支持文档/图片临时上传
|
||||||
- [ ] 优化对文档信息的检索展示(检索结果页、详情页)
|
- [ ] 优化对文档信息的检索展示(检索结果页、详情页)
|
||||||
|
|
||||||
|
|
||||||
TODO1:知识库页面的文档信息的查看(检索结果页、详情页)
|
|
||||||
|
|
||||||
根据这个模糊的分析,判断一下这个需求应该如何实现,务必阅读所有相关的文献,包括但不限于当前代码中,保存文本片段的时候所保存的信息是否支撑功能的实现,当某些需求无法实现的时候,能否采用退而求其次的方法实现略差一些的功能(不要过度增加代码的复杂度)。
|
|
||||||
|
|
||||||
模糊的需求如下:先实现在 FileTable.vue, FileDetailModal.vue 中,点击文件详情按钮,能够弹出文件详情的弹窗,显示的方法有两种,一种是以现在的 chunk 的形式展示,一种是以 markdown渲染全文的形式,但是存在 overlap 拼接的问题。
|
|
||||||
|
|
||||||
关于全文 Markdown 的获取:目前 Milvus、Chroma 知识库里面没有存储 fulltext,需要对现有的 chunk 片段做合并,但是因为存在 overlap,所以需要想办法去除 overlap。如果有 start_idx 和 end_idx 就好办了(不一定有这两个参数)。请注意,直接读取源文件的方法是错的,因为源文件并不全是 markdown 格式,可能是 html、pdf 等结构文件,因此,只能想办法拼接,而不是尝试读取文件。项目中已经安装了 md-editor-v3 ,可以参考 AgentMessageComponent.vue 中对于 markdown 的渲染。
|
|
||||||
|
|
||||||
先告诉我你要如何实现这些功能,重点实现的是 milvus db 和 chroma db ,lightrag db 尽量实现,实现不了也没事。相关的上下文如下 knowledge_router.py knowledge_base.py DataBaseInfoView.vue。
|
|
||||||
|
|
||||||
TODO2:检索以及知识库工具调用情况下的片段展示
|
|
||||||
|
|
||||||
result 中可以按照 file_id 聚合信息;信息的展示以结果卡片的形式展示,卡片之间有间隔,卡片中可以选择点击查看全文或者下载原文件。下载源文件需要根据 file_id 可以从后端获取文件的基本信息,比如可下载的路径,chunks 等信息;在 @web/src/components/ToolCallingResult/KnowledgeBaseResult.vue 文件中,添加点击某个片段的时候可以弹出信息预览框(最好可以提供源文件下载的功能)这里可以复用 FileDetailModal.vue 组件。
|
|
||||||
@ -455,12 +455,16 @@ const chunkData = async () => {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="less" scoped>
|
||||||
.add-files-content {
|
.add-files-content {
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
.ant-form-item {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-header {
|
.upload-header {
|
||||||
@ -477,20 +481,20 @@ const chunkData = async () => {
|
|||||||
|
|
||||||
.upload-mode-selector {
|
.upload-mode-selector {
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
border: 1px solid #d9d9d9;
|
border: 1px solid var(--gray-300);
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-mode-selector:hover {
|
.upload-mode-selector:hover {
|
||||||
border-color: #1890ff;
|
border-color: var(--main-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-mode-selector.active {
|
.upload-mode-selector.active {
|
||||||
border-color: #1890ff;
|
border-color: var(--main-color);
|
||||||
background-color: #e6f7ff;
|
background-color: var(--main-30);
|
||||||
color: #1890ff;
|
color: var(--main-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-controls {
|
.config-controls {
|
||||||
@ -502,8 +506,8 @@ const chunkData = async () => {
|
|||||||
.qa-split-config {
|
.qa-split-config {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
background-color: #fafafa;
|
background-color: var(--gray-50);
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-controls {
|
.toggle-controls {
|
||||||
@ -513,7 +517,7 @@ const chunkData = async () => {
|
|||||||
|
|
||||||
.param-description {
|
.param-description {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #8c8c8c;
|
color: var(--gray-600);
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,7 +535,7 @@ const chunkData = async () => {
|
|||||||
|
|
||||||
.url-hint {
|
.url-hint {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #8c8c8c;
|
color: var(--gray-600);
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,7 @@
|
|||||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||||
import { useDatabaseStore } from '@/stores/database';
|
import { useDatabaseStore } from '@/stores/database';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
import { queryApi } from '@/apis/knowledge_api';
|
||||||
import {
|
import {
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
SettingOutlined,
|
SettingOutlined,
|
||||||
@ -144,7 +145,7 @@ const meta = computed({
|
|||||||
get: () => store.meta,
|
get: () => store.meta,
|
||||||
set: (value) => Object.assign(store.meta, value)
|
set: (value) => Object.assign(store.meta, value)
|
||||||
});
|
});
|
||||||
const queryResult = computed(() => store.queryResult);
|
const queryResult = ref('');
|
||||||
|
|
||||||
// 查询测试
|
// 查询测试
|
||||||
const queryText = ref('');
|
const queryText = ref('');
|
||||||
@ -171,12 +172,47 @@ const toggleVisible = () => {
|
|||||||
emit('toggleVisible');
|
emit('toggleVisible');
|
||||||
};
|
};
|
||||||
|
|
||||||
const onQuery = () => {
|
const onQuery = async () => {
|
||||||
if (!queryText.value.trim()) {
|
if (!queryText.value.trim()) {
|
||||||
message.error('请输入查询内容');
|
message.error('请输入查询内容');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
store.onQuery(queryText.value.trim());
|
|
||||||
|
store.state.searchLoading = true;
|
||||||
|
|
||||||
|
// 确保只传递当前知识库类型支持的参数
|
||||||
|
const supportedParamKeys = new Set(queryParams.value.map(param => param.key));
|
||||||
|
const queryMeta = {};
|
||||||
|
|
||||||
|
console.log('Supported param keys:', Array.from(supportedParamKeys));
|
||||||
|
console.log('All meta params:', meta.value);
|
||||||
|
console.log('Database info:', store.database);
|
||||||
|
|
||||||
|
// 遍历 meta 中的参数,只保留当前知识库类型支持的参数
|
||||||
|
for (const [key, value] of Object.entries(meta.value)) {
|
||||||
|
// 跳过 db_id 参数
|
||||||
|
if (key === 'db_id') continue;
|
||||||
|
|
||||||
|
// 只保留当前知识库类型支持的参数
|
||||||
|
if (supportedParamKeys.has(key)) {
|
||||||
|
queryMeta[key] = value;
|
||||||
|
} else {
|
||||||
|
console.log(`Skipping unsupported parameter: ${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Filtered query meta:', queryMeta);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await queryApi.queryTest(store.database.db_id, queryText.value.trim(), queryMeta);
|
||||||
|
queryResult.value = data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
message.error(error.message);
|
||||||
|
queryResult.value = '';
|
||||||
|
} finally {
|
||||||
|
store.state.searchLoading = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const useQueryExample = (example) => {
|
const useQueryExample = (example) => {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export const useDatabaseStore = defineStore('database', () => {
|
|||||||
const database = ref({});
|
const database = ref({});
|
||||||
const databaseId = ref(null);
|
const databaseId = ref(null);
|
||||||
const selectedFile = ref(null);
|
const selectedFile = ref(null);
|
||||||
const queryResult = ref('');
|
|
||||||
const queryParams = ref([]);
|
const queryParams = ref([]);
|
||||||
const meta = reactive({});
|
const meta = reactive({});
|
||||||
const graphStats = ref({
|
const graphStats = ref({
|
||||||
@ -266,43 +266,7 @@ export const useDatabaseStore = defineStore('database', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onQuery(queryText) {
|
|
||||||
state.searchLoading = true;
|
|
||||||
queryResult.value = '';
|
|
||||||
|
|
||||||
// 确保只传递当前知识库类型支持的参数
|
|
||||||
const supportedParamKeys = new Set(queryParams.value.map(param => param.key));
|
|
||||||
const queryMeta = {};
|
|
||||||
|
|
||||||
console.log('Supported param keys:', Array.from(supportedParamKeys));
|
|
||||||
console.log('All meta params:', meta);
|
|
||||||
console.log('Database info:', database.value);
|
|
||||||
|
|
||||||
// 遍历 meta 中的参数,只保留当前知识库类型支持的参数
|
|
||||||
for (const [key, value] of Object.entries(meta)) {
|
|
||||||
// 跳过 db_id 参数
|
|
||||||
if (key === 'db_id') continue;
|
|
||||||
|
|
||||||
// 只保留当前知识库类型支持的参数
|
|
||||||
if (supportedParamKeys.has(key)) {
|
|
||||||
queryMeta[key] = value;
|
|
||||||
} else {
|
|
||||||
console.log(`Skipping unsupported parameter: ${key}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Filtered query meta:', queryMeta);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = await queryApi.queryTest(database.value.db_id, queryText, queryMeta);
|
|
||||||
queryResult.value = data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
message.error(error.message);
|
|
||||||
} finally {
|
|
||||||
state.searchLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function startAutoRefresh() {
|
function startAutoRefresh() {
|
||||||
if (state.autoRefresh && !refreshInterval) {
|
if (state.autoRefresh && !refreshInterval) {
|
||||||
@ -348,7 +312,6 @@ export const useDatabaseStore = defineStore('database', () => {
|
|||||||
database,
|
database,
|
||||||
databaseId,
|
databaseId,
|
||||||
selectedFile,
|
selectedFile,
|
||||||
queryResult,
|
|
||||||
queryParams,
|
queryParams,
|
||||||
meta,
|
meta,
|
||||||
graphStats,
|
graphStats,
|
||||||
@ -363,7 +326,7 @@ export const useDatabaseStore = defineStore('database', () => {
|
|||||||
addFiles,
|
addFiles,
|
||||||
openFileDetail,
|
openFileDetail,
|
||||||
loadQueryParams,
|
loadQueryParams,
|
||||||
onQuery,
|
|
||||||
startAutoRefresh,
|
startAutoRefresh,
|
||||||
stopAutoRefresh,
|
stopAutoRefresh,
|
||||||
toggleAutoRefresh,
|
toggleAutoRefresh,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user