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[]> => { 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.slice(0, -1)
: this.base.rerankBaseURL : this.base.rerankBaseURL
// 必须携带/v1否则会404
if (baseURL && !baseURL.endsWith('/v1')) {
baseURL = `${baseURL}/v1`
}
const url = `${baseURL}/rerank` const url = `${baseURL}/rerank`
const requestBody = { const requestBody = {
@ -40,9 +46,9 @@ export default class JinaReranker extends BaseReranker {
}) })
.filter((doc): doc is ExtractChunkData => doc !== undefined) .filter((doc): doc is ExtractChunkData => doc !== undefined)
.sort((a, b) => b.score - a.score) .sort((a, b) => b.score - a.score)
} catch (error) { } catch (error: any) {
console.error('Jina Reranker API 错误:', error) console.error('Jina Reranker API 错误:', error.status)
throw error 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[]> => { 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.slice(0, -1)
: this.base.rerankBaseURL : this.base.rerankBaseURL
// 必须携带/v1否则会404
if (baseURL && !baseURL.endsWith('/v1')) {
baseURL = `${baseURL}/v1`
}
const url = `${baseURL}/rerank` const url = `${baseURL}/rerank`
const requestBody = { const requestBody = {
@ -42,9 +48,9 @@ export default class SiliconFlowReranker extends BaseReranker {
}) })
.filter((doc): doc is ExtractChunkData => doc !== undefined) .filter((doc): doc is ExtractChunkData => doc !== undefined)
.sort((a, b) => b.score - a.score) .sort((a, b) => b.score - a.score)
} catch (error) { } catch (error: any) {
console.error('SiliconFlow Reranker API 错误:', error) console.error('SiliconFlow Reranker API 错误:', error.status)
throw error throw new Error(`${error} - BaseUrl: ${baseURL}`)
} }
} }
} }

View File

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

View File

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

View File

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