100 lines
2.9 KiB
Go
Executable File
100 lines
2.9 KiB
Go
Executable File
// 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)
|
||
}
|