xIPnexxIPnex

parser-sdk

一句话

ragbase-parser-sdk 让你两小时写出一个能跑在平台上的自定义文档解析器——平台提供 CLI 脚手架、契约校验、本地试跑、打包推送,你只关心"怎么把这种文件切块"这一件事

安装

发邮件要包

SDK 安装包不在公开 PyPI,请发邮件到 info@nox-lumen.com 申请:

  • 注明你要做的 parser 用途(什么文件格式 / 什么场景)
  • 我们会回复内部 PyPI 凭据 + 模板

拿到后:

pip install ragbase-parser-sdk

五分钟跑通最小例子

# 1. 起工程
ragbase-cli init parser my-parser
cd my-parser
 
# 2. 看默认模板(已经能跑)
ls
# pyproject.toml  manifest.json  src/my_parser/main.py  examples/sample.txt
 
# 3. 本地试跑
ragbase-cli parse-test --input examples/sample.txt --output ./out
cat ./out/chunks.jsonl   # 看切出来的 chunk
cat ./out/result.json    # 看产出元数据
 
# 4. 改业务逻辑
vi src/my_parser/main.py
 
# 5. 验证 + 打包
ragbase-cli skill validate
ragbase-cli skill build      # 产出 .ragskill 包
 
# 6. 推到平台
ragbase-cli skill push

你需要写的代码:就一个 parse 方法

from ragbase.parser_sdk import Parser, ParseContext, ParseResult, Chunk
 
class MyParser(Parser):
    def parse(self, ctx: ParseContext) -> ParseResult:
        text = ctx.read_text()
        chunks = []
        for i, section in enumerate(self.split_by_my_logic(text)):
            chunks.append(Chunk(
                content=section.body,
                metadata={
                    "section_no": i,
                    "tags": section.tags,
                },
            ))
        return ParseResult(chunks=chunks)
 
if __name__ == "__main__":
    from ragbase.parser_sdk import make_cli
    make_cli(MyParser).run()

这就完了。make_cli 把你的 Parser 子类包装成符合平台契约的 CLI(parse / partial-parse / info 三个子命令),平台调你的时候按契约走,不是命令行参数对得上对不上的事。

增量解析(改一个文件不重新切整个仓库)

加一个装饰器:

from ragbase.parser_sdk.decorators import incremental_update
 
class MyParser(Parser):
    @incremental_update
    def parse(self, ctx: ParseContext) -> ParseResult:
        ...

平台运行时自动调用你的 partial-parse 子命令,只切被改动的部分,避免大仓库每次全切。

manifest.json:告诉平台你能干啥

{
  "name": "my-parser",
  "version": "1.0.0",
  "kind": "parser",
  "capabilities": {
    "extensions": [".gcode", ".gco"],
    "mime_types": ["application/x-gcode"],
    "incremental": true,
    "vlm_required": false
  },
  "entry": "python -m my_parser"
}

平台启动时根据 capabilities.extensions 把对应文件自动路由到你的 parser,不需要改平台代码

跟平台约定的产出格式

文件内容
chunks.jsonl一行一个 chunk,平台直接落 ES
result.json元数据 / 错误 / 统计

Chunk 字段(部分):

字段用途
content切块文本(必填)
metadata.tags业务 tag,检索时可过滤
metadata.outline_path在文档结构里的位置(如 "权利要求.1.从属")
metadata.source_ref切块来自原文件哪段(行号 / 字节偏移)

代码类 parser 还可以填 function_decls / class_decls / references / imports 等结构化字段(M5 落地)。详见 Parser SKILL 体系 · 代码解析

调试套路

  • 本地循环:改一行 → parse-test → 看 chunks.jsonl → 改一行
  • 契约错skill validate 会对照平台契约(A-layer protocol mirror)报错,比上线后再发现舒服
  • 查产出ragbase-cli parse-test --debug 会留下中间产物方便排查

真实例子

通用例子

文件类型parser 关键逻辑
G-code 工艺文件(制造)按"工序段(G91 ↔ G90 切换)"切块;metadata 抽出"工时估算 / 用刀号 / 主轴转速"
AUTOSAR ARXML 子集(汽车)按 SWC / port / interface 切块;保留追溯属性,便于跟需求关联
公司模板 Word(办公)按"标题样式 H1/H2"分级切;按章节锚点写 outline_path,让 AI 引用时能精确指章节

代码场景:写一个"自定义代码切片器"

平台内置的 code-aware parser 默认是按函数/类(ATOMIC 节点)切。如果你团队需要不一样的切法,比如:

  • 按语义段切:注释块 + 紧邻函数签名 + 实现 = 一个 chunk
  • 按 commit hunk 切:依据 git blame 把同一次提交的代码块切到一起
  • 按调用关系切:相互调用强耦合的函数切到一个 chunk
  • 按业务域切(自家 monorepo):按目录前缀 / namespace 划分

完全可以用 parser-sdk 起一个独立的代码切片 SKILL,跟内置 code-aware 共存。

📥 完整可运行示例下载

我们准备好了一份完整能跑的参考实现,按 commit hunk 切片,输出严格遵循平台 chunk 契约:

hunk_aware_code_parser.py (右键 → 另存为)

下载之后照着文件开头的注释走 5 步就能 skill push 上线。

下面是核心逻辑节选:

from ragbase.parser_sdk import Parser, ParseContext, ParseResult, Chunk
from tree_sitter_languages import get_parser
 
class HunkAwareCodeParser(Parser):
    """按 commit hunk 切,比按函数切更贴 PR 评审场景。"""
 
    def parse(self, ctx: ParseContext) -> ParseResult:
        source = ctx.read_text()
        hunks = self.git_blame_hunks(ctx.path)   # 你自己的 hunk 划分逻辑
        tree = get_parser(ctx.language).parse(source.encode())
 
        chunks = []
        for hunk in hunks:
            # 把 hunk 内涉及的函数 / 类找出来一起放进同一个 chunk
            symbols = self.symbols_in_range(tree, hunk.start_byte, hunk.end_byte)
            chunks.append(Chunk(
                content=source[hunk.start_byte:hunk.end_byte],
                metadata={
                    "outline_path": ".".join(symbols[-1].scope_chain) if symbols else "",
                    "function_decls": [s.to_dict() for s in symbols if s.kind == "function"],
                    "class_decls":    [s.to_dict() for s in symbols if s.kind == "class"],
                    "commit_sha":     hunk.commit,
                    "hunk_author":    hunk.author,
                    "tags":           [f"author:{hunk.author}", f"commit:{hunk.commit[:8]}"],
                },
            ))
        return ParseResult(chunks=chunks)

manifest.json 把适用扩展名 + 优先级声明清楚,平台启动时自动注册:

{
  "name": "hunk-aware-code-parser",
  "version": "1.0.0",
  "kind": "parser",
  "capabilities": {
    "extensions": [".py", ".java", ".go", ".rs"],
    "priority": 50
  },
  "entry": "python -m hunk_aware_code_parser"
}

跟内置 code-aware 是怎么关系? 一个 KB 只会激活一个代码 parser——在 KB 设置里选用哪一个。两个 SKILL 共存,互不影响:默认 KB 用 code-aware,PR 评审专用 KB 切到你这个 hunk-aware-code-parser

会丢失原有的代码字段吗? 不会,只要你在 chunk metadata 里照样填 outline_path / function_decls / class_decls / references / imports代码索引三档 全部沿用——你只是改了"怎么聚合 chunk 边界",没改对外的 chunk 契约。

更通用的扩展套路(加一种新语言、改默认切法、fork 内置 SKILL)见 Parser SKILL 体系 · 代码也是文档

升级提醒(0.x → 1.0)

1.0 起 namespace 从 ragbase_parser_sdk 改成 ragbase.parser_sdk

sed -i 's/ragbase_parser_sdk/ragbase.parser_sdk/g' your_skill_dir/

旧工程一行迁好。

相关

On this page