Sfoglia il codice sorgente

chore: n to 1 retrieval (#6839)

tags/0.6.16
zxhlyh 1 anno fa
parent
commit
9ae88ede12
Nessun account collegato all'indirizzo email del committer

+ 18
- 12
web/app/components/app/configuration/dataset-config/params-config/config-content.tsx Vedi File

import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import {
RiAlertFill,
RiQuestionLine, RiQuestionLine,
} from '@remixicon/react' } from '@remixicon/react'
import WeightedScore from './weighted-score' import WeightedScore from './weighted-score'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { import type {
DataSet, DataSet,
WeightedScoreEnum,
} from '@/models/datasets' } from '@/models/datasets'
import { RerankingModeEnum } from '@/models/datasets' import { RerankingModeEnum } from '@/models/datasets'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
}) })
} }


const handleWeightedScoreChange = (value: { type: WeightedScoreEnum; value: number[] }) => {
const handleWeightedScoreChange = (value: { value: number[] }) => {
const configs = { const configs = {
...datasetConfigs, ...datasetConfigs,
weights: { weights: {
...datasetConfigs.weights!, ...datasetConfigs.weights!,
weight_type: value.type,
vector_setting: { vector_setting: {
...datasetConfigs.weights!.vector_setting!, ...datasetConfigs.weights!.vector_setting!,
vector_weight: value.value[0], vector_weight: value.value[0],
popupContent={( popupContent={(
<div className='w-[320px]'> <div className='w-[320px]'>
{t('dataset.nTo1RetrievalLegacy')} {t('dataset.nTo1RetrievalLegacy')}
<a
className='underline'
href={LEGACY_LINK_MAP[language]}
target='_blank'
rel='noopener noreferrer'
>
({t('dataset.nTo1RetrievalLegacyLink')})
</a>
</div> </div>
)} )}
> >
description={t('appDebug.datasetConfig.retrieveOneWay.description')} description={t('appDebug.datasetConfig.retrieveOneWay.description')}
isChosen={type === RETRIEVE_TYPE.oneWay} isChosen={type === RETRIEVE_TYPE.oneWay}
onChosen={() => { setType(RETRIEVE_TYPE.oneWay) }} onChosen={() => { setType(RETRIEVE_TYPE.oneWay) }}
extra={(
<div className='flex pl-3 pr-1 py-3 border-t border-divider-subtle bg-state-warning-hover rounded-b-xl'>
<RiAlertFill className='shrink-0 mr-1.5 w-4 h-4 text-text-warning-secondary' />
<div className='system-xs-medium text-text-primary'>
{t('dataset.nTo1RetrievalLegacyLinkText')}
<a
className='text-text-accent'
href={LEGACY_LINK_MAP[language]}
target='_blank'
rel='noopener noreferrer'
>
{t('dataset.nTo1RetrievalLegacyLink')}
</a>
</div>
</div>
)}
/> />
<RadioCard <RadioCard
icon={<MultiPathRetrieval className='shrink-0 mr-3 w-9 h-9 rounded-lg' />} icon={<MultiPathRetrieval className='shrink-0 mr-3 w-9 h-9 rounded-lg' />}
<div className='mt-2 space-y-4'> <div className='mt-2 space-y-4'>
<WeightedScore <WeightedScore
value={{ value={{
type: datasetConfigs.weights!.weight_type,
value: [ value: [
datasetConfigs.weights!.vector_setting.vector_weight, datasetConfigs.weights!.vector_setting.vector_weight,
datasetConfigs.weights!.keyword_setting.keyword_weight, datasetConfigs.weights!.keyword_setting.keyword_weight,

+ 7
- 0
web/app/components/app/configuration/dataset-config/params-config/weighted-score.css Vedi File

.weightedScoreSliderTrack {
background: var(--color-util-colors-blue-light-blue-light-500) !important;
}

.weightedScoreSliderTrack-1 {
background: transparent !important;
}

+ 18
- 69
web/app/components/app/configuration/dataset-config/params-config/weighted-score.tsx Vedi File

import { memo, useCallback } from 'react'
import { memo } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import {
DEFAULT_WEIGHTED_SCORE,
WeightedScoreEnum,
} from '@/models/datasets'
import './weighted-score.css'
import Slider from '@/app/components/base/slider' import Slider from '@/app/components/base/slider'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'


} }


type Value = { type Value = {
type: WeightedScoreEnum
value: number[] value: number[]
} }


onChange = () => {}, onChange = () => {},
}: WeightedScoreProps) => { }: WeightedScoreProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const options = [
{
value: WeightedScoreEnum.SemanticFirst,
label: t('dataset.weightedScore.semanticFirst'),
},
{
value: WeightedScoreEnum.KeywordFirst,
label: t('dataset.weightedScore.keywordFirst'),
},
{
value: WeightedScoreEnum.Customized,
label: t('dataset.weightedScore.customized'),
},
]

const disabled = value.type !== WeightedScoreEnum.Customized

const handleTypeChange = useCallback((type: WeightedScoreEnum) => {
const result = { ...value, type }

if (type === WeightedScoreEnum.SemanticFirst)
result.value = [DEFAULT_WEIGHTED_SCORE.semanticFirst.semantic, DEFAULT_WEIGHTED_SCORE.semanticFirst.keyword]

if (type === WeightedScoreEnum.KeywordFirst)
result.value = [DEFAULT_WEIGHTED_SCORE.keywordFirst.semantic, DEFAULT_WEIGHTED_SCORE.keywordFirst.keyword]

onChange(result)
}, [value, onChange])


return ( return (
<div> <div>
<div className='flex items-center mb-1 space-x-4'>
{
options.map(option => (
<div
key={option.value}
className='flex py-1.5 max-w-[calc((100%-32px)/3)] system-sm-regular text-text-secondary cursor-pointer'
onClick={() => handleTypeChange(option.value)}
>
<div
className={cn(
'shrink-0 mr-2 w-4 h-4 bg-components-radio-bg border border-components-radio-border rounded-full shadow-xs',
value.type === option.value && 'border-[5px] border-components-radio-border-checked',
)}
></div>
<div className='truncate' title={option.label}>{option.label}</div>
</div>
))
}
</div>
<div className='flex items-center px-3 h-9 space-x-3 rounded-lg border border-components-panel-border'>
<div className='shrink-0 flex items-center w-[90px] system-xs-semibold-uppercase text-util-colors-blue-blue-500'>
<div className='mr-1 truncate uppercase' title={t('dataset.weightedScore.semantic') || ''}>
{t('dataset.weightedScore.semantic')}
</div>
{formatNumber(value.value[0])}
</div>
<div className='px-3 pt-5 h-[52px] space-x-3 rounded-lg border border-components-panel-border'>
<Slider <Slider
className={cn('grow h-0.5 bg-gradient-to-r from-[#53B1FD] to-[#2ED3B7]', disabled && 'cursor-not-allowed')}
className={cn('grow h-0.5 !bg-util-colors-teal-teal-500 rounded-full')}
max={1.0} max={1.0}
min={0} min={0}
step={0.1} step={0.1}
value={value.value[0]} value={value.value[0]}
onChange={v => onChange({ type: value.type, value: [v, (10 - v * 10) / 10] })}
disabled={disabled}
thumbClassName={cn(disabled && '!cursor-not-allowed')}
trackClassName='!bg-transparent'
onChange={v => onChange({ value: [v, (10 - v * 10) / 10] })}
trackClassName='weightedScoreSliderTrack'
/> />
<div className='shrink-0 flex items-center justify-end w-[90px] system-xs-semibold-uppercase text-util-colors-cyan-cyan-500'>
{formatNumber(value.value[1])}
<div className='ml-1 truncate uppercase' title={t('dataset.weightedScore.keyword') || ''}>
{t('dataset.weightedScore.keyword')}
<div className='flex justify-between mt-1'>
<div className='shrink-0 flex items-center w-[90px] system-xs-semibold-uppercase text-util-colors-blue-light-blue-light-500'>
<div className='mr-1 truncate uppercase' title={t('dataset.weightedScore.semantic') || ''}>
{t('dataset.weightedScore.semantic')}
</div>
{formatNumber(value.value[0])}
</div>
<div className='shrink-0 flex items-center justify-end w-[90px] system-xs-semibold-uppercase text-util-colors-teal-teal-500'>
{formatNumber(value.value[1])}
<div className='ml-1 truncate uppercase' title={t('dataset.weightedScore.keyword') || ''}>
{t('dataset.weightedScore.keyword')}
</div>
</div> </div>
</div> </div>
</div> </div>

+ 12
- 7
web/app/components/base/radio-card/simple/index.tsx Vedi File

onChosen: () => void onChosen: () => void
chosenConfig?: React.ReactNode chosenConfig?: React.ReactNode
icon?: JSX.Element icon?: JSX.Element
extra?: React.ReactNode
} }


const RadioCard: FC<Props> = ({ const RadioCard: FC<Props> = ({
isChosen, isChosen,
onChosen, onChosen,
icon, icon,
extra,
}) => { }) => {
return ( return (
<div <div
className={cn(s.item, isChosen && s.active, 'flex')}
className={cn(s.item, isChosen && s.active)}
onClick={onChosen} onClick={onChosen}
> >
{icon}
<div>
<div className='flex justify-between items-center'>
<div className='leading-5 text-sm font-medium text-gray-900'>{title}</div>
<div className={s.radio}></div>
<div className='flex px-3 py-2'>
{icon}
<div>
<div className='flex justify-between items-center'>
<div className='leading-5 text-sm font-medium text-gray-900'>{title}</div>
<div className={s.radio}></div>
</div>
<div className='leading-[18px] text-xs font-normal text-gray-500'>{description}</div>
</div> </div>
<div className='leading-[18px] text-xs font-normal text-gray-500'>{description}</div>
</div> </div>
{extra}
</div> </div>
) )
} }

+ 1
- 1
web/app/components/base/radio-card/simple/style.module.css Vedi File

.item { .item {
@apply relative p-4 rounded-xl border border-gray-100 cursor-pointer;
@apply relative rounded-xl border border-gray-100 cursor-pointer;
background-color: #fcfcfd; background-color: #fcfcfd;
} }



+ 0
- 2
web/app/components/workflow/nodes/knowledge-retrieval/types.ts Vedi File

import type { RETRIEVE_TYPE } from '@/types/app' import type { RETRIEVE_TYPE } from '@/types/app'
import type { import type {
RerankingModeEnum, RerankingModeEnum,
WeightedScoreEnum,
} from '@/models/datasets' } from '@/models/datasets'


export type MultipleRetrievalConfig = { export type MultipleRetrievalConfig = {
} }
reranking_mode?: RerankingModeEnum reranking_mode?: RerankingModeEnum
weights?: { weights?: {
weight_type: WeightedScoreEnum
vector_setting: { vector_setting: {
vector_weight: number vector_weight: number
embedding_provider_name: string embedding_provider_name: string

+ 1
- 1
web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts Vedi File

handleMultipleRetrievalConfigChange, handleMultipleRetrievalConfigChange,
handleModelChanged, handleModelChanged,
handleCompletionParamsChange, handleCompletionParamsChange,
selectedDatasets,
selectedDatasets: selectedDatasets.filter(d => d.name),
handleOnDatasetsChange, handleOnDatasetsChange,
isShowSingleRun, isShowSingleRun,
hideSingleRun, hideSingleRun,

+ 0
- 2
web/app/components/workflow/nodes/knowledge-retrieval/utils.ts Vedi File

import { import {
DEFAULT_WEIGHTED_SCORE, DEFAULT_WEIGHTED_SCORE,
RerankingModeEnum, RerankingModeEnum,
WeightedScoreEnum,
} from '@/models/datasets' } from '@/models/datasets'
import { RETRIEVE_METHOD } from '@/types/app' import { RETRIEVE_METHOD } from '@/types/app'
import { DATASET_DEFAULT } from '@/config' import { DATASET_DEFAULT } from '@/config'


if (allHighQuality && !inconsistentEmbeddingModel && (reranking_mode === RerankingModeEnum.WeightedScore || reranking_mode === undefined) && !weights) { if (allHighQuality && !inconsistentEmbeddingModel && (reranking_mode === RerankingModeEnum.WeightedScore || reranking_mode === undefined) && !weights) {
result.weights = { result.weights = {
weight_type: WeightedScoreEnum.Customized,
vector_setting: { vector_setting: {
vector_weight: allHighQualityVectorSearch vector_weight: allHighQualityVectorSearch
? DEFAULT_WEIGHTED_SCORE.allHighQualityVectorSearch.semantic ? DEFAULT_WEIGHTED_SCORE.allHighQualityVectorSearch.semantic

+ 1
- 0
web/i18n/en-US/dataset.ts Vedi File

}, },
nTo1RetrievalLegacy: 'N-to-1 retrieval will be officially deprecated from September. It is recommended to use the latest Multi-path retrieval to obtain better results. ', nTo1RetrievalLegacy: 'N-to-1 retrieval will be officially deprecated from September. It is recommended to use the latest Multi-path retrieval to obtain better results. ',
nTo1RetrievalLegacyLink: 'Learn more', nTo1RetrievalLegacyLink: 'Learn more',
nTo1RetrievalLegacyLinkText: ' N-to-1 retrieval will be officially deprecated in September.',
} }


export default translation export default translation

+ 1
- 0
web/i18n/zh-Hans/dataset.ts Vedi File

}, },
nTo1RetrievalLegacy: '9 月 1 日起我们将不再提供此能力,推荐使用最新的多路召回获得更好的检索效果。', nTo1RetrievalLegacy: '9 月 1 日起我们将不再提供此能力,推荐使用最新的多路召回获得更好的检索效果。',
nTo1RetrievalLegacyLink: '了解更多', nTo1RetrievalLegacyLink: '了解更多',
nTo1RetrievalLegacyLinkText: '9 月 1 日起我们将不再提供此能力。',
} }


export default translation export default translation

+ 0
- 2
web/models/debug.ts Vedi File

import type { AgentStrategy, ModelModeType, RETRIEVE_TYPE, ToolItem, TtsAutoPlay } from '@/types/app' import type { AgentStrategy, ModelModeType, RETRIEVE_TYPE, ToolItem, TtsAutoPlay } from '@/types/app'
import type { import type {
RerankingModeEnum, RerankingModeEnum,
WeightedScoreEnum,
} from '@/models/datasets' } from '@/models/datasets'
export type Inputs = Record<string, string | number | object> export type Inputs = Record<string, string | number | object>


} }
reranking_mode?: RerankingModeEnum reranking_mode?: RerankingModeEnum
weights?: { weights?: {
weight_type: WeightedScoreEnum
vector_setting: { vector_setting: {
vector_weight: number vector_weight: number
embedding_provider_name: string embedding_provider_name: string

Loading…
Annulla
Salva