Skip to main content

以空间为概念的统一存储、检索、编排引擎 - 像管理文件夹一样管理数据

Project description

lzm-space — 空间引擎

编码:utf8 | 作者:Lzm | 日期:2026-07-16

以空间为概念的统一存储、检索、编排引擎。

一句话:像管理文件夹一样管理数据,像仓库台账一样追踪出入库。


项目定位

lzm-space 将多个存储后端(S3/ES/SQL/Redis)抽象为统一的"空间"概念,每个空间有独立的权限、台账、路径树,并通过 lzm-edsm 进行事件驱动编排。

创建空间 → 获得空间标识
  ├─ 上传文件 → 携带空间标识 → 存入 S3/OSS
  ├─ 知识归档 → 携带空间标识 → 切片向量化 → 存入 ES
  ├─ 结构数据 → 携带空间标识 → 存入 PostgreSQL JSONB
  ├─ 热数据   → 携带空间标识 → 存入 Redis
  └─ 所有操作 → 记录台账(基于 lzm-edsm 事件溯源)

功能清单

存储后端

后端 用途 依赖
S3/MinIO/OSS 文件/对象存储 minio>=7.0 S3Backend
Elasticsearch 知识库/向量检索/全文检索 elasticsearch>=8.0 ESBackend
PostgreSQL 结构化数据(JSONB/信息柜) asyncpg>=0.29 SQLBackend
Redis 缓存/热数据/记忆 redis>=5.0 RedisBackend

用户动线(SpaceClient 统一入口)

方法 功能 层级
create_space() 创建空间 空间管理
delete_space() 删除空间 空间管理
list_spaces() 列出空间 空间管理
upload_file() 上传文件到 S3 文件管理
list_files() 列出文件 文件管理
get_file() 获取文件内容 文件管理
archive_knowledge() 归档知识(切片→向量化→ES 索引) 知识库
search() 搜索(向量/全文/混合三种策略) 知识库
expand_search() 多跳搜索(事件-实体关系扩展) 知识库
remember() 缓存记忆 记忆管理
recall() 召回记忆 记忆管理
forget() 删除记忆 记忆管理
get_ledger() 查询台账 台账

搜索策略

策略 描述 需 lzm-plugin
vector 向量余弦相似度搜索(默认)
text BM25 全文检索(multi_match)
hybrid 向量 + 全文 → RRF 融合排序

P0 差距补全(v0.1.1)

功能 状态 说明
BM25 全文检索 ES multi_match 跨 content/name/key
事件/实体提取 LLM 驱动的 event/entity 提取(lzm-plugin)
多跳搜索 实体→事件→实体权重迭代扩展
Rerank 重排序 API / Chat / 本地词法三级兜底(lzm-plugin)
SQL 后端(PG JSONB) 链式查询 API + QueryBuilder + 跨空间 Hash Join
链式查询 API QueryBuilder .filter().groupby().agg().to_list()

技术栈

技术 版本
语言 Python >=3.11
编排引擎 lzm-edsm >=0.2
S3 存储 minio >=7.0(可选)
ES 存储 elasticsearch >=8.0(可选)
Redis redis-py >=5.0(可选)
插件系统 lzm-plugin >=0.2(可选)

项目状态

  • 当前阶段:P0 差距补全完成,SQL 后端统一为 PostgreSQL JSONB
  • 版本:0.1.2
  • 测试:166+ ✅(PostgreSQL 真实环境场景验证,含 5 个业务场景模拟)
  • 重要变更:探索阶段统一 PostgreSQL,放弃 MySQL/SQLite 支持,集中优化 PG JSONB 性能
  • 进度docs/timeline.md
  • TODOdocs/todo.md

快速开始

安装

# 核心(零外部依赖)
pip install lzm-space

# 全部后端
pip install lzm-space[all]

# 指定后端
pip install lzm-space[s3,es,sql]

# + 插件系统(切片/向量化/提取/重排)
pip install lzm-space[all] lzm-plugin[all]

基础用法

import asyncio
from lzm.space import SpaceClient

client = SpaceClient()

async def main():
    # 1. 创建空间
    space = await client.create_space("my-knowledge")
    print(f"空间创建成功: {space.space_id}")

    # 2. 知识归档(需要 lzm-plugin)
    doc = """
    Python 是一种广泛使用的解释型、高级编程语言。
    它由 Guido van Rossum 于 1989 年底发明。
    Go 是 Google 开发的一种编译型、并发型编程语言。
    Rust 是 Mozilla 开发的一种系统编程语言。
    """
    result = await client.archive_knowledge(
        "my-knowledge", doc,
        chunk_strategy="heading_strict",
        extract_events=True,  # 提取事件/实体(可选)
    )
    print(f"归档完成: {result.chunk_count} 个切片")

    # 3. 向量搜索(默认策略,需 lzm-plugin)
    results = await client.search("my-knowledge", "Python")
    for r in results:
        print(f"  [{r.score:.3f}] {r.content[:60]}")

    # 4. 全文搜索(不需要 lzm-plugin)
    results = await client.search(
        "my-knowledge", "编程语言",
        strategy="text", k=5,
    )
    for r in results:
        print(f"  [BM25:{r.score:.3f}] {r.content[:60]}")

    # 5. 混合搜索(向量 + 全文 + RRF 融合)
    results = await client.search(
        "my-knowledge", "并发语言",
        strategy="hybrid", k=5,
    )
    for r in results:
        print(f"  [hybrid:{r.score:.3f}] {r.content[:60]}")

    # 6. 多跳搜索(需先 archive_knowledge(extract_events=True))
    results = await client.expand_search(
        "my-knowledge", "编程",
        initial_keys=["Python", "Go"], hops=2, k=5,
    )
    for r in results:
        print(f"  [hop:{r.hop} score:{r.score:.3f}] {r.content[:60]}")

    # 7. 记忆管理
    await client.remember("my-knowledge", "pref:lang", "Python")
    value = await client.recall("my-knowledge", "pref:lang")
    print(f"记忆: {value}")

    # 8. 查看台账
    ledger = await client.get_ledger("my-knowledge", limit=10)
    for entry in ledger:
        print(f"  [{entry.operation}] {entry.data_key}")

    # 9. 结构化数据 — SQL 后端(需安装 asyncpg)
    from lzm.space.backends.sql_backend import SQLBackend
    from lzm.space.backends.base import DataDescriptor

    sql_biz = SQLBackend("order-track", {
        "host": "localhost", "port": 5432,
        "user": "postgres", "password": "...", "database": "biz",
    })
    await sql_biz.put(DataDescriptor(key="order-001", labels={
        "product": "Widget", "amount": 2999, "status": "paid",
    }))
    # 链式查询
    results = await sql_biz.query() \
        .filter("amount > 1000") \
        .filter("status = 'paid'") \
        .groupby("product") \
        .agg({"total": "sum(amount)", "cnt": "count(*)"}) \
        .to_list()
    for r in results:
        print(f"  [SQL] product={r['product']}, total={r['total']}")

asyncio.run(main())

插件集成

lzm-space 的可选依赖 lzm-plugin 提供知识库所需的计算能力:

pip install lzm-plugin[all]
插件 功能 搜索策略依赖
chunker 文档切片 archive_knowledge
embedding 文本向量化 vector / hybrid 搜索
extractor 事件/实体提取 expand_search
reranker 搜索结果重排序

目录结构

lzm-space/
├── README.md                         # 总纲
├── pyproject.toml                    # 包配置
├── src/lzm/space/
│   ├── __init__.py                   # 包入口(导出主要类型)
│   ├── core/
│   │   ├── __init__.py
│   │   ├── node.py                   # SpaceNode, SpaceType
│   │   ├── permissions.py            # SpacePermissions, AllowEntry
│   │   ├── path.py                   # 路径解析
│   │   ├── models.py                 # 数据模型(6 个数据类)
│   │   └── client.py                 # SpaceClient 统一入口(774行)
│   ├── manager/
│   │   ├── __init__.py
│   │   └── space_manager.py          # 空间 CRUD + 后端路由
│   ├── backends/
│   │   ├── __init__.py
│   │   ├── base.py                   # StorageBackend ABC + DataDescriptor
│   │   ├── es_backend.py             # Elasticsearch 后端(~580行)
│   │   ├── sql_backend.py            # SQL 结构后端 — PostgreSQL JSONB(~420行)
│   │   ├── sql_dialect.py            # PostgreSQL 方言封装(~200行)
│   │   ├── sql_query.py              # QueryBuilder + CrossSpaceQuery(~257行)
│   │   ├── redis_backend.py          # Redis 后端(~222行)
│   │   └── s3.py                     # MinIO/S3 后端(~443行)
│   └── ledger/
│       ├── __init__.py
│       └── engine.py                 # LedgerEngine(377行)
├── docs/
│   ├── timeline.md                   # 开发进度时间线
│   ├── common-errors.md              # 常见错误归档
│   ├── coding-standards.md           # 编码规范
│   ├── todo.md                       # TODO 管理
│   └── logic-records/                # 设计文档
│       ├── 20260716-gap-analysis-vs-sag-projects.md
│       └── 20260716-multi-hop-search.md
└── tests/
    ├── conftest.py                   # 测试夹具
    ├── core/
    │   └── test_client.py            # SpaceClient 测试(22个用例)
    ├── backends/
    │   ├── test_base.py
    │   ├── test_es_backend.py
    │   ├── test_redis_backend.py
    │   └── test_s3.py
    └── manager/
        ├── test_space_manager.py
        └── test_routing.py

核心数据模型

用途 示例
SpaceNode 空间节点描述 {space_id, name, space_type, path}
DataDescriptor 统一数据描述符(跨后端) {key, value, labels, data_type}
SearchResult 搜索结果项 {descriptor_id, content, score, labels}
MultiHopSearchResult 多跳搜索结果项 {..., hop, entity_keys}
ArchiveResult 归档结果 {file_descriptor, chunk_count, status}
MemoryCategory 记忆分类(PREFERENCE/CONTEXT/STATE) {name, ttl}
ExtractionResult 事件/实体提取结果 {events, entities, relations}

常见问题

Embedding API 返回 404

OpenAI Python SDK 的 client.embeddings.create() 会自动在 base_url 后追加 /embeddings。 如果 base_url 已包含 /v1/embeddings,实际请求路径会变成 /v1/embeddings/embeddings

解决:传给 Embedding 插件的 base_url 应只到 /v1 级别。

Unclosed client session 警告

ESBackend 和 RedisBackend 内部创建了 HTTP 连接池,需要显式关闭。

解决:程序退出前调用 await backend.close()

后端注册后找不到

SpaceManager.resolve_backend(space_id, data_type)默认路由名 查找后端。

解决:注册时名称需匹配默认路由:

  • data_type="file" → 注册名 "s3"
  • data_type="chunk" → 注册名 "es"
  • data_type="record" → 注册名 "sql"(需安装 asyncpg)
  • data_type="memory" → 注册名 "redis"

相关文档

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lzm_space-0.1.2.tar.gz (68.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lzm_space-0.1.2-py3-none-any.whl (76.7 kB view details)

Uploaded Python 3

File details

Details for the file lzm_space-0.1.2.tar.gz.

File metadata

  • Download URL: lzm_space-0.1.2.tar.gz
  • Upload date:
  • Size: 68.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for lzm_space-0.1.2.tar.gz
Algorithm Hash digest
SHA256 8c69d776431280f2ce45f810d77e0d7c2f45ef2a63d6fe01268eeb63f461e2a7
MD5 e905b9fcf9b6d16ee2c16c895e99360a
BLAKE2b-256 3cad7e3e497c7859a912f8b0f6decdb5f8337d1eb5266aff8ad17ec44d346b0a

See more details on using hashes here.

File details

Details for the file lzm_space-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: lzm_space-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 76.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for lzm_space-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5d10a7e6898738ab918b4bb02a2168edce269f30416dd034fa2cfe203b8c281b
MD5 d7e48c9675323dab804f9a3fb6adbdb5
BLAKE2b-256 ddb5579f8f05c795d73a44ac315b4bba0affadaa309f585cc420e1f2a04b19f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page