Skip to content

上下文提取

OpenViking 采用三层异步架构处理文档解析和上下文提取。

概览

输入文件 → Parser → TreeBuilder → SemanticQueue → 向量库
           ↓           ↓              ↓
        解析转换    文件移动     L0/L1 生成
        (无 LLM)   入队语义      (LLM 异步)

设计原则:解析与语义分离,Parser 不调用 LLM,语义生成异步进行。

Parser(解析器)

Parser 负责文档格式转换和结构化,在临时目录创建文件结构。

支持格式

格式解析器扩展名支持情况
MarkdownMarkdownParser.md, .markdown已支持
纯文本TextParser.txt已支持
PDFPDFParser.pdf已支持
HTMLHTMLParser.html, .htm已支持
代码CodeRepositoryParsergithub 代码仓库等已支持
图片ImageParser.png, .jpg 等
视频AudioParser.mp3, .wav 等
音频VideoParser.mp4, .avi 等

核心流程 (以文档为例)

python
# 1. 解析文件
parse_result = registry.parse("/path/to/doc.md")

# 2. 返回临时目录 URI
parse_result.temp_dir_path  # viking://temp/abc123

智能分割

如果 document_tokens <= 1024:
    → 保存为单文件
否则:
    → 按标题分割
    → 小节 < 512 tokens → 合并
    → 大节 > 1024 tokens → 创建子目录

返回结果

python
ParseResult(
    temp_dir_path: str,    # 临时目录 URI
    source_format: str,    # pdf/markdown/html
    parser_name: str,      # 解析器名称
    parse_time: float,     # 耗时(秒)
    meta: Dict,            # 元数据
)

TreeBuilder(树构建器)

TreeBuilder 负责将临时目录移动到 AGFS,并入队语义处理。

核心流程

python
building_tree = tree_builder.finalize_from_temp(
    temp_dir_path="viking://temp/abc123",
    scope="resources",  # resources/user/agent
)

5 阶段处理

  1. 查找文档根目录:确保临时目录下恰好 1 个子目录
  2. 确定目标 URI:根据 scope 映射基础 URI
  3. 递归移动目录树:复制所有文件到 AGFS
  4. 清理临时目录:删除临时文件
  5. 入队语义生成:提交 SemanticMsg 到队列

URI 映射

scope基础 URI
resourcesviking://resources
userviking://user
agentviking://agent

SemanticQueue(语义队列)

SemanticQueue 异步处理 L0/L1 生成和向量化。

消息结构

python
SemanticMsg(
    id: str,           # UUID
    uri: str,          # 目录 URI
    context_type: str, # resource/memory/skill
    status: str,       # pending/processing/completed
)

处理流程(自底向上)

叶子目录 → 父目录 → 根目录

单目录处理步骤

  1. 并发生成文件摘要:限制并发数 10
  2. 收集子目录摘要:读取已生成的 .abstract.md
  3. 生成 .overview.md:LLM 生成 L1 概览
  4. 提取 .abstract.md:从 overview 提取 L0 摘要
  5. 写入文件:保存到 AGFS
  6. 向量化:创建 Context 并入队 EmbeddingQueue

配置参数

参数默认值说明
max_concurrent_llm10并发 LLM 调用数
max_images_per_call10单次 VLM 最大图片数
max_sections_per_call20单次 VLM 最大章节数

代码骨架提取(AST 模式)

对于代码文件,OpenViking 支持基于 tree-sitter 的 AST 骨架提取,作为 LLM 摘要的轻量替代方案,可显著降低处理成本。

工作模式

ov.conf 中通过 code_summary_mode 字段控制(参见配置文档),支持三种模式:

模式说明
"ast"对 ≥100 行的代码文件提取结构骨架,跳过 LLM 调用(默认
"llm"全部走 LLM 生成摘要(原有行为)
"ast_llm"先提取 AST 骨架,再将骨架作为上下文辅助 LLM 生成摘要

AST 提取内容

提取的骨架包含:

  • 模块级 docstring(首行)
  • import 语句列表
  • 类名、继承关系及方法签名(ast 模式仅保留 docstring 首行,ast_llm 模式保留完整 docstring)
  • 顶层函数签名

支持语言

以下语言有专属 extractor,基于 tree-sitter 实现精确提取:

语言说明
Python完整支持
JavaScript / TypeScript完整支持
Rust完整支持
Go完整支持
Java完整支持
C / C++完整支持

其他语言不在支持列表内,自动 fallback 到 LLM。

Fallback 机制

以下情况自动回退到 LLM,并在日志中记录原因,整体流程不受影响:

  • 语言不在支持列表中
  • 文件行数 < 100
  • AST 解析报错
  • 提取结果为空骨架

文件结构

openviking/parse/parsers/code/ast/
├── extractor.py      # 语言检测 + 分发入口
├── skeleton.py       # CodeSkeleton / FunctionSig / ClassSkeleton 数据结构
└── languages/        # 各语言专属 extractor

三种上下文提取

流程对比

环节ResourceMemorySkill
Parser通用流程通用流程通用流程
基础 URIviking://resourcesviking://user/memoriesviking://agent/skills
TreeBuilder scoperesourcesuser/agentagent
SemanticMsg typeresourcememoryskill

资源提取

python
# 添加资源
await client.add_resource(
    "/path/to/doc.pdf",
    reason="API 文档"
)

# 流程: Parser → TreeBuilder(scope=resources) → SemanticQueue

技能提取

python
# 添加技能
await client.add_skill({
    "name": "search-web",
    "content": "# search-web\\n..."
})

# 流程: 直接写入 viking://agent/skills/{name}/ → SemanticQueue

记忆提取

python
# 记忆从会话自动提取
await session.commit()

# 流程: MemoryExtractor → TreeBuilder(scope=user) → SemanticQueue

相关文档

Released under the Apache-2.0 License.