Files
ai-agent/internal/brain/ingest_pdf.go
Christoph K. 905981cd1e zwischenstand
2026-03-20 23:24:56 +01:00

83 lines
2.0 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.
// ingest_pdf.go Extrahiert Text aus einer PDF-Datei und importiert ihn in Qdrant
package brain
import (
"context"
"fmt"
"strings"
"github.com/ledongthuc/pdf"
pb "github.com/qdrant/go-client/qdrant"
"google.golang.org/grpc/metadata"
"my-brain-importer/internal/config"
)
// IngestPDF extrahiert Text aus einer PDF-Datei und importiert ihn in Qdrant.
// source ist der Anzeigename der Quelle (z.B. Dateiname).
// Gibt Anzahl der importierten Chunks zurück.
func IngestPDF(filePath, source string) (int, error) {
text, err := extractPDFText(filePath)
if err != nil {
return 0, fmt.Errorf("PDF-Parsing fehlgeschlagen: %w", err)
}
text = strings.TrimSpace(text)
if len(text) < 20 {
return 0, fmt.Errorf("kein verwertbarer Text in PDF gefunden")
}
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "api-key", config.Cfg.Qdrant.APIKey)
embClient := config.NewEmbeddingClient()
conn := config.NewQdrantConn()
defer conn.Close()
ensureCollection(ctx, pb.NewCollectionsClient(conn))
pointsClient := pb.NewPointsClient(conn)
var chunks []chunk
for _, part := range splitLongSection(text) {
part = strings.TrimSpace(part)
if len(part) < 20 {
continue
}
chunks = append(chunks, chunk{Text: part, Source: source, Type: "pdf"})
}
if len(chunks) == 0 {
return 0, fmt.Errorf("kein verwertbarer Inhalt nach Aufteilung")
}
if err := ingestChunks(ctx, embClient, pointsClient, chunks); err != nil {
return 0, fmt.Errorf("Ingest fehlgeschlagen: %w", err)
}
return len(chunks), nil
}
// extractPDFText liest alle Seiten einer PDF-Datei und gibt den Text zurück.
func extractPDFText(filePath string) (string, error) {
f, r, err := pdf.Open(filePath)
if err != nil {
return "", err
}
defer f.Close()
var sb strings.Builder
totalPages := r.NumPage()
for pageNum := 1; pageNum <= totalPages; pageNum++ {
page := r.Page(pageNum)
if page.V.IsNull() {
continue
}
text, err := page.GetPlainText(nil)
if err != nil {
continue
}
sb.WriteString(text)
sb.WriteString("\n")
}
return sb.String(), nil
}