mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-20 21:06:54 +08:00
### What problem does this PR solve? Feat: Change the corresponding prompt word according to the value of fieldName #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1712,6 +1712,53 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
questions: 'Questions',
|
questions: 'Questions',
|
||||||
metadata: 'Metadata',
|
metadata: 'Metadata',
|
||||||
fieldName: 'Result Destination',
|
fieldName: 'Result Destination',
|
||||||
|
prompts: {
|
||||||
|
system: {
|
||||||
|
keywords: `Role
|
||||||
|
You are a text analyzer.
|
||||||
|
|
||||||
|
Task
|
||||||
|
Extract the most important keywords/phrases of a given piece of text content.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
- Summarize the text content, and give the top 5 important keywords/phrases.
|
||||||
|
- The keywords MUST be in the same language as the given piece of text content.
|
||||||
|
- The keywords are delimited by ENGLISH COMMA.
|
||||||
|
- Output keywords ONLY.`,
|
||||||
|
questions: `Role
|
||||||
|
You are a text analyzer.
|
||||||
|
|
||||||
|
Task
|
||||||
|
Propose 3 questions about a given piece of text content.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
- Understand and summarize the text content, and propose the top 3 important questions.
|
||||||
|
- The questions SHOULD NOT have overlapping meanings.
|
||||||
|
- The questions SHOULD cover the main content of the text as much as possible.
|
||||||
|
- The questions MUST be in the same language as the given piece of text content.
|
||||||
|
- One question per line.
|
||||||
|
- Output questions ONLY.`,
|
||||||
|
summary: `Act as a precise summarizer. Your task is to create a summary of the provided content that is both concise and faithful to the original.
|
||||||
|
|
||||||
|
Key Instructions:
|
||||||
|
1. Accuracy: Strictly base the summary on the information given. Do not introduce any new facts, conclusions, or interpretations that are not explicitly stated.
|
||||||
|
2. Language: Write the summary in the same language as the source text.
|
||||||
|
3. Objectivity: Present the key points without bias, preserving the original intent and tone of the content. Do not editorialize.
|
||||||
|
4. Conciseness: Focus on the most important ideas, omitting minor details and fluff.`,
|
||||||
|
metadata: `Extract important structured information from the given content. Output ONLY a valid JSON string with no additional text. If no important structured information is found, output an empty JSON object: {}.
|
||||||
|
|
||||||
|
Important structured information may include: names, dates, locations, events, key facts, numerical data, or other extractable entities.`,
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
keywords: `Text Content
|
||||||
|
[Insert text here]`,
|
||||||
|
questions: `Text Content
|
||||||
|
[Insert text here]`,
|
||||||
|
summary: `Text to Summarize:
|
||||||
|
[Insert text here]`,
|
||||||
|
metadata: `Content: [INSERT CONTENT HERE]`,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1630,6 +1630,53 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
questions: '问题',
|
questions: '问题',
|
||||||
metadata: '元数据',
|
metadata: '元数据',
|
||||||
fieldName: '结果目的地',
|
fieldName: '结果目的地',
|
||||||
|
prompts: {
|
||||||
|
system: {
|
||||||
|
keywords: `角色
|
||||||
|
你是一名文本分析员。
|
||||||
|
|
||||||
|
任务
|
||||||
|
从给定的文本内容中提取最重要的关键词/短语。
|
||||||
|
|
||||||
|
要求
|
||||||
|
- 总结文本内容,并给出最重要的5个关键词/短语。
|
||||||
|
- 关键词必须与给定的文本内容使用相同的语言。
|
||||||
|
- 关键词之间用英文逗号分隔。
|
||||||
|
- 仅输出关键词。`,
|
||||||
|
questions: `角色
|
||||||
|
你是一名文本分析员。
|
||||||
|
|
||||||
|
任务
|
||||||
|
针对给定的文本内容提出3个问题。
|
||||||
|
|
||||||
|
要求
|
||||||
|
- 理解并总结文本内容,并提出最重要的3个问题。
|
||||||
|
- 问题的含义不应重叠。
|
||||||
|
- 问题应尽可能涵盖文本的主要内容。
|
||||||
|
- 问题必须与给定的文本内容使用相同的语言。
|
||||||
|
- 每行一个问题。
|
||||||
|
- 仅输出问题。`,
|
||||||
|
summary: `扮演一个精准的摘要者。你的任务是为提供的内容创建一个简洁且忠实于原文的摘要。
|
||||||
|
|
||||||
|
关键说明:
|
||||||
|
1. 准确性:摘要必须严格基于所提供的信息。请勿引入任何未明确说明的新事实、结论或解释。
|
||||||
|
2. 语言:摘要必须使用与原文相同的语言。
|
||||||
|
3. 客观性:不带偏见地呈现要点,保留内容的原始意图和语气。请勿进行编辑。
|
||||||
|
4. 简洁性:专注于最重要的思想,省略细节和多余的内容。`,
|
||||||
|
metadata: `从给定内容中提取重要的结构化信息。仅输出有效的 JSON 字符串,不包含任何附加文本。如果未找到重要的结构化信息,则输出一个空的 JSON 对象:{}。
|
||||||
|
|
||||||
|
重要的结构化信息可能包括:姓名、日期、地点、事件、关键事实、数字数据或其他可提取实体。`,
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
keywords: `文本内容
|
||||||
|
[在此处插入文本]`,
|
||||||
|
questions: `文本内容
|
||||||
|
[在此处插入文本]`,
|
||||||
|
summary: `要总结的文本:
|
||||||
|
[在此处插入文本]`,
|
||||||
|
metadata: `内容:[在此处插入内容]`,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -131,12 +131,12 @@ export default function VariablePickerMenuPlugin({
|
|||||||
baseOptions,
|
baseOptions,
|
||||||
}: VariablePickerMenuPluginProps): JSX.Element {
|
}: VariablePickerMenuPluginProps): JSX.Element {
|
||||||
const [editor] = useLexicalComposerContext();
|
const [editor] = useLexicalComposerContext();
|
||||||
const isFirstRender = useRef(true);
|
|
||||||
|
|
||||||
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('/', {
|
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('/', {
|
||||||
minLength: 0,
|
minLength: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const previousValue = useRef<string | undefined>();
|
||||||
|
|
||||||
const [queryString, setQueryString] = React.useState<string | null>('');
|
const [queryString, setQueryString] = React.useState<string | null>('');
|
||||||
|
|
||||||
let options = useBuildQueryVariableOptions();
|
let options = useBuildQueryVariableOptions();
|
||||||
@ -280,8 +280,8 @@ export default function VariablePickerMenuPlugin({
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editor && value && isFirstRender.current) {
|
if (editor && value && value !== previousValue.current) {
|
||||||
isFirstRender.current = false;
|
previousValue.current = value;
|
||||||
editor.update(
|
editor.update(
|
||||||
() => {
|
() => {
|
||||||
parseTextToVariableNodes(value);
|
parseTextToVariableNodes(value);
|
||||||
|
|||||||
@ -256,6 +256,23 @@ export const initialParserValues = {
|
|||||||
fields: Object.values(ParserFields),
|
fields: Object.values(ParserFields),
|
||||||
output_format: EmailOutputFormat.Text,
|
output_format: EmailOutputFormat.Text,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fileFormat: FileType.TextMarkdown,
|
||||||
|
output_format: TextMarkdownOutputFormat.Text,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fileFormat: FileType.Docx,
|
||||||
|
output_format: DocxOutputFormat.Json,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fileFormat: FileType.PowerPoint,
|
||||||
|
output_format: PptOutputFormat.Json,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fileFormat: FileType.Audio,
|
||||||
|
llm_id: '',
|
||||||
|
output_format: AudioOutputFormat.Text,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,7 +306,7 @@ export const initialHierarchicalMergerValues = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialContextValues = {
|
export const initialExtractorValues = {
|
||||||
...initialLlmBaseValues,
|
...initialLlmBaseValues,
|
||||||
field_name: ContextGeneratorFieldName.Summary,
|
field_name: ContextGeneratorFieldName.Summary,
|
||||||
outputs: {},
|
outputs: {},
|
||||||
@ -318,6 +335,7 @@ export const RestrictedUpstreamMap = {
|
|||||||
[Operator.Splitter]: [Operator.Begin],
|
[Operator.Splitter]: [Operator.Begin],
|
||||||
[Operator.HierarchicalMerger]: [Operator.Begin],
|
[Operator.HierarchicalMerger]: [Operator.Begin],
|
||||||
[Operator.Tokenizer]: [Operator.Begin],
|
[Operator.Tokenizer]: [Operator.Begin],
|
||||||
|
[Operator.Extractor]: [Operator.Begin],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NodeMap = {
|
export const NodeMap = {
|
||||||
|
|||||||
@ -6,13 +6,13 @@ import { Form } from '@/components/ui/form';
|
|||||||
import { PromptEditor } from '@/pages/agent/form/components/prompt-editor';
|
import { PromptEditor } from '@/pages/agent/form/components/prompt-editor';
|
||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { memo } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import {
|
import {
|
||||||
ContextGeneratorFieldName,
|
ContextGeneratorFieldName,
|
||||||
initialContextValues,
|
initialExtractorValues,
|
||||||
} from '../../constant';
|
} from '../../constant';
|
||||||
import { useBuildNodeOutputOptions } from '../../hooks/use-build-options';
|
import { useBuildNodeOutputOptions } from '../../hooks/use-build-options';
|
||||||
import { useFormValues } from '../../hooks/use-form-values';
|
import { useFormValues } from '../../hooks/use-form-values';
|
||||||
@ -21,27 +21,48 @@ import { INextOperatorForm } from '../../interface';
|
|||||||
import { FormWrapper } from '../components/form-wrapper';
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
|
|
||||||
export const FormSchema = z.object({
|
export const FormSchema = z.object({
|
||||||
|
field_name: z.string(),
|
||||||
sys_prompt: z.string(),
|
sys_prompt: z.string(),
|
||||||
prompts: z.string().optional(),
|
prompts: z.string().optional(),
|
||||||
...LlmSettingSchema,
|
...LlmSettingSchema,
|
||||||
field_name: z.array(z.string()),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ExtractorFormSchemaType = z.infer<typeof FormSchema>;
|
export type ExtractorFormSchemaType = z.infer<typeof FormSchema>;
|
||||||
|
|
||||||
const ExtractorForm = ({ node }: INextOperatorForm) => {
|
const ExtractorForm = ({ node }: INextOperatorForm) => {
|
||||||
const defaultValues = useFormValues(initialContextValues, node);
|
const defaultValues = useFormValues(initialExtractorValues, node);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const form = useForm<ExtractorFormSchemaType>({
|
const form = useForm<ExtractorFormSchemaType>({
|
||||||
defaultValues,
|
defaultValues,
|
||||||
resolver: zodResolver(FormSchema),
|
resolver: zodResolver(FormSchema),
|
||||||
|
// mode: 'onChange',
|
||||||
});
|
});
|
||||||
|
|
||||||
const promptOptions = useBuildNodeOutputOptions(node?.id);
|
const promptOptions = useBuildNodeOutputOptions(node?.id);
|
||||||
|
|
||||||
const options = buildOptions(ContextGeneratorFieldName, t, 'dataflow');
|
const options = buildOptions(ContextGeneratorFieldName, t, 'dataflow');
|
||||||
|
|
||||||
|
const setPromptValue = useCallback(
|
||||||
|
(field: keyof ExtractorFormSchemaType, key: string, value: string) => {
|
||||||
|
form.setValue(field, t(`dataflow.prompts.${key}.${value}`), {
|
||||||
|
shouldDirty: true,
|
||||||
|
shouldValidate: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[form, t],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleFieldNameChange = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
if (value) {
|
||||||
|
setPromptValue('sys_prompt', 'system', value);
|
||||||
|
setPromptValue('prompts', 'user', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setPromptValue],
|
||||||
|
);
|
||||||
|
|
||||||
useWatchFormChange(node?.id, form);
|
useWatchFormChange(node?.id, form);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -51,7 +72,11 @@ const ExtractorForm = ({ node }: INextOperatorForm) => {
|
|||||||
<RAGFlowFormItem label={t('dataflow.fieldName')} name="field_name">
|
<RAGFlowFormItem label={t('dataflow.fieldName')} name="field_name">
|
||||||
{(field) => (
|
{(field) => (
|
||||||
<SelectWithSearch
|
<SelectWithSearch
|
||||||
{...field}
|
onChange={(value) => {
|
||||||
|
field.onChange(value);
|
||||||
|
handleFieldNameChange(value);
|
||||||
|
}}
|
||||||
|
value={field.value}
|
||||||
placeholder={t('dataFlowPlaceholder')}
|
placeholder={t('dataFlowPlaceholder')}
|
||||||
options={options}
|
options={options}
|
||||||
></SelectWithSearch>
|
></SelectWithSearch>
|
||||||
|
|||||||
@ -116,7 +116,7 @@ function ParserItem({ name, index, fieldLength, remove }: ParserItemProps) {
|
|||||||
>
|
>
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<span className="text-text-primary text-sm font-medium">
|
<span className="text-text-primary text-sm font-medium">
|
||||||
Parser {index}
|
Parser {index + 1}
|
||||||
</span>
|
</span>
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
<Button variant={'ghost'} onClick={() => remove(index)} ref={ref}>
|
<Button variant={'ghost'} onClick={() => remove(index)} ref={ref}>
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
NodeMap,
|
NodeMap,
|
||||||
Operator,
|
Operator,
|
||||||
initialBeginValues,
|
initialBeginValues,
|
||||||
initialContextValues,
|
initialExtractorValues,
|
||||||
initialHierarchicalMergerValues,
|
initialHierarchicalMergerValues,
|
||||||
initialNoteValues,
|
initialNoteValues,
|
||||||
initialParserValues,
|
initialParserValues,
|
||||||
@ -24,6 +24,7 @@ import {
|
|||||||
|
|
||||||
export const useInitializeOperatorParams = () => {
|
export const useInitializeOperatorParams = () => {
|
||||||
const llmId = useFetchModelId();
|
const llmId = useFetchModelId();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const initialFormValuesMap = useMemo(() => {
|
const initialFormValuesMap = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@ -33,9 +34,14 @@ export const useInitializeOperatorParams = () => {
|
|||||||
[Operator.Tokenizer]: initialTokenizerValues,
|
[Operator.Tokenizer]: initialTokenizerValues,
|
||||||
[Operator.Splitter]: initialSplitterValues,
|
[Operator.Splitter]: initialSplitterValues,
|
||||||
[Operator.HierarchicalMerger]: initialHierarchicalMergerValues,
|
[Operator.HierarchicalMerger]: initialHierarchicalMergerValues,
|
||||||
[Operator.Extractor]: { ...initialContextValues, llm_id: llmId },
|
[Operator.Extractor]: {
|
||||||
|
...initialExtractorValues,
|
||||||
|
llm_id: llmId,
|
||||||
|
sys_prompt: t('dataflow.prompts.system.summary'),
|
||||||
|
prompts: t('dataflow.prompts.user.summary'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}, [llmId]);
|
}, [llmId, t]);
|
||||||
|
|
||||||
const initializeOperatorParams = useCallback(
|
const initializeOperatorParams = useCallback(
|
||||||
(operatorName: Operator) => {
|
(operatorName: Operator) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user