Skip to content

Commit a345e56

Browse files
committed
simple mode tool reason (#3984)
* simple mode tool reason * model config cannot set empty * perf: read files code * perf: mongo gridfs chunks * perf: doc
1 parent 32ce032 commit a345e56

File tree

10 files changed

+92
-22
lines changed

10 files changed

+92
-22
lines changed

docSite/content/zh-cn/docs/development/upgrading/490.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ curl --location --request POST 'https://{{host}}/api/admin/initv490' \
4747
1. 知识库数据不再限制索引数量,可无限自定义。同时可自动更新输入文本的索引,不影响自定义索引。
4848
2. Markdown 解析,增加链接后中文标点符号检测,增加空格。
4949
3. Prompt 模式工具调用,支持思考模型。同时优化其格式检测,减少空输出的概率。
50+
4. Mongo 文件读取流合并,减少计算量。同时优化存储 chunks,极大提高大文件读取速度。50M PDF 读取时间提高 3 倍。
5051

5152
## 🐛 修复
5253

packages/service/common/file/gridfs/controller.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ export async function uploadFile({
5252
const stats = await fsp.stat(path);
5353
if (!stats.isFile()) return Promise.reject(`${path} is not a file`);
5454

55-
const readStream = fs.createReadStream(path);
55+
const readStream = fs.createReadStream(path, {
56+
highWaterMark: 256 * 1024
57+
});
5658

5759
// Add default metadata
5860
metadata.teamId = teamId;
@@ -62,9 +64,27 @@ export async function uploadFile({
6264
// create a gridfs bucket
6365
const bucket = getGridBucket(bucketName);
6466

67+
const fileSize = stats.size;
68+
const chunkSizeBytes = (() => {
69+
// 计算理想块大小:文件大小 ÷ 目标块数(10)
70+
const idealChunkSize = Math.ceil(fileSize / 10);
71+
72+
// 确保块大小至少为512KB
73+
const minChunkSize = 512 * 1024; // 512KB
74+
75+
// 取理想块大小和最小块大小中的较大值
76+
let chunkSize = Math.max(idealChunkSize, minChunkSize);
77+
78+
// 将块大小向上取整到最接近的64KB的倍数,使其更整齐
79+
chunkSize = Math.ceil(chunkSize / (64 * 1024)) * (64 * 1024);
80+
81+
return chunkSize;
82+
})();
83+
6584
const stream = bucket.openUploadStream(filename, {
6685
metadata,
67-
contentType
86+
contentType,
87+
chunkSizeBytes
6888
});
6989

7090
// save to gridfs

packages/service/common/file/gridfs/utils.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ import { PassThrough } from 'stream';
33

44
export const gridFsStream2Buffer = (stream: NodeJS.ReadableStream) => {
55
return new Promise<Buffer>((resolve, reject) => {
6-
const chunks: Buffer[] = [];
7-
let totalLength = 0;
6+
const chunks: Uint8Array[] = [];
87

98
stream.on('data', (chunk) => {
109
chunks.push(chunk);
11-
totalLength += chunk.length;
1210
});
1311
stream.on('end', () => {
14-
const resultBuffer = Buffer.concat(chunks, totalLength); // 一次性拼接
12+
const resultBuffer = Buffer.concat(chunks); // 一次性拼接
1513
resolve(resultBuffer);
1614
});
1715
stream.on('error', (err) => {
@@ -21,25 +19,26 @@ export const gridFsStream2Buffer = (stream: NodeJS.ReadableStream) => {
2119
};
2220

2321
export const stream2Encoding = async (stream: NodeJS.ReadableStream) => {
24-
const start = Date.now();
2522
const copyStream = stream.pipe(new PassThrough());
2623

2724
/* get encoding */
2825
const buffer = await (() => {
2926
return new Promise<Buffer>((resolve, reject) => {
30-
let tmpBuffer: Buffer = Buffer.from([]);
27+
const chunks: Uint8Array[] = [];
28+
let totalLength = 0;
3129

3230
stream.on('data', (chunk) => {
33-
if (tmpBuffer.length < 200) {
34-
tmpBuffer = Buffer.concat([tmpBuffer, chunk]);
31+
if (totalLength < 200) {
32+
chunks.push(chunk);
33+
totalLength += chunk.length;
3534

36-
if (tmpBuffer.length >= 200) {
37-
resolve(tmpBuffer);
35+
if (totalLength >= 200) {
36+
resolve(Buffer.concat(chunks));
3837
}
3938
}
4039
});
4140
stream.on('end', () => {
42-
resolve(tmpBuffer);
41+
resolve(Buffer.concat(chunks));
4342
});
4443
stream.on('error', (err) => {
4544
reject(err);

packages/service/core/ai/audio/speech.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ export async function text2Speech({
4343
const readableStream = response.body as unknown as NodeJS.ReadableStream;
4444
readableStream.pipe(res);
4545

46-
let bufferStore = Buffer.from([]);
46+
const chunks: Uint8Array[] = [];
4747

4848
readableStream.on('data', (chunk) => {
49-
bufferStore = Buffer.concat([bufferStore, chunk]);
49+
chunks.push(chunk);
5050
});
5151
readableStream.on('end', () => {
52-
onSuccess({ model, buffer: bufferStore });
52+
onSuccess({ model, buffer: Buffer.concat(chunks) });
5353
});
5454
readableStream.on('error', (e) => {
5555
onError(e);

packages/service/core/ai/config/provider/DeepSeek.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
"defaultConfig": {},
4747
"fieldMap": {},
4848
"type": "llm",
49-
"showTopP": true,
50-
"showStopSign": true
49+
"showTopP": false,
50+
"showStopSign": false
5151
}
5252
]
5353
}

packages/web/i18n/en/account_model.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
"edit_channel": "Channel configuration",
2222
"enable_channel": "Enable",
2323
"forbid_channel": "Disabled",
24+
"input maxToken_tip": "The model max_tokens parameter, if left blank, means that the model does not support it.",
2425
"key_type": "API key format:",
2526
"log": "Call log",
2627
"log_detail": "Log details",
2728
"log_request_id_search": "Search by requestId",
2829
"log_status": "Status",
2930
"mapping": "Model Mapping",
3031
"mapping_tip": "A valid Json is required. \nThe model can be mapped when sending a request to the actual address. \nFor example:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\nWhen FastGPT requests the gpt-4o model, the gpt-4o-test model is sent to the actual address, instead of gpt-4o.",
32+
"max_temperature_tip": "If the model temperature parameter is not filled in, it means that the model does not support the temperature parameter.",
3133
"model": "Model",
3234
"model_name": "Model name",
3335
"model_test": "Model testing",

packages/web/i18n/zh-CN/account_model.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
"edit_channel": "渠道配置",
2222
"enable_channel": "启用",
2323
"forbid_channel": "禁用",
24+
"input maxToken_tip": "模型 max_tokens 参数,如果留空,则代表模型不支持该参数。",
2425
"key_type": "API key 格式: ",
2526
"log": "调用日志",
2627
"log_detail": "日志详情",
2728
"log_request_id_search": "根据 requestId 搜索",
2829
"log_status": "状态",
2930
"mapping": "模型映射",
3031
"mapping_tip": "需填写一个有效 Json。可在向实际地址发送请求时,对模型进行映射。例如:\n{\n \"gpt-4o\": \"gpt-4o-test\"\n}\n当 FastGPT 请求 gpt-4o 模型时,会向实际地址发送 gpt-4o-test 的模型,而不是 gpt-4o。",
32+
"max_temperature_tip": "模型 temperature 参数,不填则代表模型不支持 temperature 参数。",
3133
"model": "模型",
3234
"model_name": "模型名",
3335
"model_test": "模型测试",

packages/web/i18n/zh-Hant/account_model.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
"edit_channel": "渠道配置",
2020
"enable_channel": "啟用",
2121
"forbid_channel": "禁用",
22+
"input maxToken_tip": "模型 max_tokens 參數,如果留空,則代表模型不支持該參數。",
2223
"key_type": "API key 格式:",
2324
"log": "調用日誌",
2425
"log_detail": "日誌詳情",
2526
"log_request_id_search": "根據 requestId 搜索",
2627
"log_status": "狀態",
2728
"mapping": "模型映射",
2829
"mapping_tip": "需填寫一個有效 Json。\n可在向實際地址發送請求時,對模型進行映射。\n例如:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\n當 FastGPT 請求 gpt-4o 模型時,會向實際地址發送 gpt-4o-test 的模型,而不是 gpt-4o。",
30+
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支持 temperature 參數。",
2931
"model": "模型",
3032
"model_name": "模型名",
3133
"model_test": "模型測試",

projects/app/src/pageComponents/account/model/AddModelBox.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
3838
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
3939
import { Prompt_CQJson, Prompt_ExtractJson } from '@fastgpt/global/core/ai/prompt/agent';
4040
import MyModal from '@fastgpt/web/components/common/MyModal';
41+
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
4142

4243
export const AddModelButton = ({
4344
onCreate,
@@ -134,6 +135,14 @@ export const ModelEditModal = ({
134135

135136
const { runAsync: updateModel, loading: updatingModel } = useRequest2(
136137
async (data: SystemModelItemType) => {
138+
for (const key in data) {
139+
// @ts-ignore
140+
const val = data[key];
141+
if (val === null || val === undefined || Number.isNaN(val)) {
142+
// @ts-ignore
143+
data[key] = '';
144+
}
145+
}
137146
return putSystemModel({
138147
model: data.model,
139148
metadata: data
@@ -295,7 +304,16 @@ export const ModelEditModal = ({
295304
{isLLMModel && (
296305
<>
297306
<Tr>
298-
<Td>{t('common:core.ai.Max context')}</Td>
307+
<Td>
308+
<FormLabel
309+
required
310+
color={'myGray.600'}
311+
fontSize={'md'}
312+
fontWeight={'normal'}
313+
>
314+
{t('common:core.ai.Max context')}
315+
</FormLabel>
316+
</Td>
299317
<Td textAlign={'right'}>
300318
<Flex justifyContent={'flex-end'}>
301319
<MyNumberInput
@@ -308,7 +326,16 @@ export const ModelEditModal = ({
308326
</Td>
309327
</Tr>
310328
<Tr>
311-
<Td>{t('account:model.max_quote')}</Td>
329+
<Td>
330+
<FormLabel
331+
required
332+
color={'myGray.600'}
333+
fontSize={'md'}
334+
fontWeight={'normal'}
335+
>
336+
{t('account:model.max_quote')}
337+
</FormLabel>
338+
</Td>
312339
<Td textAlign={'right'}>
313340
<Flex justifyContent={'flex-end'}>
314341
<MyNumberInput
@@ -321,15 +348,25 @@ export const ModelEditModal = ({
321348
</Td>
322349
</Tr>
323350
<Tr>
324-
<Td>{t('common:core.chat.response.module maxToken')}</Td>
351+
<Td>
352+
<HStack spacing={1}>
353+
<Box>{t('common:core.chat.response.module maxToken')}</Box>
354+
<QuestionTip label={t('account_model:input maxToken_tip')} />
355+
</HStack>
356+
</Td>
325357
<Td textAlign={'right'}>
326358
<Flex justifyContent={'flex-end'}>
327359
<MyNumberInput register={register} name="maxResponse" {...InputStyles} />
328360
</Flex>
329361
</Td>
330362
</Tr>
331363
<Tr>
332-
<Td>{t('account:model.max_temperature')}</Td>
364+
<Td>
365+
<HStack spacing={1}>
366+
<Box>{t('account:model.max_temperature')}</Box>
367+
<QuestionTip label={t('account_model:max_temperature_tip')} />
368+
</HStack>
369+
</Td>
333370
<Td textAlign={'right'}>
334371
<Flex justifyContent={'flex-end'}>
335372
<MyNumberInput

projects/app/src/web/core/app/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,13 @@ export function form2AppWorkflow(
504504
label: '',
505505
valueType: WorkflowIOValueTypeEnum.boolean,
506506
value: true
507+
},
508+
{
509+
key: NodeInputKeyEnum.aiChatReasoning,
510+
renderTypeList: [FlowNodeInputTypeEnum.hidden],
511+
label: '',
512+
valueType: WorkflowIOValueTypeEnum.boolean,
513+
value: formData.aiSettings.aiChatReasoning
507514
}
508515
],
509516
outputs: ToolModule.outputs

0 commit comments

Comments
 (0)