embedding.go 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package rag
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/2930134478/AI-CS/backend/service/embedding"
  6. )
  7. // DocumentEmbeddingService 文档向量化服务
  8. type DocumentEmbeddingService struct {
  9. vectorStoreService *VectorStoreService
  10. embeddingProvider embedding.EmbeddingProvider
  11. }
  12. // NewDocumentEmbeddingService 创建文档向量化服务实例(使用 provider 实现配置保存即生效)
  13. func NewDocumentEmbeddingService(vectorStoreService *VectorStoreService, embeddingProvider embedding.EmbeddingProvider) *DocumentEmbeddingService {
  14. return &DocumentEmbeddingService{
  15. vectorStoreService: vectorStoreService,
  16. embeddingProvider: embeddingProvider,
  17. }
  18. }
  19. // EmbedDocument 向量化单个文档并存储
  20. func (s *DocumentEmbeddingService) EmbedDocument(ctx context.Context, documentID uint, knowledgeBaseID uint, content string) error {
  21. svc, err := s.embeddingProvider.Get(ctx)
  22. if err != nil {
  23. return fmt.Errorf("获取嵌入服务失败: %w", err)
  24. }
  25. // 向量化
  26. vectors, err := svc.EmbedTexts(ctx, []string{content})
  27. if err != nil {
  28. return fmt.Errorf("文档向量化失败: %w", err)
  29. }
  30. if len(vectors) == 0 {
  31. return fmt.Errorf("未返回向量")
  32. }
  33. // 存储向量
  34. docIDStr := ConvertDocumentID(documentID)
  35. kbIDStr := ConvertKnowledgeBaseID(knowledgeBaseID)
  36. if err := s.vectorStoreService.UpsertVector(ctx, docIDStr, kbIDStr, content, vectors[0]); err != nil {
  37. return fmt.Errorf("存储向量失败: %w", err)
  38. }
  39. return nil
  40. }
  41. // EmbedDocuments 批量向量化文档并存储
  42. func (s *DocumentEmbeddingService) EmbedDocuments(ctx context.Context, documentIDs []uint, knowledgeBaseIDs []uint, contents []string) error {
  43. if len(documentIDs) != len(knowledgeBaseIDs) || len(documentIDs) != len(contents) {
  44. return fmt.Errorf("参数长度不匹配")
  45. }
  46. svc, err := s.embeddingProvider.Get(ctx)
  47. if err != nil {
  48. return fmt.Errorf("获取嵌入服务失败: %w", err)
  49. }
  50. // 批量向量化
  51. vectors, err := svc.EmbedTexts(ctx, contents)
  52. if err != nil {
  53. return fmt.Errorf("批量向量化失败: %w", err)
  54. }
  55. if len(vectors) != len(contents) {
  56. return fmt.Errorf("向量数量不匹配")
  57. }
  58. // 转换 ID
  59. docIDStrs := make([]string, len(documentIDs))
  60. kbIDStrs := make([]string, len(knowledgeBaseIDs))
  61. for i, id := range documentIDs {
  62. docIDStrs[i] = ConvertDocumentID(id)
  63. }
  64. for i, id := range knowledgeBaseIDs {
  65. kbIDStrs[i] = ConvertKnowledgeBaseID(id)
  66. }
  67. // 批量存储向量
  68. if err := s.vectorStoreService.UpsertVectors(ctx, docIDStrs, kbIDStrs, contents, vectors); err != nil {
  69. return fmt.Errorf("批量存储向量失败: %w", err)
  70. }
  71. return nil
  72. }
  73. // DeleteDocumentEmbedding 删除文档的向量
  74. func (s *DocumentEmbeddingService) DeleteDocumentEmbedding(ctx context.Context, documentID uint) error {
  75. docIDStr := ConvertDocumentID(documentID)
  76. return s.vectorStoreService.DeleteVector(ctx, docIDStr)
  77. }
  78. // DeleteDocumentEmbeddings 批量删除文档的向量
  79. func (s *DocumentEmbeddingService) DeleteDocumentEmbeddings(ctx context.Context, documentIDs []uint) error {
  80. docIDStrs := make([]string, len(documentIDs))
  81. for i, id := range documentIDs {
  82. docIDStrs[i] = ConvertDocumentID(id)
  83. }
  84. return s.vectorStoreService.DeleteVectors(ctx, docIDStrs)
  85. }