mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-30 00:32:50 +00:00
perf: Extract field can use default value
This commit is contained in:
parent
fc743bbafd
commit
fa8c5dcd6d
|
|
@ -30,9 +30,10 @@ curl --location --request POST 'https://{{host}}/api/init/v469' \
|
|||
2. 新增 - 完善了HTTP模块的变量提示。
|
||||
3. 新增 - HTTP模块支持OpenAI单接口导入。
|
||||
4. 新增 - 全局变量支持增加外部变量。可通过分享链接的Query或 API 的 variables 参数传入。
|
||||
5. 优化 - 问题补全。增加英文类型。同时可以设置为单独模块,方便复用。
|
||||
6. 优化 - 重写了计量模式
|
||||
7. 优化 - Token 过滤历史记录,保持偶数条,防止部分模型报错。
|
||||
8. 优化 - 分享链接SEO,可直接展示应用名和头像。
|
||||
9. 修复 - 标注功能。
|
||||
10. 修复 - qa生成线程计数错误。
|
||||
5. 新增 - 内容提取模块增加默认值。
|
||||
6. 优化 - 问题补全。增加英文类型。同时可以设置为单独模块,方便复用。
|
||||
7. 优化 - 重写了计量模式
|
||||
8. 优化 - Token 过滤历史记录,保持偶数条,防止部分模型报错。
|
||||
9. 优化 - 分享链接SEO,可直接展示应用名和头像。
|
||||
10. 修复 - 标注功能。
|
||||
11. 修复 - qa生成线程计数错误。
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export const ContextExtractModule: FlowModuleTemplateType = {
|
|||
{
|
||||
key: ModuleOutputKeyEnum.failed,
|
||||
label: '提取字段缺失',
|
||||
description: '存在一个或多个字段未提取成功。尽管使用了默认值也算缺失。',
|
||||
valueType: ModuleIOValueTypeEnum.boolean,
|
||||
type: FlowNodeOutputTypeEnum.source,
|
||||
targets: []
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ export type ContextExtractAgentItemType = {
|
|||
desc: string;
|
||||
key: string;
|
||||
required: boolean;
|
||||
defaultValue?: string;
|
||||
enum?: string;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -317,6 +317,9 @@ importers:
|
|||
jschardet:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
json5:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3
|
||||
jsonwebtoken:
|
||||
specifier: ^9.0.2
|
||||
version: 9.0.2
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
"immer": "^9.0.19",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jschardet": "^3.0.0",
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mermaid": "^10.2.3",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
2. 新增 - 完善了HTTP模块的变量提示。
|
||||
3. 新增 - HTTP模块支持OpenAI单接口导入。
|
||||
4. 新增 - 全局变量支持增加外部变量。可通过分享链接的Query或 API 的 variables 参数传入。
|
||||
5. 优化 - 问题补全。增加英文类型。同时可以设置为单独模块,方便复用。
|
||||
6. [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
|
||||
7. [使用文档](https://doc.fastgpt.in/docs/intro/)
|
||||
8. [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)
|
||||
5. 新增 - 内容提取模块增加默认值。
|
||||
6. 优化 - 问题补全。增加英文类型。同时可以设置为单独模块,方便复用。
|
||||
7. [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
|
||||
8. [使用文档](https://doc.fastgpt.in/docs/intro/)
|
||||
9. [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)
|
||||
|
|
@ -774,6 +774,8 @@
|
|||
"Input description": "",
|
||||
"label": "Dataset quote"
|
||||
},
|
||||
"Default value": "Default ",
|
||||
"Default value placeholder": "Null characters are returned by default",
|
||||
"Field Description": "Description",
|
||||
"Field Name": "Name",
|
||||
"Field Type": "Type",
|
||||
|
|
@ -798,7 +800,9 @@
|
|||
"Enum Description": "Lists the possible values for the field, one per row",
|
||||
"Enum Value": "Enum",
|
||||
"Field Description Placeholder": "Name/age /sql statement......",
|
||||
"Field Setting Title": "Extract field configuration"
|
||||
"Field Setting Title": "Extract field configuration",
|
||||
"Required": "Required",
|
||||
"Required Description": "Even if the field cannot be extracted, it is returned with the default value"
|
||||
},
|
||||
"http": {
|
||||
"Add props": "Add props",
|
||||
|
|
|
|||
|
|
@ -561,7 +561,8 @@
|
|||
"success": "开始同步"
|
||||
}
|
||||
},
|
||||
"training": {}
|
||||
"training": {
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"Auxiliary Data": "辅助数据",
|
||||
|
|
@ -775,6 +776,8 @@
|
|||
"Input description": "可接收知识库搜索的结果。",
|
||||
"label": "知识库引用"
|
||||
},
|
||||
"Default value": "默认值",
|
||||
"Default value placeholder": "不填则默认返回空字符",
|
||||
"Field Description": "字段描述",
|
||||
"Field Name": "字段名",
|
||||
"Field Type": "字段类型",
|
||||
|
|
@ -799,7 +802,9 @@
|
|||
"Enum Description": "列举出该字段可能的值,每行一个",
|
||||
"Enum Value": "枚举值",
|
||||
"Field Description Placeholder": "姓名/年龄/sql语句……",
|
||||
"Field Setting Title": "提取字段配置"
|
||||
"Field Setting Title": "提取字段配置",
|
||||
"Required": "必须返回",
|
||||
"Required Description": "即使无法提取该字段,也会使用默认值进行返回"
|
||||
},
|
||||
"http": {
|
||||
"Add props": "添加参数",
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@ import { useTranslation } from 'next-i18next';
|
|||
import MyTooltip from '@/components/MyTooltip';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
|
||||
export const defaultField = {
|
||||
export const defaultField: ContextExtractAgentItemType = {
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
desc: '',
|
||||
key: '',
|
||||
required: true,
|
||||
enum: ''
|
||||
};
|
||||
|
||||
|
|
@ -33,9 +34,10 @@ const ExtractFieldModal = ({
|
|||
onSubmit: (data: ContextExtractAgentItemType) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { register, handleSubmit } = useForm<ContextExtractAgentItemType>({
|
||||
const { register, handleSubmit, watch } = useForm<ContextExtractAgentItemType>({
|
||||
defaultValues: defaultField
|
||||
});
|
||||
const required = watch('required');
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
|
|
@ -45,16 +47,31 @@ const ExtractFieldModal = ({
|
|||
onClose={onClose}
|
||||
>
|
||||
<ModalBody>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box flex={'0 0 70px'}>{t('common.Require Input')}</Box>
|
||||
<Flex mt={2} alignItems={'center'}>
|
||||
<Flex alignItems={'center'} flex={'0 0 80px'}>
|
||||
{t('core.module.extract.Required')}
|
||||
<MyTooltip label={t('core.module.extract.Required Description')} forceShow>
|
||||
<QuestionOutlineIcon ml={1} />
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
<Switch {...register('required')} />
|
||||
</Flex>
|
||||
{required && (
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'}>{t('core.module.Default value')}</Box>
|
||||
<Input
|
||||
placeholder={t('core.module.Default value placeholder')}
|
||||
{...register('defaultValue')}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 70px'}>{t('core.module.Field key')}</Box>
|
||||
<Box flex={'0 0 80px'}>{t('core.module.Field key')}</Box>
|
||||
<Input placeholder="name/age/sql" {...register('key', { required: true })} />
|
||||
</Flex>
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 70px'}>{t('core.module.Field Description')}</Box>
|
||||
<Box flex={'0 0 80px'}>{t('core.module.Field Description')}</Box>
|
||||
<Input
|
||||
placeholder={t('core.module.extract.Field Description Placeholder')}
|
||||
{...register('desc', { required: true })}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
|||
const newOutput = {
|
||||
key: data.key,
|
||||
label: `提取结果-${data.desc}`,
|
||||
description: '无法提取时不会返回',
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.source,
|
||||
targets: []
|
||||
|
|
|
|||
|
|
@ -31,10 +31,9 @@ export const Prompt_ExtractJson = `你可以从 <对话记录></对话记录>
|
|||
|
||||
<字段说明>
|
||||
1. 下面的 JSON 字符串均按照 JSON Schema 的规则描述。
|
||||
2. key 代表字段名;description 代表字段的描述;required 代表字段是否必须;enum 是可选值,代表可选的 value。
|
||||
3. 如果字段内容为空,你可以返回空字符串。
|
||||
|
||||
{{json}}
|
||||
2. key 代表字段名;description 代表字段的描述;enum 是可选值,代表可选的 value。
|
||||
3. 如果没有可提取的内容,忽略该字段。
|
||||
4. 本次需提取的JSON Schema:{{json}}
|
||||
</字段说明>
|
||||
|
||||
<对话记录>
|
||||
|
|
|
|||
|
|
@ -415,9 +415,9 @@ export async function getServerSideProps(context: any) {
|
|||
|
||||
return {
|
||||
props: {
|
||||
appName: app?.appId?.name,
|
||||
appAvatar: app?.appId?.avatar,
|
||||
appIntro: app?.appId?.intro,
|
||||
appName: app?.appId?.name || '',
|
||||
appAvatar: app?.appId?.avatar || '',
|
||||
appIntro: app?.appId?.intro || '',
|
||||
...(await serviceSideProps(context))
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
|||
import { getHistories } from '../utils';
|
||||
import { ModelTypeEnum, getLLMModel } from '@fastgpt/service/core/ai/model';
|
||||
import { formatModelChars2Points } from '@fastgpt/service/support/wallet/usage/utils';
|
||||
import json5 from 'json5';
|
||||
|
||||
type Props = ModuleDispatchProps<{
|
||||
[ModuleInputKeyEnum.history]?: ChatItemType[];
|
||||
|
|
@ -64,7 +65,8 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
|||
|
||||
// remove invalid key
|
||||
for (let key in arg) {
|
||||
if (!extractKeys.find((item) => item.key === key)) {
|
||||
const item = extractKeys.find((item) => item.key === key);
|
||||
if (!item) {
|
||||
delete arg[key];
|
||||
}
|
||||
if (arg[key] === '') {
|
||||
|
|
@ -72,12 +74,20 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
|||
}
|
||||
}
|
||||
|
||||
// auto fill required fields
|
||||
extractKeys.forEach((item) => {
|
||||
if (item.required && !arg[item.key]) {
|
||||
arg[item.key] = item.defaultValue || '';
|
||||
}
|
||||
});
|
||||
|
||||
// auth fields
|
||||
let success = !extractKeys.find((item) => !(item.key in arg));
|
||||
// auth empty value
|
||||
if (success) {
|
||||
for (const key in arg) {
|
||||
if (arg[key] === '') {
|
||||
const item = extractKeys.find((item) => item.key === key);
|
||||
if (!item) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -125,14 +135,8 @@ async function toolChoice({
|
|||
...histories,
|
||||
{
|
||||
obj: ChatRoleEnum.Human,
|
||||
value: `你的任务:
|
||||
value: `你的任务是根据上下文获取适当的 JSON 字符串。要求:
|
||||
"""
|
||||
${description || '根据用户要求获取适当的 JSON 字符串。'}
|
||||
"""
|
||||
|
||||
要求:
|
||||
"""
|
||||
- 如果字段为空,你返回空字符串。
|
||||
- 字符串不要换行。
|
||||
- 结合上下文和当前问题进行获取。
|
||||
"""
|
||||
|
|
@ -167,8 +171,7 @@ ${description || '根据用户要求获取适当的 JSON 字符串。'}
|
|||
description,
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties,
|
||||
required: extractKeys.filter((item) => item.required).map((item) => item.key)
|
||||
properties
|
||||
}
|
||||
};
|
||||
const tools: any = [
|
||||
|
|
@ -193,7 +196,7 @@ ${description || '根据用户要求获取适当的 JSON 字符串。'}
|
|||
|
||||
const arg: Record<string, any> = (() => {
|
||||
try {
|
||||
return JSON.parse(
|
||||
return json5.parse(
|
||||
response?.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments || '{}'
|
||||
);
|
||||
} catch (error) {
|
||||
|
|
@ -225,7 +228,7 @@ async function completions({
|
|||
json: extractKeys
|
||||
.map(
|
||||
(item) =>
|
||||
`{"key":"${item.key}", "description":"${item.desc}", "required":${item.required}${
|
||||
`{"key":"${item.key}", "description":"${item.desc}"${
|
||||
item.enum ? `, "enum":"[${item.enum.split('\n')}]"` : ''
|
||||
}}`
|
||||
)
|
||||
|
|
@ -240,7 +243,6 @@ Human: ${content}`
|
|||
userKey: user.openaiAccount,
|
||||
timeout: 480000
|
||||
});
|
||||
|
||||
const data = await ai.chat.completions.create({
|
||||
model: extractModel.model,
|
||||
temperature: 0.01,
|
||||
|
|
@ -260,19 +262,14 @@ Human: ${content}`
|
|||
arg: {}
|
||||
};
|
||||
|
||||
const jsonStr = answer
|
||||
.substring(start, end + 1)
|
||||
.replace(/(\\n|\\)/g, '')
|
||||
.replace(/ /g, '');
|
||||
|
||||
try {
|
||||
return {
|
||||
rawResponse: answer,
|
||||
tokens: countMessagesTokens(messages),
|
||||
|
||||
arg: JSON.parse(jsonStr) as Record<string, any>
|
||||
arg: json5.parse(answer) as Record<string, any>
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {
|
||||
rawResponse: answer,
|
||||
tokens: countMessagesTokens(messages),
|
||||
|
|
|
|||
Loading…
Reference in New Issue