mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
feat: csv导入去重;文档说明
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
接受一个csv文件,表格头包含 question 和 answer。question 代表问题,answer 代表答案。
|
||||
导入前会进行去重,如果问题和答案完全相同,则不会被导入,所以最终导入的内容可能会比文件的内容少。
|
||||
| question | answer |
|
||||
| --- | --- |
|
||||
| 什么是 laf | laf 是一个云函数开发平台…… |
|
||||
|
@@ -1,3 +1,3 @@
|
||||
## Fast GPT V2.5
|
||||
* 内容压缩,替换中文标点符号和多余符号,减少一些上下文tokens。
|
||||
* 优化 QA 拆分记账。
|
||||
## Fast GPT V2.7
|
||||
* FastGpt Api 允许你将 Fast Gpt 的部分功能通过 api 的形式,将知识库接入到自己的应用中,例如:飞书、企业微信、客服助手.
|
||||
* 通过 csv 文件导入和导出你的问答对。你可以将你的 csv 文件放置在飞书文档上,以便团队共享。
|
@@ -91,7 +91,7 @@ export const postModelDataSplitData = (data: { modelId: string; text: string; pr
|
||||
* json导入数据
|
||||
*/
|
||||
export const postModelDataCsvData = (modelId: string, data: string[][]) =>
|
||||
POST(`/model/data/pushModelDataCsv`, { modelId, data: data });
|
||||
POST<number>(`/model/data/pushModelDataCsv`, { modelId, data: data });
|
||||
|
||||
/**
|
||||
* 更新模型数据
|
||||
|
@@ -3,9 +3,9 @@ import { jsonRes } from '@/service/response';
|
||||
import { connectToDatabase, Model } from '@/service/mongo';
|
||||
import { authToken } from '@/service/utils/tools';
|
||||
import { generateVector } from '@/service/events/generateVector';
|
||||
import { vectorToBuffer, formatVector } from '@/utils/tools';
|
||||
import { connectRedis } from '@/service/redis';
|
||||
import { VecModelDataPrefix, ModelDataStatusEnum } from '@/constants/redis';
|
||||
import { VecModelDataIdx } from '@/constants/redis';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
||||
|
||||
@@ -41,9 +41,35 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
throw new Error('无权操作该模型');
|
||||
}
|
||||
|
||||
// 去重
|
||||
const searchRes = await Promise.allSettled(
|
||||
data.map(async ([q, a]) => {
|
||||
try {
|
||||
q = q.replace(/\\n/g, '\n');
|
||||
a = a.replace(/\\n/g, '\n');
|
||||
const redisSearch = await redis.ft.search(VecModelDataIdx, `@q:${q} @text:${a}`, {
|
||||
RETURN: ['q', 'text']
|
||||
});
|
||||
if (redisSearch.total > 0) {
|
||||
return Promise.reject('已经存在');
|
||||
}
|
||||
} catch (error) {
|
||||
error;
|
||||
}
|
||||
return Promise.resolve({
|
||||
q,
|
||||
a
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const filterData = searchRes
|
||||
.filter((item) => item.status === 'fulfilled')
|
||||
.map<{ q: string; a: string }>((item: any) => item.value);
|
||||
|
||||
// 插入 redis
|
||||
const insertRedisRes = await Promise.allSettled(
|
||||
data.map((item) => {
|
||||
filterData.map((item) => {
|
||||
return redis.sendCommand([
|
||||
'HMSET',
|
||||
`${VecModelDataPrefix}:${nanoid()}`,
|
||||
@@ -52,9 +78,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
'modelId',
|
||||
String(modelId),
|
||||
'q',
|
||||
item[0],
|
||||
item.q,
|
||||
'text',
|
||||
item[1],
|
||||
item.a,
|
||||
'status',
|
||||
ModelDataStatusEnum.waiting
|
||||
]);
|
||||
@@ -64,7 +90,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
generateVector();
|
||||
|
||||
jsonRes(res, {
|
||||
data: insertRedisRes.filter((item) => item.status === 'rejected').length
|
||||
data: insertRedisRes.filter((item) => item.status === 'fulfilled').length
|
||||
});
|
||||
} catch (err) {
|
||||
jsonRes(res, {
|
||||
|
@@ -64,10 +64,11 @@ const SelectJsonModal = ({
|
||||
const { mutate, isLoading } = useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!fileData) return;
|
||||
await postModelDataCsvData(modelId, fileData);
|
||||
const res = await postModelDataCsvData(modelId, fileData);
|
||||
toast({
|
||||
title: '导入数据成功,需要一段时间训练',
|
||||
status: 'success'
|
||||
title: `导入数据成功,最终导入: ${res || 0} 条数据。需要一段时间训练`,
|
||||
status: 'success',
|
||||
duration: 4000
|
||||
});
|
||||
onClose();
|
||||
onSuccess();
|
||||
@@ -90,7 +91,7 @@ const SelectJsonModal = ({
|
||||
<ModalCloseButton />
|
||||
|
||||
<ModalBody h={'100%'} display={['block', 'flex']} fontSize={'sm'} overflowY={'auto'}>
|
||||
<Box flex={'1 0 0'} w={['100%', 0]} mr={[0, 4]} mb={[4, 0]}>
|
||||
<Box flex={'2 0 0'} w={['100%', 0]} mr={[0, 4]} mb={[4, 0]}>
|
||||
<Markdown source={intro} />
|
||||
<Box
|
||||
my={3}
|
||||
@@ -115,7 +116,7 @@ const SelectJsonModal = ({
|
||||
<Box ml={4}>一共 {fileData.length} 组数据</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Box flex={'2 0 0'} h={'100%'} overflow={'auto'} p={2} backgroundColor={'blackAlpha.50'}>
|
||||
<Box flex={'3 0 0'} h={'100%'} overflow={'auto'} p={2} backgroundColor={'blackAlpha.50'}>
|
||||
{fileData.map((item, index) => (
|
||||
<Box key={index}>
|
||||
<Box>
|
||||
|
@@ -55,10 +55,11 @@ const OpenApi = () => {
|
||||
<>
|
||||
<Card px={6} py={4} position={'relative'}>
|
||||
<Box fontSize={'xl'} fontWeight={'bold'}>
|
||||
Open Api
|
||||
FastGpt Api
|
||||
</Box>
|
||||
<Box fontSize={'sm'} mt={2}>
|
||||
Open Api 允许你将 Fast Gpt 的部分功能通过 api 的形式接入到自己的应用中。请注意保管你的 Api
|
||||
FastGpt Api 允许你将 Fast Gpt 的部分功能通过 api
|
||||
的形式接入到自己的应用中,例如:飞书、企业微信、客服助手。请注意保管你的 Api
|
||||
Key,不要泄露!
|
||||
</Box>
|
||||
<Box
|
||||
|
Reference in New Issue
Block a user