// ingest_json.go – Importiert KI-Bildbeschreibungen aus einer JSON-Datei in Qdrant package brain import ( "context" "encoding/json" "fmt" "log" "os" pb "github.com/qdrant/go-client/qdrant" openai "github.com/sashabaranov/go-openai" "google.golang.org/grpc/metadata" "my-brain-importer/internal/config" ) // ImageEntry entspricht der JSON-Ausgabe von analyze-images.go type ImageEntry struct { FilePath string `json:"file_path"` FileName string `json:"file_name"` Description string `json:"description"` } // RunIngestJSON importiert Bildbeschreibungen aus einer JSON-Datei in Qdrant. func RunIngestJSON(inputFile string) { fmt.Printf("📂 Lade \"%s\"...\n", inputFile) raw, err := os.ReadFile(inputFile) if err != nil { log.Fatalf("❌ Datei nicht gefunden: %v", err) } var entries []ImageEntry if err := json.Unmarshal(raw, &entries); err != nil { log.Fatalf("❌ JSON Fehler: %v", err) } if len(entries) == 0 { log.Fatal("❌ Keine Einträge in JSON") } fmt.Printf("✅ %d Einträge geladen\n\n", len(entries)) ctx := context.Background() ctx = metadata.AppendToOutgoingContext(ctx, "api-key", config.Cfg.Qdrant.APIKey) conn := config.NewQdrantConn() defer conn.Close() ensureCollection(ctx, pb.NewCollectionsClient(conn)) pointsClient := pb.NewPointsClient(conn) embClient := config.NewEmbeddingClient() fmt.Printf("🤖 Embedding: %s (%s)\n\n", config.Cfg.Embedding.Model, config.Cfg.Embedding.URL) success := 0 for i, entry := range entries { fmt.Printf("[%d/%d] 🔄 %s\n", i+1, len(entries), entry.FileName) embResp, err := embClient.CreateEmbeddings(ctx, openai.EmbeddingRequest{ Input: []string{entry.Description}, Model: openai.EmbeddingModel(config.Cfg.Embedding.Model), }) if err != nil { log.Printf(" ❌ Embedding Fehler: %v\n", err) continue } _, err = pointsClient.Upsert(ctx, &pb.UpsertPoints{ CollectionName: config.Cfg.Qdrant.Collection, Points: []*pb.PointStruct{ { Id: &pb.PointId{ PointIdOptions: &pb.PointId_Uuid{ Uuid: generateID(entry.Description, entry.FileName), }, }, Vectors: &pb.Vectors{ VectorsOptions: &pb.Vectors_Vector{ Vector: &pb.Vector{Data: embResp.Data[0].Embedding}, }, }, Payload: map[string]*pb.Value{ "text": {Kind: &pb.Value_StringValue{StringValue: entry.Description}}, "source": {Kind: &pb.Value_StringValue{StringValue: entry.FileName}}, "path": {Kind: &pb.Value_StringValue{StringValue: entry.FilePath}}, "type": {Kind: &pb.Value_StringValue{StringValue: "image"}}, }, }, }, }) if err != nil { log.Printf(" ❌ Speichern Fehler: %v\n", err) } else { success++ } } fmt.Printf("\n✅ Fertig: %d von %d Bildern importiert\n", success, len(entries)) fmt.Printf("🌐 Dashboard: http://%s:6333/dashboard\n", config.Cfg.Qdrant.Host) }