Update 更新知识项
(ctx context.Context, item *KnowledgeItem)
| 326 | |
| 327 | // Update 更新知识项 |
| 328 | func (m *manager) Update(ctx context.Context, item *KnowledgeItem) error { |
| 329 | if item == nil { |
| 330 | return errors.New("knowledge: item cannot be nil") |
| 331 | } |
| 332 | |
| 333 | if item.ID == "" { |
| 334 | return errors.New("knowledge: item ID cannot be empty") |
| 335 | } |
| 336 | |
| 337 | m.mu.Lock() |
| 338 | defer m.mu.Unlock() |
| 339 | |
| 340 | // 检查是否存在 |
| 341 | existing, err := m.getItemFromMemory(ctx, item.ID) |
| 342 | if err != nil { |
| 343 | return fmt.Errorf("knowledge: item not found: %w", err) |
| 344 | } |
| 345 | |
| 346 | // 更新时间戳 |
| 347 | item.UpdatedAt = time.Now() |
| 348 | item.CreatedAt = existing.CreatedAt // 保持创建时间 |
| 349 | |
| 350 | // PII检测 |
| 351 | if m.piiStrategy != nil { |
| 352 | if sanitized := m.sanitizeContent(item); sanitized != item { |
| 353 | item = sanitized |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | // 重新生成向量(如果内容变化) |
| 358 | if m.config.AutoEmbed && (item.Content != existing.Content || len(item.Embedding) == 0) { |
| 359 | embedding, err := m.generateEmbedding(ctx, item) |
| 360 | if err != nil { |
| 361 | return fmt.Errorf("knowledge: failed to generate embedding: %w", err) |
| 362 | } |
| 363 | item.Embedding = embedding |
| 364 | } |
| 365 | |
| 366 | // 重新计算质量 |
| 367 | item.Quality = m.calculateQuality(item) |
| 368 | |
| 369 | // 保存到内存 |
| 370 | if err := m.saveItemToMemory(ctx, item); err != nil { |
| 371 | return fmt.Errorf("knowledge: failed to save updated item to memory: %w", err) |
| 372 | } |
| 373 | |
| 374 | // 更新向量存储 |
| 375 | if len(item.Embedding) > 0 { |
| 376 | doc := vector.Document{ |
| 377 | ID: item.ID, |
| 378 | Text: item.Content, |
| 379 | Embedding: item.Embedding, |
| 380 | Metadata: map[string]any{ |
| 381 | "type": string(item.Type), |
| 382 | "category": item.Category, |
| 383 | "tags": strings.Join(item.Tags, ","), |
| 384 | "source": item.Source, |
| 385 | "author": item.Author, |
no test coverage detected