fix(knowledge): show more info (#3790)

* feat: remove rerank model from embedded model

* feat: add rerank model info

* fix: embedding and rerank model end without `/v1` bug
This commit is contained in:
Chen Tao 2025-03-22 22:14:25 +08:00 committed by GitHub
parent 6c6af2a12b
commit d56774fd59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 84 additions and 25 deletions

View File

@ -10,9 +10,15 @@ export default class JinaReranker extends BaseReranker {
}
public rerank = async (query: string, searchResults: ExtractChunkData[]): Promise<ExtractChunkData[]> => {
const baseURL = this.base?.rerankBaseURL?.endsWith('/')
let baseURL = this.base?.rerankBaseURL?.endsWith('/')
? this.base.rerankBaseURL.slice(0, -1)
: this.base.rerankBaseURL
// 必须携带/v1否则会404
if (baseURL && !baseURL.endsWith('/v1')) {
baseURL = `${baseURL}/v1`
}
const url = `${baseURL}/rerank`
const requestBody = {
@ -40,9 +46,9 @@ export default class JinaReranker extends BaseReranker {
})
.filter((doc): doc is ExtractChunkData => doc !== undefined)
.sort((a, b) => b.score - a.score)
} catch (error) {
console.error('Jina Reranker API 错误:', error)
throw error
} catch (error: any) {
console.error('Jina Reranker API 错误:', error.status)
throw new Error(`${error} - BaseUrl: ${baseURL}`)
}
}
}

View File

@ -10,9 +10,15 @@ export default class SiliconFlowReranker extends BaseReranker {
}
public rerank = async (query: string, searchResults: ExtractChunkData[]): Promise<ExtractChunkData[]> => {
const baseURL = this.base?.rerankBaseURL?.endsWith('/')
let baseURL = this.base?.rerankBaseURL?.endsWith('/')
? this.base.rerankBaseURL.slice(0, -1)
: this.base.rerankBaseURL
// 必须携带/v1否则会404
if (baseURL && !baseURL.endsWith('/v1')) {
baseURL = `${baseURL}/v1`
}
const url = `${baseURL}/rerank`
const requestBody = {
@ -42,9 +48,9 @@ export default class SiliconFlowReranker extends BaseReranker {
})
.filter((doc): doc is ExtractChunkData => doc !== undefined)
.sort((a, b) => b.score - a.score)
} catch (error) {
console.error('SiliconFlow Reranker API 错误:', error)
throw error
} catch (error: any) {
console.error('SiliconFlow Reranker API 错误:', error.status)
throw new Error(`${error} - BaseUrl: ${baseURL}`)
}
}
}

View File

@ -61,6 +61,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
} = useKnowledge(selectedBase.id || '')
const providerName = getProviderName(base?.model.provider || '')
const rerankModelProviderName = getProviderName(base?.rerankModel?.provider || '')
const disabled = !base?.version || !providerName
if (!base) {
@ -445,13 +446,34 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
</ContentSection>
<Divider style={{ margin: '10px 0' }} />
<ModelInfo>
<label htmlFor="model-info">{t('knowledge.model_info')}</label>
<div className="model-header">
<label>{t('knowledge.model_info')}</label>
<Button icon={<SettingOutlined />} onClick={() => KnowledgeSettingsPopup.show({ base })} size="small" />
</div>
<div className="model-row">
<div className="label-column">
<label>{t('models.embedding_model')}</label>
</div>
<div className="tag-column">
{providerName && <Tag color="purple">{providerName}</Tag>}
<Tag color="blue">{base.model.name}</Tag>
<Tag color="cyan">{t('models.dimensions', { dimensions: base.dimensions || 0 })}</Tag>
{providerName && <Tag color="purple">{providerName}</Tag>}
<Button icon={<SettingOutlined />} onClick={() => KnowledgeSettingsPopup.show({ base })} size="small" />
</div>
</div>
{base.rerankModel && (
<div className="model-row">
<div className="label-column">
<label>{t('models.rerank_model')}</label>
</div>
<div className="tag-column">
{rerankModelProviderName && <Tag color="purple">{rerankModelProviderName}</Tag>}
<Tag color="blue">{base.rerankModel?.name}</Tag>
</div>
</div>
)}
</ModelInfo>
<IndexSection>
@ -547,15 +569,39 @@ const IndexSection = styled.div`
const ModelInfo = styled.div`
display: flex;
align-items: center;
flex-direction: column;
gap: 8px;
padding: 5px;
color: var(--color-text-3);
.model-header {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 4px;
}
.model-row {
display: flex;
align-items: flex-start;
}
.label-column {
width: 80px;
flex-shrink: 0;
}
.tag-column {
display: flex;
flex-wrap: wrap;
gap: 4px;
align-items: center;
}
label {
margin-right: 8px;
color: var(--color-text-2);
}
`
const FlexColumn = styled.div`
display: flex;
flex-direction: column;

View File

@ -40,7 +40,7 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
const allModels = providers
.map((p) => p.models)
.flat()
.filter((model) => isEmbeddingModel(model))
.filter((model) => isEmbeddingModel(model) && !isRerankModel(model))
const rerankModels = providers
.map((p) => p.models)
@ -55,7 +55,7 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
label: p.isSystem ? t(`provider.${p.id}`) : p.name,
title: p.name,
options: sortBy(p.models, 'name')
.filter((model) => isEmbeddingModel(model))
.filter((model) => isEmbeddingModel(model) && !isRerankModel(model))
.map((m) => ({
label: m.name,
value: getModelUniqId(m)
@ -82,6 +82,7 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
try {
const values = await form.validateFields()
const selectedModel = find(allModels, JSON.parse(values.model)) as Model
const selectedRerankModel = values.rerankModel
? (find(rerankModels, JSON.parse(values.rerankModel)) as Model)
: undefined
@ -170,12 +171,12 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
tooltip={{ title: t('models.rerank_model_tooltip'), placement: 'right' }}
rules={[{ required: false, message: t('message.error.enter.model') }]}>
<Select style={{ width: '100%' }} options={rerankSelectOptions} placeholder={t('settings.models.empty')} />
<SettingHelpText style={{ marginTop: 10 }}>
</Form.Item>
<SettingHelpText style={{ marginTop: -15, marginBottom: 20 }}>
{t('models.rerank_model_support_provider', {
provider: SUPPORTED_REANK_PROVIDERS.map((id) => t(`provider.${id}`))
})}
</SettingHelpText>
</Form.Item>
</Form>
</Modal>
)

View File

@ -57,7 +57,7 @@ const PopupContainer: React.FC<Props> = ({ base: _base, resolve }) => {
label: p.isSystem ? t(`provider.${p.id}`) : p.name,
title: p.name,
options: sortBy(p.models, 'name')
.filter((model) => isEmbeddingModel(model))
.filter((model) => isEmbeddingModel(model) && !isRerankModel(model))
.map((m) => ({
label: m.name,
value: getModelUniqId(m)