mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-08 12:24:48 +08:00
feat(raptor): add Psi tree builder with original-space ranking and safe migration (#14679)
### What problem does this PR solve? Closes #14674. This PR improves RAPTOR configuration and tree construction while preserving the existing RAPTOR behavior as the default. RAPTOR currently builds summary layers with the original UMAP + GMM clustering path. This PR keeps that default path, and adds: - A hidden backend tree-builder option: - `tree_builder="raptor"`: default, existing RAPTOR behavior. - `tree_builder="psi"`: rank-aware Psi-style tree builder using original embedding-space cosine ranking. - A user-facing clustering method option for the default RAPTOR builder: - `clustering_method="gmm"`: existing default. - `clustering_method="ahc"`: agglomerative hierarchical clustering path. - A RAPTOR UI setting for `Clustering method` and `Max cluster`. ### What changed #### Backend - Added `tree_builder` support for RAPTOR/Psi. - Added `clustering_method` support for GMM/AHC. - Kept existing RAPTOR + GMM as the default. - Added Psi tree building from original-space cosine similarity. - Added bucketed Psi building controls for large inputs: - `raptor.ext.psi_exact_max_leaves` - `raptor.ext.psi_bucket_size` - Added method-aware RAPTOR summary metadata using existing `extra.raptor_method`. - Avoided adding a dedicated DB schema field for experimental method tracking. - Added cleanup/migration logic to avoid mixing stale RAPTOR summary trees. - Added defensive checks for Psi tree construction and summary failures. #### Frontend/UI - Added `Clustering method` in RAPTOR settings with `GMM` and `AHC`. - Added/kept `Max cluster` in RAPTOR settings. - Enlarged max cluster UI limit to `1024`, matching backend validation. - Kept AHC editable even when a RAPTOR task has already finished. - Fixed the UI save payload so `clustering_method` and `tree_builder` are serialized through `parser_config.raptor.ext`, avoiding backend validation errors for extra top-level RAPTOR fields. Example saved RAPTOR config: ```json { "raptor": { "max_cluster": 317, "ext": { "clustering_method": "ahc", "tree_builder": "raptor" } } } Co-authored-by: CaptainTimon <CaptainTimon@users.noreply.github.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import { DocumentParserType, ParseType } from '@/constants/knowledge';
|
||||
import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { IParserConfig } from '@/interfaces/database/document';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import { IChangeParserRequestBody } from '@/interfaces/request/document';
|
||||
import { MetadataType } from '@/pages/dataset/components/metedata/constant';
|
||||
import {
|
||||
AutoMetadata,
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
} from '@/pages/dataset/dataset-setting/configuration/common-item';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import omit from 'lodash/omit';
|
||||
import {} from 'module';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -56,10 +55,7 @@ import {
|
||||
|
||||
const FormId = 'ChunkMethodDialogForm';
|
||||
|
||||
interface IProps extends IModalProps<{
|
||||
parserId: string;
|
||||
parserConfig: IChangeParserConfigRequestBody;
|
||||
}> {
|
||||
interface IProps extends IModalProps<IChangeParserRequestBody> {
|
||||
loading: boolean;
|
||||
parserId: string;
|
||||
pipelineId?: string;
|
||||
@@ -126,16 +122,19 @@ export function ChunkMethodDialog({
|
||||
mineru_formula_enable: z.boolean().optional(),
|
||||
mineru_table_enable: z.boolean().optional(),
|
||||
mineru_lang: z.string().optional(),
|
||||
// raptor: z
|
||||
// .object({
|
||||
// use_raptor: z.boolean().optional(),
|
||||
// prompt: z.string().optional().optional(),
|
||||
// max_token: z.coerce.number().optional(),
|
||||
// threshold: z.coerce.number().optional(),
|
||||
// max_cluster: z.coerce.number().optional(),
|
||||
// random_seed: z.coerce.number().optional(),
|
||||
// })
|
||||
// .optional(),
|
||||
raptor: z
|
||||
.object({
|
||||
use_raptor: z.boolean().optional(),
|
||||
prompt: z.string().optional(),
|
||||
max_token: z.coerce.number().optional(),
|
||||
threshold: z.coerce.number().optional(),
|
||||
max_cluster: z.coerce.number().optional(),
|
||||
random_seed: z.coerce.number().optional(),
|
||||
scope: z.string().optional(),
|
||||
clustering_method: z.enum(['gmm', 'ahc']).optional(),
|
||||
tree_builder: z.enum(['raptor', 'psi']).optional(),
|
||||
})
|
||||
.optional(),
|
||||
// graphrag: z.object({
|
||||
// use_graphrag: z.boolean().optional(),
|
||||
// }),
|
||||
|
||||
@@ -23,14 +23,17 @@ export function useDefaultParserValues() {
|
||||
mineru_formula_enable: true,
|
||||
mineru_table_enable: true,
|
||||
mineru_lang: 'English',
|
||||
// raptor: {
|
||||
// use_raptor: false,
|
||||
// prompt: t('knowledgeConfiguration.promptText'),
|
||||
// max_token: 256,
|
||||
// threshold: 0.1,
|
||||
// max_cluster: 64,
|
||||
// random_seed: 0,
|
||||
// },
|
||||
raptor: {
|
||||
use_raptor: false,
|
||||
prompt: t('knowledgeConfiguration.promptText'),
|
||||
max_token: 256,
|
||||
threshold: 0.1,
|
||||
max_cluster: 64,
|
||||
random_seed: 0,
|
||||
scope: 'file',
|
||||
clustering_method: 'gmm',
|
||||
tree_builder: 'raptor',
|
||||
},
|
||||
// graphrag: {
|
||||
// use_graphrag: false,
|
||||
// },
|
||||
|
||||
Reference in New Issue
Block a user