This commit is contained in:
2026-06-22 08:55:57 +08:00
parent dbb87823e8
commit 6ade6e8fa9
325 changed files with 41131 additions and 855 deletions
+39 -2
View File
@@ -13,8 +13,11 @@ type GeminiClient struct {
sdk *genai.Client
}
// Compile-time assertion: GeminiClient must satisfy LLMClient.
var _ LLMClient = (*GeminiClient)(nil)
// Compile-time assertion: GeminiClient must satisfy LLMClient + Embedder.
var (
_ LLMClient = (*GeminiClient)(nil)
_ Embedder = (*GeminiClient)(nil)
)
// NewGemini 构造 GeminiClient。apiKey 不可空;baseURL 可空(用 SDK 默认端点)。
func NewGemini(apiKey, baseURL string) (*GeminiClient, error) {
@@ -142,3 +145,37 @@ func (c *GeminiClient) CountTokens(ctx context.Context, modelID string, req Requ
}
return int(res.TotalTokens), nil
}
// EmbedDims returns the platform-standard embedding dimension. gemini-embedding
// honors OutputDimensionality so Embed pins the output to PlatformEmbeddingDims.
func (c *GeminiClient) EmbedDims(string) int { return PlatformEmbeddingDims }
// Embed calls EmbedContent with all inputs batched as separate Contents, pinning
// OutputDimensionality to the fixed pgvector column width. Returns one vector per
// input in order.
func (c *GeminiClient) Embed(ctx context.Context, modelID string, inputs []string) ([][]float32, error) {
if len(inputs) == 0 {
return nil, nil
}
contents := make([]*genai.Content, len(inputs))
for i, in := range inputs {
contents[i] = &genai.Content{Role: "user", Parts: []*genai.Part{genai.NewPartFromText(in)}}
}
dims := int32(PlatformEmbeddingDims)
resp, err := c.sdk.Models.EmbedContent(ctx, modelID, contents, &genai.EmbedContentConfig{
OutputDimensionality: &dims,
})
if err != nil {
return nil, fmt.Errorf("gemini embeddings: %w", err)
}
if len(resp.Embeddings) != len(inputs) {
return nil, fmt.Errorf("gemini embeddings: got %d vectors for %d inputs", len(resp.Embeddings), len(inputs))
}
out := make([][]float32, len(resp.Embeddings))
for i, e := range resp.Embeddings {
v := make([]float32, len(e.Values))
copy(v, e.Values)
out[i] = v
}
return out, nil
}