# ai-memory-core 使用手册

> 版本: 0.1.0 | 本文档适用于希望将长期记忆能力集成到 AI 应用中的开发者。

---

## 目录

1. [概述与设计理念](#1-概述与设计理念)
2. [安装与前置条件](#2-安装与前置条件)
3. [数据目录配置](#3-数据目录配置)
4. [空间隐喻系统](#4-空间隐喻系统)
5. [记忆 CRUD 操作](#5-记忆-crud-操作)
6. [元数据追踪与高价值记忆](#6-元数据追踪与高价值记忆)
7. [会话注入（热记忆）](#7-会话注入热记忆)
8. [LLM 记忆提取](#8-llm-记忆提取)
9. [自定义提取提示词模板](#9-自定义提取提示词模板)
10. [集成示例](#10-集成示例)
11. [最佳实践](#11-最佳实践)
12. [故障排查](#12-故障排查)

---

## 1. 概述与设计理念

### 什么是 ai-memory-core？

`ai-memory-core` 是一个轻量级 Rust 库，为 AI/LLM 应用提供跨会话的记忆能力。它解决的核心问题是：**AI 助手每次对话都从零开始，无法记住用户的偏好、决策和知识**。

### 双轨记忆架构

系统将记忆分为两轨：

| 记忆类型 | 存储位置 | 时机 | 用途 |
|----------|---------|------|------|
| **热记忆** | 注入到 system prompt | 每次对话开始前 | 让 AI 了解用户偏好、项目背景 |
| **冷记忆** | `memories.md` 磁盘文件 | 持久化存储 | 完整的记忆历史，人类可读 |

```
┌─ 热记忆 (Hot Memory) ─────────────────────────────┐
│  每次对话前自动注入到 system prompt                │
│  ● 按优先级排序（高价值 > 低频）                   │
│  ● 控制在 2000 tokens 以内                         │
│  ● 格式: [USER_MEMORY]\n...\n[/USER_MEMORY]        │
└────────────────────────────────────────────────────┘

┌─ 冷记忆 (Cold Memory) ────────────────────────────┐
│  持久化存储在 data_dir/memories.md                  │
│  ● 纯 Markdown 格式                               │
│  ● 支持空间隐喻分类                                │
│  ● 自动去重（内容去重，日期更新）                   │
└────────────────────────────────────────────────────┘

┌─ 元数据层 (Metadata) ──────────────────────────────┐
│  持久化在 data_dir/memories.meta.json               │
│  ● MD5 内容指纹                                    │
│  ● 跨会话访问次数统计                               │
│  ● 高价值标识 (access_count >= 5)                   │
└────────────────────────────────────────────────────┘
```

### 数据流全景

```
用户对话 ──→ 系统
               │
    ┌──────────┴──────────┐
    │                     │
    ▼                     ▼
┌───────┐           ┌──────────┐
│ 存储   │           │ 记忆注入   │
│ (Save) │           │ (Inject)  │
└───┬───┘           └─────┬────┘
    │                     │
    ▼                     ▼
memories.md          system prompt
    │                     │
    ▼                     ▼
┌──────────┐         LLM API
│ 元数据追踪 │
│ (Meta)    │
└─────┬────┘
      │
      ▼
memories.meta.json

         ┌──────────┐
         │ 会话结束  │
         └─────┬────┘
               │
               ▼
         ┌──────────┐
         │ LLM 提取  │
         │ (Extra.)  │
         └─────┬────┘
               │
               ▼
         memories.md
```

---

## 2. 安装与前置条件

### Rust 版本要求

- Rust 1.75+ (edition 2021)

### 添加依赖

**核心功能**（零额外网络依赖）：

```toml
[dependencies]
ai-memory-core = "0.1"
```

**含 LLM 提取功能**（需要 `reqwest` + tokio runtime）：

```toml
[dependencies]
ai-memory-core = { version = "0.1", features = ["llm-extraction"] }
```

### Feature Flags 说明

| Flag | 用途 | 额外编译依赖 |
|------|------|-------------|
| *(无)* | 核心功能：IO、分类、元数据、注入、MemorySave 工具 | `serde`, `serde_json`, `chrono`, `dirs`, `md-5` |
| `llm-extraction` | 异步 LLM 记忆提取 | 上述 + `reqwest` |

---

## 3. 数据目录配置

### 默认路径

如果不调用 `init()`，系统默认使用 `~/.ai-memory/`。

```
~/.ai-memory/
├── memories.md          # 记忆文件
└── memories.meta.json   # 元数据文件
```

### 自定义路径

```rust
use std::path::PathBuf;
use ai_memory_core::init;

// 必须在使用任何记忆函数前调用
init(PathBuf::from("/opt/my-app/data"));

// 后续所有操作都在 /opt/my-app/data/ 下进行
```

### 文件路径获取

```rust
use ai_memory_core::{memories_file, metadata_file};

// 获取当前配置下的文件路径
println!("记忆文件: {:?}", memories_file());       // data_dir/memories.md
println!("元数据文件: {:?}", metadata_file());       // data_dir/memories.meta.json
```

### 首次初始化

系统在首次保存记忆时会自动创建数据目录和 `memories.md` 骨架文件。也可以手动初始化：

```rust
use ai_memory_core::ensure_memories_file;

let path = ensure_memories_file().expect("无法创建记忆文件");
println!("记忆文件已创建: {:?}", path);
```

---

## 4. 空间隐喻系统

空间隐喻是 `ai-memory-core` 的核心设计，将记忆组织为三层分类体系。

### 三层结构

```
路径格式: Wing/Hall/Room  或  Hall/Room

Wing (维度)    — 记忆所属的语境空间（可选，省略则为全局）
Hall (主分类)  — 记忆的功能类别（必选）
Room (子分类)  — 记忆的具体主题（必选，可自由命名）
```

### 内置 Wing（维度）

| Wing | 前缀 | 说明 |
|------|------|------|
| `Wing::Project` | `"project"` | 项目维度的记忆 |
| `Wing::User` | `"user"` | 用户维度的记忆 |

### 内置 Hall（主分类）

| Hall | 显示名称 | 说明 |
|------|---------|------|
| `MemoryHall::Preferences` | `"Preferences"` | 用户/项目偏好 |
| `MemoryHall::ProjectKnowledge` | `"Project Knowledge"` | 项目相关知识 |
| `MemoryHall::Decisions` | `"Decisions"` | 做出的决策 |
| `MemoryHall::WorkflowPatterns` | `"Workflow Patterns"` | 工作流模式 |

### 路径解析

```rust
use ai_memory_core::categories::MemoryPath;

// 2 层路径（省略 Wing，全局记忆）
let path: MemoryPath = "Preferences/programming-languages".parse().unwrap();
// path.wing = None
// path.hall = MemoryHall::Preferences
// path.room = "programming-languages"

// 3 层完整路径
let path: MemoryPath = "project/Decisions/database-choice".parse().unwrap();
// path.wing = Some(Wing::Project)
// path.hall = MemoryHall::Decisions
// path.room = "database-choice"

// 获取显示名称
println!("{}", path.display());        // "project/Decisions/database-choice"
println!("{}", path.section_title());  // "## Project\n### Decisions\n#### database-choice"
```

### 路径校验

系统会对路径进行严格校验：
- 无效的 Wing 前缀返回 `Err`
- 无效的 Hall 名称返回 `Err`
- 格式错误（少于 2 个或多于 3 个部分）返回 `Err`

### 扩展分类

通过修改 `categories.rs` 中的声明式宏来扩展分类系统：

```rust
declare_wings! {
    Project : "project";
    User : "user";
    Team : "team";        // 新增
}

declare_halls! {
    Preferences : "Preferences";
    ProjectKnowledge : "Project Knowledge";
    Decisions : "Decisions";
    WorkflowPatterns : "Workflow Patterns";
    CodingStandards : "Coding Standards";   // 新增
    SecurityPolicies : "Security Policies";  // 新增
}
```

宏会自动生成所有必需的方法：`Display`、`FromStr`、`all()`、遍历支持。

---

## 5. 记忆 CRUD 操作

### 保存记忆（推荐方式）

使用 `handle_memory_save`，自动完成路径解析、内容校验、去重和文件写入：

```rust
use ai_memory_core::handle_memory_save;

// 基础用法
let result = handle_memory_save(
    "Preferences/programming-languages",
    "偏好使用 Rust 进行高性能开发"
);
match result {
    Ok(msg) => println!("{}", msg),
    Err(e) => eprintln!("保存失败: {}", e),
}

// 带 Wing 的完整路径
handle_memory_save(
    "project/Decisions/architecture",
    "采用微服务架构，使用 Kubernetes 部署"
).unwrap();
```

**自动去重**：如果同一个 section 下已存在内容相同的条目，系统只更新日期：

```rust
// 第一次保存
handle_memory_save("Preferences/editor", "使用 VS Code").unwrap();
// 文件: - [2026-06-01] 使用 VS Code

// 第二次保存相同内容
handle_memory_save("Preferences/editor", "使用 VS Code").unwrap();
// 文件: - [2026-06-01] 使用 VS Code（仅更新日期，不新增重复条目）
```

### 底层文件 IO

如果需要对文件内容进行更精细的控制：

```rust
use ai_memory_core::{load_memories, save_memories, append_to_section, format_initial_memories};

// 加载全部记忆
if let Some(memories) = load_memories() {
    println!("当前记忆:\n{}", memories);
}

// 追加到指定 section（纯文本操作，带去重）
let existing = load_memories().unwrap_or_default();
let updated = append_to_section(
    &existing,
    "## Preferences\n### communication-style",
    "- [2026-06-01] 使用中文进行日常交流"
);
save_memories(&updated).unwrap();

// 创建新文件
let new_file = format_initial_memories(
    "## Preferences",
    "- [2026-06-01] 偏好使用 TypeScript"
);
save_memories(&new_file).unwrap();

// 全量替换
save_memories("# 全新内容\n\n## Preferences\n- [2026-06-01] 重置记忆").unwrap();
```

### MemorySave 工具 Schema

为 LLM function calling 集成提供的 JSON Schema：

```rust
use ai_memory_core::memory_save_schema;

let schema = memory_save_schema();
// {
//   "type": "object",
//   "properties": {
//     "path": { "type": "string", "description": "..." },
//     "content": { "type": "string", "description": "..." }
//   },
//   "required": ["path", "content"]
// }

// 提供给 LLM API 的 tools 参数
println!("{}", serde_json::to_string_pretty(&schema).unwrap());
```

---

## 6. 元数据追踪与高价值记忆

### 元数据存储

每条记忆都有一个元数据记录，通过 `MetadataStore` 管理：

```rust
use ai_memory_core::{MetadataStore, content_fingerprint};

// 加载元数据
let mut store = MetadataStore::load();

// 记录记忆访问
let fp = content_fingerprint("偏好使用 Rust");
store.track_access(&fp);

// 再次访问同一记忆
store.track_access(&fp);

// 多次访问后，获取元数据信息
if let Some(meta) = store.get(&fp) {
    println!("访问次数: {}", meta.access_count);
    println!("是否高价值: {}", meta.is_high_value());
}

// 持久化到磁盘
store.save().unwrap();
```

### 高价值记忆

访问次数达到 **5 次及以上** 的记忆被标记为高价值，在注入时有最高优先级：

```rust
let mut store = MetadataStore::new();

// 模拟多次访问
for _ in 0..3 {
    store.track_access("低频记忆指纹");
}
for _ in 0..8 {
    store.track_access("高频记忆指纹");
}

// 获取高价值记忆
let high_value = store.high_value_memories();
for meta in high_value {
    println!("高价值记忆: {} (访问 {} 次)", meta.fingerprint, meta.access_count);
}
```

### 内容指纹

`content_fingerprint()` 基于 MD5 哈希，先对内容进行归一化（去除首尾空格），然后计算 32 位十六进制指纹：

```rust
use ai_memory_core::content_fingerprint;

let fp1 = content_fingerprint("偏好使用 Rust");
let fp2 = content_fingerprint("  偏好使用 Rust  ");  // 归一化后相同
assert_eq!(fp1, fp2);  // 相同内容的指纹相同

let fp3 = content_fingerprint("偏好使用 rust");  // 大小写不同
assert_ne!(fp1, fp3);  // 不同内容的指纹不同
```

---

## 7. 会话注入（热记忆）

### 自动注入

在每次对话开始前，将记忆注入到 system prompt：

```rust
use ai_memory_core::inject_memories_into_system_prompt;

let system_prompt = "You are a helpful coding assistant. Follow best practices.";

// 自动加载、排序、截断并注入记忆
let enriched_prompt = inject_memories_into_system_prompt(system_prompt);

// 发送给 LLM
send_to_llm(&enriched_prompt).await;
```

### 注入格式

注入的记忆以 `[USER_MEMORY] ... [/USER_MEMORY]` 标记包裹：

```
You are a helpful coding assistant. Follow best practices.

[USER_MEMORY]

偏好使用 TypeScript 和 Rust 进行日常开发
采用 PostgreSQL 作为主数据库
使用 VS Code 编辑器
每个函数必须编写单元测试
代码审查必须在合并前完成

[/USER_MEMORY]
```

### 排序策略

记忆按以下优先级排序：

1. **高价值优先** — `is_high_value == true` (access_count >= 5)
2. **访问次数** — 访问越频繁越靠前
3. **日期** — 越新的越靠前

### Token 预算控制

- 最大注入量：**2000 tokens**（约 8000 字符）
- 包含 `[USER_MEMORY]` 标记的字符数
- 超出预算的记忆自动截断

### 手动加载（用于自定义格式）

```rust
use ai_memory_core::load_memories_for_injection;

// 获取格式化后的记忆文本（无 system prompt）
let memories = load_memories_for_injection();
if !memories.is_empty() {
    // 自定义注入逻辑
    let custom_prompt = format!("## 背景知识\n{}\n\n## 指令\n请基于以上背景回答用户问题。", memories);
    send_to_llm(&custom_prompt).await;
}
```

---

## 8. LLM 记忆提取

### 完整提取流程

会话结束后，自动从对话历史中提取重要记忆：

```rust
use ai_memory_core::{build_extraction_prompt, parse_extraction_result, save_extracted_memories, extract_and_save_memories};

// === 方式一：分步执行 ===

// 1. 生成提取提示词
let conversation = "用户: 我们项目使用 TypeScript 和 React...";
let prompt = build_extraction_prompt(conversation);

// 2. 调用 LLM API（以 OpenAI 为例）
let llm_response = call_openai(&prompt).await;

// 3. 解析 LLM 返回的文本
let extracted: Vec<ExtractedMemory> = parse_extraction_result(&llm_response);
for mem in &extracted {
    println!("提取: [{}] {}", mem.path, mem.content);
}

// 4. 保存到磁盘（自动去重 + 追加）
let count = save_extracted_memories(&extracted).unwrap();
println!("保存了 {} 条记忆", count);

// === 方式二：一体化 ===

let all_in_one_result = extract_and_save_memories(&llm_response).unwrap();
```

### 使用内置 LLM 提取器（需 `llm-extraction` feature）

```rust
use ai_memory_core::extract_memories_with_llm;

async fn end_of_session(api_key: &str, conversation: &str) {
    match extract_memories_with_llm(api_key, conversation, "anthropic").await {
        Ok(count) => println!("✓ 从会话中提取了 {} 条记忆", count),
        Err(e) => eprintln!("✗ 提取失败: {}", e),
    }
}
```

### 支持的 LLM Provider

| Provider | 标识符 | 默认模型 | API 端点 |
|----------|--------|---------|----------|
| Anthropic | `"anthropic"` | `claude-3-haiku-20240307` | `api.anthropic.com/v1/messages` |
| OpenAI | `"openai"` | `gpt-3.5-turbo` | `api.openai.com/v1/chat/completions` |
| DeepSeek | `"deepseek"` | `deepseek-chat` | `api.deepseek.com/v1/chat/completions` |

### LLM 输出格式

AI 返回的格式约定（内置解析器支持 `**[Category]** content`）：

```
**[Preferences]** 使用 TypeScript 而非 JavaScript
**[Decisions]** 采用 PostgreSQL 作为主数据库
**[Knowledge]** API 端点位于 /api/v1/
```

以 `**[` 开头、`]**` 结尾的行才会被解析。输出 `NONE` 表示无记忆可提取。

### 演示模式（不调用 LLM）

```rust
use ai_memory_core::extract_memories_simple;

// 仅打印对话摘要，不实际保存（用于调试和测试）
extract_memories_simple("这是一段对话摘要...").unwrap();
// 输出:
// [Memory Extraction] Simple extraction (demo mode)
// [Memory Extraction] Conversation summary (24 chars):
// 这是一段对话摘要...
```

---

## 9. 自定义提取提示词模板

### 外部模板文件

在数据目录下创建 `prompts/memory/extract.md` 文件，系统会自动优先使用该模板：

```
data_dir/
├── memories.md
├── memories.meta.json
└── prompts/
    └── memory/
        └── extract.md        # 自定义提取提示词
```

### 模板格式

```markdown
你是一个记忆提取专家。从以下对话中提取三类记忆：

## 提取规则

1. **偏好 (Preferences)**：用户明确表达的编程语言、工具、工作流等偏好
2. **决策 (Decisions)**：重要的架构决策、技术选型、设计模式选择
3. **知识 (Knowledge)**：项目特定的业务逻辑、配置方式、API 约定

## 输出格式

**[Preferences]** 一句话描述
**[Decisions]** 一句话描述
**[Knowledge]** 一句话描述

## 质量标准

- 每条不超过 30 字
- 只提取长期有用的信息
- 忽略临时性、一次性的内容
- 无记忆可提取时输出 "NONE"

## 对话摘要

{conversation_summary}
```

### 关键约束

- 模板**必须**包含 `{conversation_summary}` 占位符
- 模板会被缓存到内存中，修改后需调用 `clear_prompt_cache()` 强制重载
- 如果模板格式导致 `build_extraction_prompt()` 生成的 prompt 中没有对话内容，提取结果将为空

```rust
use ai_memory_core::clear_prompt_cache;

// 修改模板后清除缓存
clear_prompt_cache();
```

---

## 10. 集成示例

### 示例 A：Tauri 桌面应用

```rust
// main.rs — 应用启动时初始化
use ai_memory_core::init;
use std::path::PathBuf;

fn main() {
    let app_data = dirs::data_dir()
        .expect("Cannot find data dir")
        .join("my-taiapp");

    init(app_data);

    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![save_memory, get_memories])
        .run(tauri::generate_context!())
        .expect("error running tauri");
}

// 提供给前端的命令
#[tauri::command]
fn save_memory(path: String, content: String) -> Result<String, String> {
    ai_memory_core::handle_memory_save(&path, &content)
        .map_err(|e| e.to_string())
}

#[tauri::command]
fn get_memories() -> Result<String, String> {
    ai_memory_core::load_memories()
        .ok_or("No memories found".to_string())
}
```

### 示例 B：LLM Agent 中的 system prompt 增强

```rust
use ai_memory_core::inject_memories_into_system_prompt;

async fn chat_with_llm(api_key: &str, user_message: &str) -> String {
    let base_system_prompt = "\
You are an expert programming assistant.
- Always write tests for your code
- Follow the user's preferences";

    // 注入个性化记忆
    let full_system_prompt = inject_memories_into_system_prompt(base_system_prompt);

    let response = openai_client
        .chat()
        .system(&full_system_prompt)
        .user(user_message)
        .send()
        .await;

    response.content
}
```

### 示例 C：会话结束自动提取 + 反馈循环

```rust
use ai_memory_core::{extract_memories_with_llm, inject_memories_into_system_prompt};

struct SessionContext {
    api_key: String,
    history: Vec<String>,
}

impl SessionContext {
    fn new(api_key: String) -> Self {
        Self { api_key, history: vec![] }
    }

    fn build_system_prompt(&self) -> String {
        let base = "You are a helpful AI assistant.";
        inject_memories_into_system_prompt(base)
    }

    fn add_message(&mut self, msg: &str) {
        self.history.push(msg.to_string());
    }

    async fn end_session(&self) {
        let full_conversation = self.history.join("\n");
        match extract_memories_with_llm(
            &self.api_key,
            &full_conversation,
            "anthropic",
        ).await {
            Ok(count) => println!("会话结束。提取了 {} 条新记忆，下次对话将自动引用。", count),
            Err(e) => eprintln!("记忆提取失败（不影响正常功能）: {}", e),
        }
    }
}
```

### 示例 D：CLI 工具

```rust
use std::io::{self, Write};
use ai_memory_core::{init, handle_memory_save, load_memories};
use std::path::PathBuf;

fn main() {
    init(PathBuf::from("~/.my-cli-memory"));

    loop {
        print!("记忆> ");
        io::stdout().flush().unwrap();

        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();
        let input = input.trim();

        match input {
            "" => continue,
            "exit" | "quit" => break,
            "list" => {
                if let Some(m) = load_memories() {
                    println!("{}", m);
                }
            }
            cmd if cmd.contains(":") => {
                let parts: Vec<&str> = cmd.splitn(2, ':').collect();
                let path = parts[0].trim();
                let content = parts[1].trim();
                match handle_memory_save(path, content) {
                    Ok(msg) => println!("{}", msg),
                    Err(e) => eprintln!("错误: {}", e),
                }
            }
            _ => {
                println!("用法: Hall/Room: 内容  或  list  或  exit");
            }
        }
    }
}
```

---

## 11. 最佳实践

### 记忆粒度

**DO** — 每一条记忆应该是一句话级别的独立知识点：

```
- [2026-06-01] 偏好使用 TypeScript 而非 JavaScript
- [2026-06-01] 前端使用 React 18 + Vite
```

**DON'T** — 不要把大段对话或复杂上下文作为单条记忆：

```
- [2026-06-01] 在今天的长达三小时的会话中，用户首先讨论了...
```

### 分类建议

| 场景 | 推荐路径 |
|------|---------|
| 用户编辑器偏好 | `Preferences/editor-config` |
| 项目的技术栈选型 | `Project Knowledge/frontend-stack` |
| 架构决策 | `Decisions/architecture` |
| 代码审查规范 | `Workflow Patterns/code-review` |
| 通信语言偏好 | `Preferences/communication-style` |
| 个人工具偏好 | `user/Preferences/personal-tools` |

### 提取时机

- **每次会话结束时**自动提取（异步，不阻塞用户）
- 对于短对话（< 5 轮），可跳过提取以减少 API 开销
- 提取失败不应影响用户正常使用——保持降级运行

### 提示词调优

1. 使用外部模板文件 `prompts/memory/extract.md`
2. 根据实际提取质量迭代优化模板
3. 在模板中明确"什么不该提取"比"什么该提取"更重要
4. 保持模板简洁（< 500 字），避免 LLM 产生幻觉

### Token 预算

- 默认 2000 tokens 的注入预算适合大多数场景
- 如果 system prompt 本身较长（> 4000 tokens），考虑降低注入预算
- 核心记忆信息（偏好、决策）通常 50-200 tokens 就足够

### 数据安全

- 记忆文件为纯文本 Markdown，不加密
- **不要**将敏感信息（API key、密码、个人隐私）作为记忆保存
- 记忆注入到 LLM API 的 system prompt 中，会被发送到远程 API

---

## 12. 故障排查

### 问题：记忆保存成功但下次对话没有注入

**原因**：数据目录不一致。

```bash
# 检查默认目录
ls ~/.ai-memory/memories.md

# 检查是否调用了 init() 并确认路径
```

**解决**：确认 `init()` 在应用启动时调用一次，且之后未重复调用或使用了不同的路径。

### 问题：去重不生效

**原因**：内容添加了额外的空格或与已有条目不完全一致。

```rust
// 这两条会被视为不同内容：
"- [2026-06-01] 使用 TypeScript"
"- [2026-06-01] 使用 TypeScript。"  // 末尾多了句号
```

**解决**：系统只对内容部分（去除日期前缀和首尾空格）进行去重比对。确保内容表述一致。

### 问题：LLM 提取结果为 0 条

**可能原因**：
1. 对话中没有值得提取的信息
2. 提取提示词模板过于严格或格式不正确
3. LLM 返回了 `NONE`
4. LLM 输出的格式不符合 `**[Category]** content` 约定

**排查步骤**：

```rust
use ai_memory_core::build_extraction_prompt;

// 1. 检查生成的提示词
let prompt = build_extraction_prompt("测试对话");
println!("=== 提取提示词 ===\n{}\n================\n", prompt);

// 2. 将提示词手动贴到 ChatGPT/Claude 中，检查能否正常输出
```

### 问题：并发测试中目录冲突

**原因**：测试中使用全局状态 (`init()`) 时未加 `#[serial]` 标记。

**解决**：所有使用 `init()` 的测试应标记为 `#[serial]`：

```rust
use serial_test::serial;

#[test]
#[serial]
fn test_my_feature() {
    // init() 调用...
}
```

### 问题：提取提示词模板修改后不生效

**原因**：模板被缓存到内存中。

**解决**：调用 `clear_prompt_cache()` 或在 `build_extraction_prompt()` 后续调用中自动生效。

```rust
use ai_memory_core::clear_prompt_cache;

clear_prompt_cache();  // 强制重载外部模板
```

---

*文档版本: 0.1.0 | 最后更新: 2026-06-01*
