Files
xk-ai-agent/internal/kb/embedder.go
2026-08-14 21:50:48 +08:00

104 lines
3.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package kb
import "context"
// ========================================================================
// Embedder 接口V2 预留)
// ========================================================================
// V1 只实现 NoopEmbedder默认不调任何向量化服务
//
// V2 接入 BGE-M3 / 阿里 / OpenAI 时只需:
// 1. 新增文件 embedder_bge.go 实现 Embedder 接口
// 2. 在 NewEmbedder 工厂函数里加 case
// 3. 业务代码Searcher / Importer零改动
// ========================================================================
// Embedder 向量化接口
//
// 各实现的差异主要在:
// - Name():返回 provider 标识noop/bge_m3/aliyun/openai
// - Embed()批量把文本转成向量V1 noop 直接返回 nil
// - Dim()向量维度V1 noop 返回 0
// - Available()是否能用V1 noop 返回 false
type Embedder interface {
// Name 返回 provider 名(用于日志/前端展示)
Name() string
// Embed 批量向量化
//
// 入参texts 一段或多段文本
// 出参:与 texts 等长的向量数组;每个向量是 []float32维度由实现决定
// V1 NoopEmbedder 返回 nil, nil不报错调用方判断 Available() 后再调用)
Embed(ctx context.Context, texts []string) ([][]float32, error)
// Dim 返回向量维度
// NoopEmbedder 返回 0
// BGE-M3 返回 1024阿里 text-embedding-v3 返回 1024
Dim() int
// Available 是否可用
// NoopEmbedder 返回 false明确告知调用方"我不做向量化"
// 真实 provider 返回 true
Available() bool
}
// ========================================================================
// NoopEmbedder —— V1 默认实现(不做任何向量化)
// ========================================================================
// NoopEmbedder 空实现,所有方法返回零值
//
// 设计意图:
// - 让 V1 的 Importer/Searcher 代码结构里就有 Embedder 接口位置
// - 通过判断 Available() 自动跳过向量化逻辑
// - V2 替换为真实 Embedder 时无需改业务代码
type NoopEmbedder struct{}
// NewNoopEmbedder 构造
func NewNoopEmbedder() *NoopEmbedder { return &NoopEmbedder{} }
// Name 返回 provider 名
func (n *NoopEmbedder) Name() string { return "noop" }
// Embed 不做向量化,直接返回 nil
func (n *NoopEmbedder) Embed(ctx context.Context, texts []string) ([][]float32, error) {
return nil, nil
}
// Dim 返回 0noop 没有维度)
func (n *NoopEmbedder) Dim() int { return 0 }
// Available 返回 false明确告知调用方不要依赖我
func (n *NoopEmbedder) Available() bool { return false }
// ========================================================================
// Embedder 工厂V1 只支持 noopV2 扩展)
// ========================================================================
// NewEmbedder 根据 provider 名构造对应的 Embedder
//
// 参数:
// - provider从 xk_system_config.ai_kb_embedding_provider 读到的值
// - apiKey从 xk_system_config.ai_kb_embedding_api_key 读到的值V1 noop 不用)
//
// 返回:
// V1 默认走 noop 分支
// V2 新增 bge_m3/aliyun/openai 时在这里加 case
// 未知 provider 也回落到 noop不阻断业务
func NewEmbedder(provider, apiKey string) Embedder {
switch provider {
case "noop", "":
return NewNoopEmbedder()
// V2 预留:
// case "bge_m3":
// return NewBGEM3Embedder(apiKey)
// case "aliyun":
// return NewAliyunEmbedder(apiKey)
// case "openai":
// return NewOpenAIEmbedder(apiKey)
default:
// 未知 provider 回落到 noop保证可用性
return NewNoopEmbedder()
}
}