Add 添加知识项
(ctx context.Context, item *KnowledgeItem)
| 199 | |
| 200 | // Add 添加知识项 |
| 201 | func (m *manager) Add(ctx context.Context, item *KnowledgeItem) error { |
| 202 | if item == nil { |
| 203 | return errors.New("knowledge: item cannot be nil") |
| 204 | } |
| 205 | |
| 206 | if item.ID == "" { |
| 207 | return errors.New("knowledge: item ID cannot be empty") |
| 208 | } |
| 209 | |
| 210 | m.mu.Lock() |
| 211 | defer m.mu.Unlock() |
| 212 | |
| 213 | // 检查是否已存在 |
| 214 | if existing, err := m.getItemFromMemory(ctx, item.ID); err == nil && existing != nil { |
| 215 | return fmt.Errorf("knowledge: item with ID %s already exists", item.ID) |
| 216 | } |
| 217 | |
| 218 | // 设置时间戳 |
| 219 | now := time.Now() |
| 220 | item.CreatedAt = now |
| 221 | item.UpdatedAt = now |
| 222 | |
| 223 | // 设置命名空间 |
| 224 | if item.Namespace == "" { |
| 225 | item.Namespace = m.config.Namespace |
| 226 | } |
| 227 | |
| 228 | // PII检测 |
| 229 | if m.piiStrategy != nil { |
| 230 | if sanitized := m.sanitizeContent(item); sanitized != item { |
| 231 | item = sanitized |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | // 自动生成向量 |
| 236 | if m.config.AutoEmbed && len(item.Embedding) == 0 { |
| 237 | embedding, err := m.generateEmbedding(ctx, item) |
| 238 | if err != nil { |
| 239 | return fmt.Errorf("knowledge: failed to generate embedding: %w", err) |
| 240 | } |
| 241 | item.Embedding = embedding |
| 242 | } |
| 243 | |
| 244 | // 质量检查 |
| 245 | if item.Quality == 0 { |
| 246 | item.Quality = m.calculateQuality(item) |
| 247 | } |
| 248 | |
| 249 | // 保存到内存 |
| 250 | if err := m.saveItemToMemory(ctx, item); err != nil { |
| 251 | return fmt.Errorf("knowledge: failed to save item to memory: %w", err) |
| 252 | } |
| 253 | |
| 254 | // 保存向量到向量存储 |
| 255 | if len(item.Embedding) > 0 { |
| 256 | doc := vector.Document{ |
| 257 | ID: item.ID, |
| 258 | Text: item.Content, |
no test coverage detected