{"question": "OpenViking 的核心定位是什么？与传统向量数据库（如 Milvus、Pinecone）有何本质区别？", "files": ["OpenViking/README.md", "OpenViking/docs/en/concepts/01-architecture.md"], "answer": "OpenViking 是一个专门为 AI Agent 设计的开源上下文数据库（Context Database）。与传统向量数据库的本质区别在于：\n\n1. **设计范式不同**：OpenViking 采用\"文件系统范式\"统一管理记忆、资源和技能，而传统向量数据库仅提供扁平的向量存储。\n\n2. **解决的问题不同**：OpenViking 解决 Agent 开发中的五大挑战：上下文碎片化、上下文需求激增、检索效果差、上下文不可观察、记忆迭代受限。传统向量数据库主要解决向量检索问题。\n\n3. **功能特性不同**：\n   - 分层上下文加载（L0/L1/L2三层结构）显著降低 Token 消耗\n   - 目录递归检索结合目录定位与语义搜索\n   - 可视化检索轨迹，支持调试\n   - 自动会话管理，实现上下文自我迭代\n\n4. **架构层次**：OpenViking 包含 Client、Service、Retrieve、Session、Parse、Compressor、Storage 等多层架构，而传统向量数据库主要是存储和检索层。"}
{"question": "分层记忆设计（L0 抽象层、L1 概述层、L2 内容层）的设计初衷是什么？三层之间如何保持语义一致性？", "files": ["OpenViking/docs/en/concepts/03-context-layers.md"], "answer": "分层记忆设计的初衷是平衡检索效率与内容完整性。\n\n**三层结构说明**：\n- **L0（Abstract）**：最简洁的内容表示，约100 tokens，用于向量检索和快速过滤，存储在 `.abstract.md` 文件中。\n- **L1（Overview）**：约2k tokens的综合摘要，包含导航指引，用于重排序和理解访问方式，存储在 `.overview.md` 文件中。\n- **L2（Detail）**：完整原始内容，无 token 限制，仅在确认需要时加载。\n\n**语义一致性保证**：\n1. **生成机制**：SemanticProcessor 采用自底向上的方式遍历目录，为每个节点生成 L0/L1，确保层级间的语义关联。\n2. **统一来源**：所有层级都源自同一份原始内容，L0 是 L1 的精炼，L1 是 L2 的结构化摘要。\n3. **渐进式加载**：检索时先通过 L0 定位，再通过 L1 确认相关性，最后按需加载 L2，保证语义传递。\n\n**API 支持**：\n```python\nabstract = client.abstract(\"viking://resources/docs/auth\")  # L0\noverview = client.overview(\"viking://resources/docs/auth\")  # L1\ncontent = client.read(\"viking://resources/docs/auth/oauth.md\")  # L2\n```"}
{"question": "六种记忆类别（profile、preferences、entities、events、cases、patterns）的划分依据是什么？在实际应用中如何自动分类？", "files": ["OpenViking/docs/en/concepts/02-context-types.md", "OpenViking/openviking/session/memory_extractor.py"], "answer": "六种记忆类别基于人类认知模式的简化和工程考量进行划分。\n\n**划分依据**：\n\n**用户记忆**：\n- **profile**：用户基本信息，存储在 `user/memories/.overview.md`\n- **preferences**：用户偏好，按主题聚合，存储在 `user/memories/preferences/`\n- **entities**：实体记忆（人、项目、概念），存储在 `user/memories/entities/`\n- **events**：事件记录（决策、里程碑），存储在 `user/memories/events/`\n\n**Agent 记忆**：\n- **cases**：学习到的案例，存储在 `agent/memories/cases/`\n- **patterns**：学习到的模式，存储在 `agent/memories/patterns/`\n\n**自动分类机制**：\nMemoryExtractor 通过 LLM 自动提取和分类记忆。流程如下：\n1. 格式化会话消息\n2. 调用 `compression.memory_extraction` 提示词模板\n3. LLM 返回结构化的记忆候选，包含 category、abstract、overview、content\n4. 根据 category 写入对应目录\n\n**更新策略**：\n- profile、preferences、entities：可追加更新\n- events、cases、patterns：不更新，作为历史记录"}
{"question": "OpenViking 如何支持多 Agent 协作场景？不同 Agent 之间的记忆如何隔离与共享？", "files": ["OpenViking/docs/en/concepts/02-context-types.md", "OpenViking/docs/en/concepts/01-architecture.md"], "answer": "OpenViking 通过 URI 命名空间和作用域设计支持多 Agent 协作。\n\n**记忆隔离机制**：\n1. **URI 命名空间**：\n   - `viking://user/memories/` - 用户级记忆\n   - `viking://agent/memories/` - Agent 级记忆\n   - `viking://resources/` - 共享资源\n   - `viking://agent/skills/` - Agent 技能\n\n2. **作用域划分**：\n   - **User Scope**：用户相关的 profile、preferences、entities、events\n   - **Agent Scope**：Agent 学习到的 cases、patterns\n   - **Resources Scope**：共享的知识库\n\n**记忆共享机制**：\n1. **资源层共享**：所有 Agent 可以访问 `viking://resources/` 下的共享知识库。\n2. **用户记忆共享**：同一用户的不同 Agent 可以共享 `viking://user/memories/` 下的用户偏好和实体记忆。\n3. **关系管理**：通过 `.relations.json` 建立资源间的关联关系，支持跨 Agent 的上下文关联。\n\n**实际应用**：\n```python\n# Agent A 添加资源\nclient.add_resource(\"./docs/api.pdf\", target=\"viking://resources/api\")\n\n# Agent B 可以检索到\nresults = client.find(\"API usage\", target_uri=\"viking://resources/\")\n```"}
{"question": "会话的生命周期是如何管理的？commit_session 后记忆如何被持久化和索引？", "files": ["OpenViking/docs/en/concepts/08-session.md"], "answer": "会话生命周期遵循：创建 → 交互 → 提交 的模式。\n\n**生命周期管理**：\n1. **创建**：`session = client.session(session_id=\"chat_001\")`\n2. **交互**：\n   - `session.add_message(role, parts)` - 添加消息\n   - `session.used(contexts, skill)` - 记录使用的上下文/技能\n3. **提交**：`session.commit()` - 归档并提取记忆\n\n**commit 后的持久化流程**：\n1. **归档流程**：\n   - 增加 compression_index\n   - 复制当前消息到归档目录\n   - 生成结构化摘要（LLM）\n   - 清空当前消息列表\n\n2. **记忆提取**：\n   - MemoryExtractor 从消息中提取 6 类记忆\n   - 生成 L0（abstract）和 L1（overview）\n   - 写入对应的 VikingFS 目录\n\n3. **索引构建**：\n   - 对新生成的记忆内容进行向量化\n   - 写入 Vector Index 支持语义检索\n\n**消息结构**：\n- Message：id、role、parts、created_at\n- Part 类型：TextPart、ContextPart、ToolPart\n\n**返回结果**：\n```python\n{\n  \"status\": \"committed\",\n  \"memories_extracted\": 5,\n  \"active_count_updated\": 2,\n  \"archived\": True\n}\n```"}
{"question": "技能系统的设计理念是什么？与传统的 Function Calling 或 Tool Use 有何不同？", "files": ["OpenViking/docs/en/api/04-skills.md", "OpenViking/docs/en/concepts/02-context-types.md"], "answer": "技能系统的设计理念是将 Agent 可调用的能力统一管理，与 Function Calling 的区别在于存储和检索方式。\n\n**设计理念**：\n1. **统一存储**：技能作为上下文的一种类型，与记忆、资源采用相同的存储范式。\n2. **分层描述**：技能同样有 L0（简短描述）、L1（详细概述）、L2（完整定义）三层结构。\n3. **语义检索**：支持通过自然语言描述检索相关技能。\n\n**与传统 Function Calling 的区别**：\n| 维度 | OpenViking Skills | Function Calling |\n|------|-------------------|-----------------|\n| 存储方式 | 文件系统 + 向量索引 | 代码定义 |\n| 检索方式 | 语义检索 + 目录定位 | 精确匹配 |\n| 描述层次 | L0/L1/L2 三层 | 单层描述 |\n| 上下文关联 | 支持关系管理 | 无 |\n\n**存储位置**：\n```\nviking://agent/skills/{skill-name}/\n├── .abstract.md          # L0: 简短描述\n├── SKILL.md              # L1: 详细概述\n└── scripts               # L2: 完整定义\n```\n\n**支持的数据格式**：\n1. Dict（Skill 格式）\n2. Dict（MCP Tool 格式）- 自动检测并转换\n3. String（SKILL.md 内容）\n4. Path（文件或目录）"}
{"question": "OpenViking 适合哪些具体的应用场景？例如：长期记忆助手、知识库问答、代码助手等场景的适配性如何？", "files": ["OpenViking/README.md", "OpenViking/docs/en/concepts/01-architecture.md"], "answer": "OpenViking 专为 AI Agent 设计，适合需要长期上下文管理的场景。\n\n**核心应用场景**：\n\n1. **长期记忆助手**：\n   - 自动从会话中提取用户偏好、实体记忆\n   - 支持跨会话的记忆累积和检索\n   - 适配性：★★★★★（核心场景）\n\n2. **知识库问答**：\n   - 支持 PDF、Markdown、HTML 等多种文档格式\n   - 分层检索提高效率和准确性\n   - 适配性：★★★★★（核心场景）\n\n3. **代码助手**：\n   - 支持代码仓库解析（Git/Zip）\n   - 自动过滤非代码目录（.git、node_modules）\n   - 语义检索代码片段\n   - 适配性：★★★★☆（支持代码解析）\n\n4. **多模态助手**：\n   - 支持图片、视频、音频处理\n   - VLM 描述和向量化\n   - 适配性：★★★★☆（需要 VLM 支持）\n\n5. **企业知识管理**：\n   - 统一管理文档、代码、技能\n   - 支持关系管理和关联检索\n   - 适配性：★★★★★（核心场景）\n\n**场景适配关键能力**：\n- 分层上下文加载：降低 Token 成本\n- 目录递归检索：提高检索精度\n- 可视化检索轨迹：便于调试优化\n- 自动会话管理：实现记忆迭代"}
{"question": "如何评估 OpenViking 的检索质量？是否有内置的评测机制或指标？", "files": ["OpenViking/openviking/eval/__init__.py:1-25", "OpenViking/examples/eval/rag_eval.py"], "answer": "OpenViking 提供了 eval 评估模块，支持 RAGAS 等主流评测工具集成。\n\n**内置评测机制**：\n\n1. **eval 模块组成**：\n   - `EvalSample`：评估样本数据结构\n   - `EvalDataset`：评估数据集\n   - `RagasEvaluator`：RAGAS 评测适配器\n   - `RAGQueryPipeline`：RAG 查询流水线\n\n2. **支持的评测指标**（通过 RAGAS）：\n   - **faithfulness**：答案忠实度\n   - **answer_relevance**：答案相关性\n   - **context_precision**：上下文精确度\n   - **context_recall**：上下文召回率\n\n3. **评测流程**：\n```python\n# 准备评估样本\nsamples = [EvalSample(\n    query=\"问题\",\n    context=[\"检索到的上下文\"],\n    response=\"生成的答案\",\n    ground_truth=\"标准答案\"\n)]\n\n# 运行评测\nevaluator = RagasEvaluator()\nsummary = await evaluator.evaluate_dataset(dataset)\n```\n\n4. **CLI 评测工具**：\n```bash\nuv run rag_eval.py \\\n  --docs_dir ./docs \\\n  --question_file ./questions.json \\\n  --output ./results.json\n```\n\n**评测报告输出**：\n- 平均分数（mean_scores）\n- 每个样本的详细分数\n- JSON 格式结果保存"}
{"question": "OpenViking 与主流 RAG 框架（LlamaIndex、LangChain）的集成方式是什么？是否可以无缝替换其向量存储组件？", "files": ["OpenViking/docs/en/concepts/05-storage.md", "OpenViking/docs/en/api/06-retrieval.md"], "answer": "OpenViking 采用独立的存储架构，通过 API 接口与 RAG 框架集成。\n\n**存储架构**：\nOpenViking 使用双层存储架构，分离内容存储与索引存储：\n- **AGFS**：内容存储层，存储 L0/L1/L2 全部内容、多媒体文件、关系\n- **Vector Index**：索引存储层，存储 URI、向量、元数据（不含文件内容）\n\n**与 RAG 框架的集成方式**：\n\n1. **API 层集成**：\n   - 提供 `find()` 和 `search()` API\n   - `find()`：基础向量相似度搜索\n   - `search()`：复杂检索（意图分析、会话上下文、查询扩展）\n\n2. **检索结果结构**：\n```python\nclass FindResult:\n    memories: List[MatchedContext]   # 记忆上下文\n    resources: List[MatchedContext]  # 资源上下文\n    skills: List[MatchedContext]     # 技能上下文\n```\n\n3. **替换向量存储的可行性**：\n   - 可以通过 HTTP API 与 LlamaIndex/LangChain 集成\n   - 但 OpenViking 提供的是完整的上下文管理方案，不仅仅是向量存储\n   - 建议作为独立的上下文管理层使用\n\n**HTTP API 支持**：\n```bash\nPOST /api/v1/search/find\n{\n  \"query\": \"how to authenticate users\",\n  \"limit\": 10\n}\n```"}
{"question": "在生产环境中，OpenViking 的性能瓶颈可能出现在哪些环节？如何进行容量规划和性能调优？", "files": ["OpenViking/docs/en/concepts/05-storage.md", "OpenViking/openviking/storage/viking_vector_index_backend.py"], "answer": "OpenViking 的性能瓶颈主要出现在语义处理、向量检索和存储层。\n\n**潜在性能瓶颈**：\n\n1. **语义处理队列**：\n   - L0/L1 生成依赖 LLM 调用\n   - 大量资源添加时队列积压\n   - 调优：增加并发处理数、使用更快的 VLM\n\n2. **向量检索**：\n   - 大规模数据集的相似度计算\n   - 调优：使用 VikingDB 后端、调整索引参数\n\n3. **存储层**：\n   - AGFS 后端选择（local/s3/memory）\n   - 向量索引存储（本地持久化/HTTP 服务/Volcengine VikingDB）\n\n**容量规划建议**：\n\n1. **存储后端选择**：\n   - 本地开发：`backend: \"local\"`\n   - 生产环境：`backend: \"s3\"` 或 `backend: \"volcengine\"`\n\n2. **向量索引配置**：\n```json\n{\n  \"storage\": {\n    \"vectordb\": {\n      \"backend\": \"volcengine\",\n      \"dimension\": 1024\n    }\n  }\n}\n```\n\n3. **性能调优参数**：\n   - `batch_size`：嵌入请求批量大小\n   - `limit`：检索结果数量限制\n   - `score_threshold`：相关性分数阈值\n\n4. **监控指标**：\n   - 语义处理队列长度\n   - 向量检索延迟\n   - 存储层 I/O 性能"}
{"question": "VikingFS 与 AGFS 的关系是什么？为什么需要两层文件系统抽象？", "files": ["OpenViking/docs/en/concepts/05-storage.md"], "answer": "VikingFS 是 AGFS 之上的 URI 抽象层，两者构成双层存储架构。\n\n**关系说明**：\n\n```\n┌─────────────────────────────────────────┐\n│          VikingFS (URI Abstraction)      │\n│    URI Mapping · Hierarchical Access     │\n│           · Relation Management          │\n└────────────────┬────────────────────────┘\n        ┌────────┴────────┐\n        │                 │\n┌───────▼────────┐  ┌─────▼───────────┐\n│  Vector Index  │  │      AGFS       │\n│ (Semantic      │  │ (Content        │\n│  Search)       │  │  Storage)       │\n└────────────────┘  └─────────────────┘\n```\n\n**职责划分**：\n\n| 层级 | 职责 | 内容 |\n|------|------|------|\n| **VikingFS** | URI 抽象层 | URI 映射、层级访问、关系管理 |\n| **AGFS** | 内容存储层 | L0/L1/L2 全部内容、多媒体文件 |\n| **Vector Index** | 索引存储层 | URI、向量、元数据 |\n\n**为什么需要两层抽象**：\n\n1. **职责分离**：\n   - VikingFS 处理 URI 到物理路径的映射\n   - AGFS 处理实际的文件读写操作\n\n2. **后端灵活性**：\n   - AGFS 支持多种后端：localfs、s3fs、memory\n   - VikingFS 屏蔽底层存储差异\n\n3. **URI 映射示例**：\n```\nviking://resources/docs/auth  →  /local/resources/docs/auth\nviking://user/memories        →  /local/user/memories\n```\n\n4. **设计优势**：\n   - 清晰职责：向量索引负责检索，AGFS 负责存储\n   - 内存优化：向量索引不存储文件内容\n   - 独立扩展：向量索引和 AGFS 可独立扩展"}
{"question": "`client.add_resource` 支持哪些输入格式？如何处理本地目录的递归添加和子目录过滤？", "files": ["OpenViking/docs/en/api/02-resources.md", "OpenViking/openviking/parse/directory_scan.py:1-80"], "answer": "`add_resource` 支持多种输入格式，目录处理通过 directory_scan 模块实现。\n\n**支持的输入格式**：\n\n| 格式 | 扩展名 | 处理方式 |\n|------|--------|----------|\n| PDF | `.pdf` | 文本和图片提取 |\n| Markdown | `.md` | 原生支持 |\n| HTML | `.html`, `.htm` | 清理文本提取 |\n| 纯文本 | `.txt` | 直接导入 |\n| JSON/YAML | `.json`, `.yaml` | 结构化解析 |\n| 代码 | `.py`, `.js`, `.go` 等 | 语法感知解析 |\n| 图片 | `.png`, `.jpg` 等 | VLM 描述 |\n| 视频/音频 | `.mp4`, `.mp3` 等 | 转录 |\n\n**目录递归添加流程**：\n\n1. **DirectoryScan 预扫描**：\n   - 遍历目录树\n   - 分类文件为 processable / unsupported\n   - 跳过：点文件、符号链接、空文件\n\n2. **目录过滤机制**：\n```python\ndef _should_skip_directory(dir_path, root, ignore_dirs):\n    # 跳过：点目录、符号链接、IGNORE_DIRS\n```\n\n3. **内置忽略目录**：\n   - `.git`、`node_modules`、`__pycache__` 等\n   - 通过 `IGNORE_DIRS` 常量定义\n\n4. **API 参数**：\n```python\nclient.add_resource(\n    \"./documents\",           # 本地目录路径\n    target=\"viking://resources/docs\",  # 目标 URI\n    reason=\"文档说明\",        # 添加原因\n    wait=True,               # 等待处理完成\n    timeout=300              # 超时时间\n)\n```\n\n**处理流水线**：\nInput → Parser → TreeBuilder → AGFS → SemanticQueue → Vector Index"}
{"question": "向量索引是如何构建和维护的？增量更新时如何避免全量重建？", "files": ["OpenViking/openviking/storage/viking_vector_index_backend.py", "OpenViking/docs/en/concepts/05-storage.md"], "answer": "向量索引通过 VikingVectorIndexBackend 实现，支持增量更新。\n\n**索引构建流程**：\n\n1. **初始化配置**：\n```python\nconfig = VectorDBBackendConfig(\n    backend=\"local\",           # local/http/volcengine\n    path=\"./data/vectordb\",\n    dimension=1024,\n    distance_metric=\"cosine\"\n)\nbackend = VikingVectorIndexBackend(config=config)\n```\n\n2. **支持的后端模式**：\n   - **local**：本地持久化存储\n   - **http**：远程 HTTP 服务\n   - **volcengine**：火山引擎 VikingDB\n\n3. **索引特性**：\n   - 使用 BruteForce 索引进行向量相似度搜索\n   - 支持标量过滤和多操作符\n   - 每个集合自动管理索引\n\n**增量更新机制**：\n\n1. **URI 级别操作**：\n   - VikingFS 的 `rm()`、`mv()` 操作同步更新向量索引\n   - 新增内容自动触发向量化并写入索引\n\n2. **避免全量重建**：\n   - 通过 URI 唯一标识每个向量条目\n   - 更新时只删除旧向量、插入新向量\n   - 不影响其他条目的索引\n\n3. **双层存储优势**：\n   - 向量索引只存储 URI 引用和元数据\n   - 内容变更不影响索引结构\n   - 独立扩展存储和索引层\n\n**核心 API**：\n- `upsert()`：插入或更新向量\n- `delete()`：删除向量\n- `search()`：向量相似度搜索"}
{"question": "配置文件 `ov.conf` 的必填项有哪些？如何配置不同的 VLM 后端（OpenAI、Volcengine 等）？", "files": ["OpenViking/docs/en/guides/01-configuration.md:1-150"], "answer": "配置文件 `ov.conf` 包含 embedding、vlm、rerank、storage 等配置项。\n\n**必填配置项**：\n\n```json\n{\n  \"embedding\": {\n    \"dense\": {\n      \"provider\": \"volcengine\",     // 必填：volcengine/openai/vikingdb\n      \"api_key\": \"your-api-key\",    // 必填\n      \"model\": \"doubao-embedding-vision-250615\",\n      \"dimension\": 1024\n    }\n  },\n  \"vlm\": {\n    \"provider\": \"volcengine\",       // 必填\n    \"api_key\": \"your-api-key\",      // 必填\n    \"model\": \"doubao-seed-1-8-251228\"\n  }\n}\n```\n\n**VLM 后端配置**：\n\n1. **Volcengine（豆包模型）**：\n```json\n{\n  \"vlm\": {\n    \"api_base\": \"https://ark.cn-beijing.volces.com/api/v3\",\n    \"api_key\": \"your-volcengine-api-key\",\n    \"provider\": \"volcengine\",\n    \"model\": \"doubao-seed-1-8-251228\"\n  }\n}\n```\n\n2. **OpenAI**：\n```json\n{\n  \"vlm\": {\n    \"api_base\": \"https://api.openai.com/v1\",\n    \"api_key\": \"your-openai-api-key\",\n    \"provider\": \"openai\",\n    \"model\": \"gpt-4-vision-preview\"\n  }\n}\n```\n\n**Embedding 配置**：\n\n| 参数 | 说明 |\n|------|------|\n| `provider` | volcengine/openai/vikingdb |\n| `api_key` | API 密钥 |\n| `model` | 模型名称 |\n| `dimension` | 向量维度 |\n| `input` | 输入类型：text/multimodal |\n\n**可选配置**：\n- `rerank`：重排序模型配置\n- `storage`：存储后端配置"}
{"question": "`HierarchicalRetriever` 的检索流程是怎样的？如何实现从 L0 到 L2 的层级穿透检索？", "files": ["OpenViking/openviking/retrieve/hierarchical_retriever.py"], "answer": "HierarchicalRetriever 实现目录递归检索和层级穿透。\n\n**检索流程**：\n\n1. **初始化**：\n```python\nclass HierarchicalRetriever:\n    MAX_CONVERGENCE_ROUNDS = 3    # 收敛轮次\n    MAX_RELATIONS = 5            # 最大关联数\n    SCORE_PROPAGATION_ALPHA = 0.5  # 分数传播系数\n    DIRECTORY_DOMINANCE_RATIO = 1.2  # 目录分数阈值\n    GLOBAL_SEARCH_TOPK = 3       # 全局检索数量\n```\n\n2. **检索模式**：\n   - **THINKING**：深度思考模式\n   - **QUICK**：快速检索模式\n\n3. **核心方法**：\n```python\nasync def retrieve(\n    self,\n    query: TypedQuery,\n    limit: int = 5,\n    mode: RetrieverMode = RetrieverMode.THINKING,\n    score_threshold: Optional[float] = None,\n    metadata_filter: Optional[Dict[str, Any]] = None,\n) -> QueryResult:\n```\n\n**层级穿透机制**：\n\n1. **L0 检索**：\n   - 向量相似度搜索 `.abstract.md` 内容\n   - 快速过滤不相关内容\n\n2. **L1 确认**：\n   - 读取 `.overview.md` 进行重排序\n   - 确认内容相关性\n\n3. **L2 加载**：\n   - 按需读取完整内容\n   - 仅在确认需要时加载\n\n**关键特性**：\n- 分数传播：目录分数向子节点传播\n- 目录优势：目录分数需超过最大子节点分数\n- 关联检索：自动检索关联上下文"}
{"question": "语义处理队列的工作机制是什么？如何监控和调试异步处理状态？", "files": ["OpenViking/docs/en/concepts/01-architecture.md", "OpenViking/openviking/service/resource_service.py:1-80"], "answer": "语义处理队列通过 SemanticQueue 异步生成 L0/L1 内容。\n\n**工作机制**：\n\n1. **处理流水线**：\n```\nInput → Parser → TreeBuilder → AGFS → SemanticQueue → Vector Index\n```\n\n2. **队列处理**：\n   - TreeBuilder 将文件移动到 AGFS 后入队\n   - SemanticQueue 异步处理队列项\n   - 自底向上生成 L0/L1\n\n3. **异步处理优势**：\n   - 不阻塞资源添加操作\n   - 支持大规模文档处理\n   - LLM 调用并行化\n\n**监控和调试**：\n\n1. **等待处理完成**：\n```python\nresult = client.add_resource(\"./docs\", wait=False)\nclient.wait_processed()  # 等待队列处理完成\n```\n\n2. **超时控制**：\n```python\nresult = client.add_resource(\n    \"./docs\",\n    wait=True,\n    timeout=300  # 超时时间（秒）\n)\n```\n\n3. **DebugService**：\n   - 提供 ObserverService 用于调试\n   - 可视化检索轨迹\n\n4. **日志监控**：\n   - 通过 logger 获取处理状态\n   - 监控队列长度和处理延迟\n\n**Service 层支持**：\n- ResourceService 管理 add_resource 操作\n- wait_processed() 方法等待语义处理完成"}
{"question": "如何通过代码动态创建和管理 Session？Session 与 Memory 的关系是什么？", "files": ["OpenViking/docs/en/concepts/08-session.md", "OpenViking/openviking/session/memory_extractor.py"], "answer": "Session 通过 client API 动态创建，commit 后自动提取 Memory。\n\n**Session 创建和管理**：\n\n1. **创建 Session**：\n```python\n# 创建新会话\nsession = client.session(session_id=\"chat_001\")\n\n# 或使用 create_session\nresult = client.create_session()\n```\n\n2. **添加消息**：\n```python\nsession.add_message(\n    \"user\",\n    [TextPart(\"How to configure embedding?\")]\n)\n\nsession.add_message(\n    \"assistant\",\n    [\n        TextPart(\"Here's how...\"),\n        ContextPart(uri=\"viking://user/memories/profile.md\"),\n    ]\n)\n```\n\n3. **记录使用**：\n```python\nsession.used(contexts=[\"viking://user/memories/profile.md\"])\nsession.used(skill={\n    \"uri\": \"viking://agent/skills/code-search\",\n    \"input\": \"search config\",\n    \"output\": \"found 3 files\",\n    \"success\": True\n})\n```\n\n4. **提交会话**：\n```python\nresult = session.commit()\n# {\"status\": \"committed\", \"memories_extracted\": 5}\n```\n\n**Session 与 Memory 的关系**：\n\n1. **Memory 来源**：\n   - Memory 从 Session 消息中提取\n   - MemoryExtractor 在 commit 时触发\n\n2. **提取流程**：\n   - 格式化会话消息\n   - 调用 LLM 提取 6 类记忆\n   - 写入对应目录并索引\n\n3. **记忆类别映射**：\n   - profile → `user/memories/profile.md`\n   - preferences → `user/memories/preferences/`\n   - entities → `user/memories/entities/`\n   - events → `user/memories/events/`\n   - cases → `agent/memories/cases/`\n   - patterns → `agent/memories/patterns/`"}
{"question": "OpenViking Server 模式与本地模式的区别是什么？如何选择部署方式？", "files": ["OpenViking/openviking/server/bootstrap.py:1-61", "OpenViking/docs/en/concepts/01-architecture.md"], "answer": "Server 模式提供 HTTP API，本地模式直接嵌入应用。\n\n**模式对比**：\n\n| 维度 | 本地模式 | Server 模式 |\n|------|----------|-------------|\n| 访问方式 | Python SDK | HTTP API |\n| 部署复杂度 | 简单 | 需启动服务 |\n| 多客户端 | 不支持 | 支持 |\n| 资源共享 | 单进程 | 多进程共享 |\n| 适用场景 | 单机应用 | 生产环境 |\n\n**Server 模式启动**：\n\n1. **命令行启动**：\n```bash\nopenviking-server --host 0.0.0.0 --port 1933 --config ./ov.conf\n```\n\n2. **参数说明**：\n- `--host`：绑定地址\n- `--port`：端口号\n- `--config`：配置文件路径\n\n3. **HTTP API 示例**：\n```bash\ncurl -X POST http://localhost:1933/api/v1/resources \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Key: your-key\" \\\n  -d '{\"path\": \"./documents/guide.md\"}'\n```\n\n**部署方式选择**：\n\n1. **选择本地模式**：\n   - 单机应用开发\n   - 快速原型验证\n   - 无需多客户端访问\n\n2. **选择 Server 模式**：\n   - 生产环境部署\n   - 多客户端/多服务访问\n   - 需要集中式上下文管理\n   - 微服务架构集成\n\n**Service 层复用**：\n两种模式共享 Service 层逻辑，支持 HTTP Server 和 CLI 复用。"}
{"question": "如何扩展自定义的 Parser？例如支持新的文档格式或代码语言？", "files": ["OpenViking/openviking/parse/registry.py", "OpenViking/openviking/parse/parsers/base_parser.py:1-80"], "answer": "通过 ParserRegistry 注册自定义 Parser，支持 Protocol 接口。\n\n**自定义 Parser 步骤**：\n\n1. **实现 BaseParser 接口**：\n```python\nclass BaseParser(ABC):\n    @abstractmethod\n    async def parse(self, source: Union[str, Path], instruction: str = \"\", **kwargs) -> ParseResult:\n        \"\"\"解析文档\"\"\"\n        pass\n    \n    @abstractmethod\n    async def parse_content(self, content: str, source_path: Optional[str] = None, **kwargs) -> ParseResult:\n        \"\"\"解析内容\"\"\"\n        pass\n    \n    @property\n    @abstractmethod\n    def supported_extensions(self) -> List[str]:\n        \"\"\"支持的文件扩展名\"\"\"\n        pass\n```\n\n2. **注册 Parser**：\n```python\nfrom openviking.parse.registry import get_registry\n\nclass MyParser(BaseParser):\n    @property\n    def supported_extensions(self) -> List[str]:\n        return [\".myext\"]\n    \n    async def parse(self, source, instruction=\"\", **kwargs):\n        # 实现解析逻辑\n        return ParseResult(...)\n\n# 注册\nregistry = get_registry()\nregistry.register(\"my_parser\", MyParser())\n```\n\n3. **使用 Protocol 接口**：\n```python\nregistry.register_custom(\n    handler=my_parser,      # 实现 CustomParserProtocol\n    extensions=[\".custom\"],\n    name=\"custom_parser\"\n)\n```\n\n**内置 Parser**：\n- TextParser：纯文本\n- MarkdownParser：Markdown\n- PDFParser：PDF\n- HTMLParser：HTML\n- CodeRepositoryParser：代码仓库\n- ImageParser：图片（可选）\n\n**扩展点**：\n- `supported_extensions`：定义支持的扩展名\n- `can_parse()`：检查文件是否可解析\n- `_read_file()`：读取文件内容"}
{"question": "eval 模块的 RAGAS 集成是如何实现的？如何自定义评测指标？", "files": ["OpenViking/openviking/eval/ragas.py", "OpenViking/openviking/eval/base.py:1-60"], "answer": "eval 模块通过 RagasEvaluator 适配器集成 RAGAS，支持自定义评测指标。\n\n**RAGAS 集成实现**：\n\n1. **RagasEvaluator 类**：\n```python\nclass RagasEvaluator(BaseEvaluator):\n    def __init__(self, metrics=None, llm=None, embeddings=None):\n        from ragas.metrics import (\n            answer_relevance,\n            context_precision,\n            context_recall,\n            faithfulness,\n        )\n        self.metrics = metrics or [\n            faithfulness,\n            answer_relevance,\n            context_precision,\n            context_recall,\n        ]\n```\n\n2. **评测流程**：\n```python\nasync def evaluate_dataset(self, dataset: EvalDataset) -> SummaryResult:\n    # 转换为 RAGAS 数据集格式\n    data = {\n        \"question\": [s.query for s in dataset.samples],\n        \"contexts\": [s.context for s in dataset.samples],\n        \"answer\": [s.response for s in dataset.samples],\n        \"ground_truth\": [s.ground_truth for s in dataset.samples],\n    }\n    \n    # 调用 RAGAS evaluate\n    result = evaluate(data, metrics=self.metrics)\n```\n\n**自定义评测指标**：\n\n1. **继承 BaseEvaluator**：\n```python\nclass MyEvaluator(BaseEvaluator):\n    async def evaluate_sample(self, sample: EvalSample) -> EvalResult:\n        # 实现自定义评测逻辑\n        scores = {\"my_metric\": 0.85}\n        return EvalResult(sample=sample, scores=scores)\n```\n\n2. **自定义 RAGAS 指标**：\n```python\nfrom ragas import evaluate\nfrom ragas.metrics import Metric\n\nclass MyMetric(Metric):\n    name = \"my_metric\"\n    # 实现指标计算\n\nevaluator = RagasEvaluator(metrics=[MyMetric()])\n```\n\n3. **评测结果结构**：\n```python\nclass SummaryResult(BaseModel):\n    dataset_name: str\n    sample_count: int\n    mean_scores: Dict[str, float]  # 平均分数\n    results: List[EvalResult]       # 每个样本结果\n```"}
