OrionBelt Semantic Layer

Motor API-first e servidor MCP que transforma definições declarativas de modelos YAML em SQL otimizado para Postgres, Snowflake, ClickHouse, Dremio e Databricks

Documentação

OrionBelt Semantic Layer logo

OrionBelt® Camada Semântica e de Contexto, Mecanismo de Regras e Sidecar Semântico

Defina suas métricas uma vez em YAML. Deixe agentes e ferramentas de BI consultá-las sem nunca tocar no seu esquema.

Um sidecar semântico: ele acompanha os sistemas que você já executa, em vez de substituí-los.

Live Demo

Version 2.32.0 PyPI Docker pulls Python 3.12+ License: BUSL-1.1


Peça a um LLM para escrever SQL contra um esquema estrela bruto e, mais cedo ou mais tarde, ele junta duas tabelas de fatos e entrega um número de receita inflado por um fator de oito. Parece correto. Ninguém percebe.

OrionBelt é uma camada semântica e de contexto com um mecanismo de regras, e roda como um sidecar semântico. Você declara dimensões, medidas, métricas e junções em YAML versionado. OrionBelt os compila em SQL específico por dialeto por meio de uma AST real, e roteia consultas multi-fato por meio de um planejador de Camada de Fatos Composta que bloqueia os caminhos de junção que produzem armadilhas de leque. Agentes e ferramentas de BI pedem "Total Revenue" by "Country". Eles nunca veem um nome de tabela.

Nenhuma ferramenta de BI no meio. Sem bloqueio de runtime. Aponte para o que você já tem.

Quatro formas de entrada

O mesmo modelo atende a todas as superfícies que você já usa. Quatro delas, e um modelo por trás de todas as quatro:

SuperfíciePortaFalaConecte-se com
PostgreSQL wire5432Protocolo PostgresDuckDB via ATTACH, Tableau, Dremio como fonte federada, Power BI, Superset, DBeaver, Metabase, psql
Arrow Flight SQL8815gRPC + ArrowDuckDB via adbc_scanner, Tableau e Power BI por meio dos drivers Flight SQL JDBC/ODBC, clientes ADBC (Python, Go, Java)
REST8000HTTP + JSONseu código, notebooks, curl e os 8 drivers PEP 249 (que compilam aqui e executam diretamente no warehouse)
MCPstdio / HTTPModel Context Protocolagentes de IA: Claude, Cursor, Copilot, Windsurf

Ambas as superfícies SQL falam OBSQL, então SELECT "Region", "Total Sales" FROM sales_model é a mesma consulta, independentemente de qual você usou para entrar. ADBC é como você usa a superfície Flight SQL, em vez de uma quinta superfície própria, e DuckDB é um cliente que pode usar qualquer uma das superfícies SQL.

Oito formas de saída

Compila para BigQuery, ClickHouse, Databricks, Dremio, DuckDB/MotherDuck, MySQL, PostgreSQL e Snowflake. O warehouse por trás do modelo é independente da superfície à sua frente: qualquer uma das quatro superfícies, contra qualquer um dos oito dialetos.

Aqui está a consulta TPC-DS 98. Duas medidas sobre a mesma coluna, idênticas exceto por uma linha: Class Revenue está fixada em uma granularidade mais grossa do que a consulta pede.

measures:
  Store Sales Amount:
    columns: [{dataObject: Store Sales, column: Ext Sales Price}]
    aggregation: sum

  Class Revenue:
    columns: [{dataObject: Store Sales, column: Ext Sales Price}]
    aggregation: sum
    grain: {mode: FIXED, keepOnly: [Class]}   # <- pin to Class, ignore query grain

metrics:
  Revenue Ratio:
    expression: "{[Store Sales Amount]} * 100.0 / {[Class Revenue]}"

Essa única linha grain é o que se torna SUM(...) OVER (PARTITION BY "Class") abaixo.

A consulta nomeia conceitos de negócio. Sem tabelas, sem junções, sem SQL:

select:
  dimensions: [Item ID, Item Description, Category, Class, Current Price]
  measures: [Store Sales Amount, Revenue Ratio]
where:
  - {field: Category, op: inlist, value: [Sports, Books, Home]}
  - {field: Order Date, op: between, value: ["1999-02-22", "1999-03-24"]}
pip install orionbelt-semantic-layer
obsl compile tpcds.obml.yml -q Q98.yml -d duckdb
WITH "base" AS (
  SELECT
    "Item"."i_item_id" AS "Item ID",
    "Item"."i_item_desc" AS "Item Description",
    "Item"."i_category" AS "Category",
    "Item"."i_class" AS "Class",
    "Item"."i_current_price" AS "Current Price",
    CAST(SUM("Store Sales"."ss_ext_sales_price") AS DECIMAL(18, 2)) AS "Store Sales Amount",
    SUM("Store Sales"."ss_ext_sales_price") AS "Class Revenue"
  FROM "main"."store_sales" AS "Store Sales"
  LEFT JOIN "main"."item" AS "Item"
    ON "Store Sales"."ss_item_sk" = "Item"."i_item_sk"
  LEFT JOIN "main"."date_dim" AS "Date"
    ON "Store Sales"."ss_sold_date_sk" = "Date"."d_date_sk"
  WHERE
    "Item"."i_category" IN ('Sports', 'Books', 'Home')
    AND "Date"."d_date" BETWEEN '1999-02-22' AND '1999-03-24'
  GROUP BY ALL
)
SELECT
  "Item ID" AS "Item ID",
  "Item Description" AS "Item Description",
  "Category" AS "Category",
  "Class" AS "Class",
  "Current Price" AS "Current Price",
  "Store Sales Amount" AS "Store Sales Amount",
  "Store Sales Amount" * 100.0 / NULLIF(SUM("Class Revenue") OVER (PARTITION BY "Class"), 0) AS "Revenue Ratio"
FROM "base" AS "base"
ORDER BY
  "Category" ASC,
  "Class" ASC,
  "Item ID" ASC,
  "Item Description" ASC,
  "Revenue Ratio" ASC

Você não escreveu o caminho de junção, a função de janela sobre um agregado, a proteção NULLIF ou um único nome de tabela. Altere -d duckdb para -d snowflake e os mesmos dois arquivos compilam para Snowflake, ou para qualquer um dos oito dialetos.

Isso é verificado, não presumido. 40 consultas TPC-DS são construídas contra um único modelo OBML e comparadas linha por linha com o SQL de referência de cada mecanismo: 39 de 40 correspondem no DuckDB em sf=1, 37 de 40 no ClickHouse em sf=10. Cada uma das diferenças restantes remonta a uma variante de referência, em vez de um erro de compilação, e cada uma é documentada. Veja a varredura ou as consultas em examples/tpcds_queries/.

Onde o OrionBelt se encaixa

OrionBelt é um sidecar, não uma plataforma. Ele compila um modelo YAML em SQL correto e o expõe pelos protocolos que você já usa. Ele não executa um cluster, não possui seu cache nem pede que você adote uma nuvem.

Use OrionBelt quando:

  • Agentes consultam seus dados e um número silenciosamente errado é inaceitável. Consultas multi-fato passam por um planejador de Camada de Fatos Composta que bloqueia caminhos de junção com armadilhas de leque, em vez de somar silenciosamente através deles.
  • Você quer suas definições de métricas em YAML revisável, sem JavaScript ou Python na camada de modelo.
  • Sua ferramenta de BI deve se conectar pelo driver Postgres que ela já possui, sem novo conector para instalar e sem runtime de fornecedor no caminho.
  • Você faz self-host, em mais de um mecanismo, e quer um único modelo que compile para todos eles.

Use outra coisa quando:

  • Você precisa de pré-agregação e cache ajustados para dashboards de alta concorrência em escala. Cube tem anos de endurecimento de produção lá que o OrionBelt não tem.
  • Suas métricas já vivem no dbt e seu time está satisfeito lá. MetricFlow as mantém onde estão.
  • Você quer uma linguagem de análise exploratória em vez de uma camada de serviço. Malloy é um ajuste melhor.

Experimente a demonstração ao vivo com um modelo pré-carregado, ou abra o notebook Colab e execute-o contra dados TPC-H.

O que é uma Camada de Contexto?

Uma camada semântica diz ao consumidor como calcular um número: qual tabela, qual junção, qual agregado. Uma camada de contexto também diz o que o número significa e o que o negócio espera dele, em uma forma que um agente pode consultar em vez de adivinhar. No OrionBelt, esse contexto vive no mesmo modelo que as métricas:

  • Regras de negócio declaram condições sobre as dimensões, medidas e métricas do modelo: quem conta como cliente de alto valor, quais categorias não devem vender com prejuízo. O mecanismo de regras compila cada regra para a consulta que relata seus membros ou violações, e avalia uma regra ou todas por REST, MCP, CLI (obsl rules evaluate) e UI.
  • Mapeamentos de conceitos externos vinculam objetos de dados, dimensões, medidas, métricas e regras aos conceitos que sua organização já governa (schema.org, FIBO, um vocabulário interno), com proveniência.
  • O grafo OBSL expõe cada modelo carregado como RDF, para que seus artefatos, junções, regras e links de conceitos possam ser consultados com SPARQL.
  • Linhagem mostra do que uma dimensão, medida, métrica, regra ou consulta é construída, até as tabelas e junções que o planejador escolheu, como JSON, Mermaid ou Turtle vinculado ao grafo OBSL, na API, na CLI (obsl lineage) e na UI.
  • Descrições, sinônimos e proprietários em cada artefato dão aos agentes o vocabulário que os usuários realmente falam.

Agentes alcançam tudo isso por MCP e REST, ao lado das ferramentas de consulta, para que o mesmo modelo que calcula um número também possa explicá-lo. A próxima seção mostra regras e links de conceitos em um modelo.

Significado, não apenas métricas

Um modelo que só sabe que Vendas Totais é uma soma ainda deixa o agente adivinhando o que é um cliente de alto valor, ou se uma categoria vendendo com prejuízo é um bug ou um fato. Desde a 2.30, o modelo carrega isso também, e é isso que torna o OrionBelt uma camada de contexto além de uma camada semântica: regras de negócio, links para as ontologias que sua organização governa e o próprio modelo como um grafo RDF dão ao agente o significado por trás dos números, não apenas os números.

Regras de negócio são condições sobre as próprias dimensões, medidas e métricas do modelo, sem SQL. O mecanismo de regras compila cada uma para a consulta que relata suas descobertas: os membros de uma regra de classificação ou elegibilidade, as violações de uma regra de validação ou restrição.

rules:
  Non-Negative Margin:
    type: validation
    severity: error
    description: Every product category must sell for at least what it cost
    grain: [Product Category]
    condition: {field: Gross Margin, op: ">=", value: 0}

Esta regra lê uma métrica, então é agregada: ela se torna um HAVING na granularidade da categoria pelo mesmo planejador de qualquer consulta, incluindo multi-fato. POST /v1/rules/{name}/evaluate retorna as categorias infratoras para esta regra, e POST /v1/rules/evaluate executa todas as regras em um único relatório.

Links de ontologia amarram artefatos aos conceitos que sua organização já governa, como relações de mapeamento SKOS com proveniência:

ontology:
  prefixes:
    schema: "https://schema.org/"

dataObjects:
  Products:
    externalConceptMappings:
      - concept: schema:Product
        relation: exact
        justification: curated

Links nunca mudam o SQL. Eles mudam o que pode ser perguntado: cada modelo carregado também é um grafo RDF, então "quais artefatos significam um schema.org Product" é uma consulta SPARQL, e a API de descoberta responde o mesmo por REST (/concept-mappings, seu /namespaces e a lista de lacunas /unmapped).

Para um agente, essa é a diferença entre adivinhar e consultar. Por MCP, list_rules, evaluate_rule e find_concept_mappings ficam ao lado de execute_query como ferramentas.

Guias: Regras de Negócio, Mapeamentos de Conceitos Externos, Grafo OBSL e SPARQL.

Conteúdo

Quatro formas de entrada · O que é uma Camada de Contexto? · Significado, não apenas métricas · Experimente em 30 segundos · Claude Desktop / MCP · Por que OrionBelt? · Recursos · Exemplo · Documentação · Roadmap · Comercial · Desenvolvimento


Experimente em 30 Segundos

Opção A: Demonstração ao Vivo (sem instalação)

Abra a Demonstração ao Vivo — UI Gradio com um modelo de exemplo pré-carregado. Cole uma consulta, escolha um dialeto, veja o SQL instantaneamente.

Explorador de API: Swagger UI | ReDoc

Quer experimentar a superfície PostgreSQL wire? O Cloud Run é somente HTTPS, então a demonstração pública não pode expor as portas 5432 (pgwire) ou 8815 (Flight SQL). Inicie a mesma demonstração localmente em dois comandos — ela inclui o conjunto de dados DuckDB orionbelt_1_commerce embutido e a superfície OBSQL completa:

docker run --rm -d --name orionbelt-demo \
  -p 8080:8080 -p 5432:5432 -p 8815:8815 \
  -e PGWIRE_ENABLED=true \
  -e FLIGHT_ENABLED=true \
  ralforion/orionbelt-semantic-layer-api:latest

# REST + UI Gradio:   http://localhost:8080/ui
# pgwire (qualquer psql / DBeaver / Tableau / Power BI):
psql "host=localhost port=5432 user=obsl dbname=orionbelt_1_commerce sslmode=disable" \
  -c 'SELECT "Client Name", "Total Sales" LIMIT 5'
# Teste rápido do Flight SQL:
uv run python examples/obsql.py 'SELECT "Client Name", "Total Sales" LIMIT 5'

docker stop orionbelt-demo

O contêiner vem com PGWIRE_AUTH_MODE=trust (padrão), então é seguro para localhost, mas não é seguro expô-lo à internet pública. Para implantações expostas, defina AUTH_MODE=api_key (incluído na v2.12.0): o pgwire então negocia SCRAM-SHA-256 (ou texto claro sobre TLS) contra o armazenamento de chaves compartilhado.

Opção B: Google Colab (sem instalação)

Open In Colab — Notebook interativo com dados TPC-H: explore o modelo, compile consultas entre dialetos, execute contra DuckDB e veja os resultados. Requer runtime Python 3.12.

Opção C: Instalar do PyPI

pip install orionbelt-semantic-layer

Em seguida, cole em um REPL Python:

from orionbelt.parser import ReferenceResolver, TrackedLoader
from orionbelt.compiler.pipeline import CompilationPipeline
from orionbelt.models.query import QueryObject, QuerySelect

model_yaml = """
version: 1.0
dataObjects:
  Orders:
    code: ORDERS
    columns:
      Price: { code: PRICE, abstractType: float }
      Country: { code: COUNTRY, abstractType: string }
dimensions:
  Country:
    dataObject: Orders
    column: Country
    resultType: string
measures:
  Total Revenue:
    resultType: float
    aggregation: sum
    expression: "{[Orders].[Price]}"
"""

loader = TrackedLoader()
raw, source_map = loader.load_string(model_yaml)
resolver = ReferenceResolver()
model, result = resolver.resolve(raw, source_map)

query = QueryObject(select=QuerySelect(dimensions=["Country"], measures=["Total Revenue"]))
pipeline = CompilationPipeline()
output = pipeline.compile(query, model, "postgres")
print(output.sql)

Saída:

SELECT
  "Orders"."COUNTRY" AS "Country",
  CAST(SUM("Orders"."PRICE") AS NUMERIC(18, 2)) AS "Total Revenue"
FROM ORDERS AS "Orders"
GROUP BY "Orders"."COUNTRY"

Nenhum arquivo env é necessário — o pipeline de compilação é sem estado.

Inicie os servidores:

orionbelt-api                              # REST API on :8000 (Swagger UI at /docs, Gradio UI at /ui)
orionbelt-ui                               # standalone Gradio UI on :7860 (connects to API on :8000)
FLIGHT_ENABLED=true orionbelt-api          # API + Arrow Flight SQL on :8815 (DBeaver, Tableau, Power BI)
PGWIRE_ENABLED=true orionbelt-api          # API + PostgreSQL wire on :5432 (Tableau, DBeaver, Superset, psql, Dremio source)

Opção C2: Instalar com uv

uv pip install orionbelt-semantic-layer
uv run orionbelt-api                       # REST API on :8000 (Swagger UI at /docs, Gradio UI at /ui)
uv run orionbelt-ui                        # standalone Gradio UI on :7860 (connects to API on :8000)
FLIGHT_ENABLED=true uv run orionbelt-api   # API + Arrow Flight SQL on :8815 (DBeaver, Tableau, Power BI)
PGWIRE_ENABLED=true uv run orionbelt-api   # API + PostgreSQL wire on :5432 (Tableau, DBeaver, Superset, psql, Dremio source)

Use a CLI obsl (sem servidor necessário — compila em processo):

obsl validate model.yaml                                  # lint a model (exit 1 on error, CI-friendly)
obsl compile model.yaml -q query.json -d snowflake        # print the generated SQL
obsl compile model.yaml --sql 'SELECT "Region", "Sales" FROM model'  # ... or from an OBSQL string
obsl describe model.yaml                                   # overview of data objects + artefacts
obsl diagram model.yaml                                    # Mermaid ER diagram
obsl convert obml-to-osi model.yaml                        # OBML -> OSI (and osi-to-obml)
obsl execute -q query.json --server http://host           # run against a deployed model (omit MODEL)

Veja o guia da CLI para todos os comandos.

Teste a superfície Flight SQL sem uma ferramenta de BI:

uv run python examples/obsql.py 'SELECT version()'
uv run python examples/obsql.py 'SHOW TABLES'
uv run python examples/obsql.py 'SELECT "Region", "Total Sales" FROM sales LIMIT 5'

# Multi-model deployment? Pick the model with -m:
uv run python examples/obsql.py -m sales 'SHOW TABLES'
uv run python examples/obsql.py --list   # discover loaded models via REST

Experimente OBSQL em 30 segundos

OBSQL — OrionBelt Semantic QL — é a superfície SQL que ferramentas de BI e humanos realmente escrevem. Rótulos simples, marcadores MEASURE(), ou wrappers de agregação correspondentes; validação de correspondência de agregação; WITH ROLLUP / WITH CUBE; sem escape para SQL bruto do warehouse. Mesma linguagem sobre Arrow Flight SQL (v2.4+) e PostgreSQL wire (v2.5+):

PGWIRE_ENABLED=true uv run orionbelt-api &

# Every BI tool already ships a Postgres ODBC/JDBC driver — point yours at :5432
psql "host=localhost port=5432 user=obsl dbname=sales sslmode=disable" \
  -c 'SELECT "Region", "Total Sales" LIMIT 5'

# All three measure forms compile to the same vendor SQL:
psql "..." -c 'SELECT "Region", "Total Sales"        FROM sales LIMIT 5'  -- bare
psql "..." -c 'SELECT "Region", MEASURE("Total Sales") FROM sales LIMIT 5'  -- explicit marker
psql "..." -c 'SELECT "Region", SUM("Total Sales")   FROM sales LIMIT 5'  -- matching aggregate

Consulte a referência OBSQL para a gramática completa.

Opção D: Docker

Estágio 1 — Início com zero configuração (modelos carregados posteriormente via API ou UI):

docker run -p 8080:8080 ralforion/orionbelt-semantic-layer-api

Abra http://localhost:8080/docs para explorar a API.

Estágio 2 — Configuração realista com docker compose:

# docker-compose.yml
services:
  api:
    image: ralforion/orionbelt-semantic-layer-api:2.32.0
    ports: ["8080:8080"]
    env_file: .env
    volumes:
      - ./models:/app/models:ro
    environment:
      MODEL_FILES: /app/models/my-model.obml.yml

  ui:
    image: ralforion/orionbelt-semantic-layer-ui:2.32.0
    ports: ["7860:7860"]
    environment:
      API_BASE_URL: http://api:8080
docker compose up -d

Consulte .env.template para a referência completa de variáveis de ambiente.

Notas sobre Docker:

  • API_SERVER_HOST já está 0.0.0.0 dentro do contêiner — nenhuma substituição necessária.
  • MCP via stdio não funciona no Docker. Use o cliente MCP HTTP para implantações conteinerizadas.
  • Monte modelos em /app/models (ou qualquer caminho) e defina MODEL_FILES (caminhos separados por vírgula) para pré-carregar na inicialização.
  • Para produção, fixe uma tag de versão (:2.32.0) em vez de :latest.

Claude Desktop / MCP

O servidor MCP é um cliente fino separado que delega para a API REST:

orionbelt-semantic-layer-mcp

Adicione ao seu claude_desktop_config.json do Claude Desktop:

{
  "mcpServers": {
    "orionbelt": {
      "command": "uvx",
      "args": ["orionbelt-semantic-layer-mcp"]
    }
  }
}

Também funciona com Copilot, Cursor e Windsurf. Consulte o repositório MCP para opções completas de configuração.


Por que OrionBelt?

OrionBeltdbt Semantic LayerCubeMalloy
Formato do modeloSomente YAML (OBML)Python + YAMLJavaScriptDSL personalizado
Geração de SQLBaseado em AST (seguro contra injeção)Templates de stringTemplates de stringCompilador
Multi-dialeto8 dialetos, sem lock-in em tempo de execuçãodbt Cloud obrigatórioCube Cloud ou self-hostFocado em BigQuery
Consultas multi-fatoStar Schema + planejador CFL (prevenção de fan-trap)LimitadoPré-agregaçõesJoins automáticos
Superfície de integraçãoAPI REST + MCP + UI GradioAPI dbt CloudREST + GraphQLExtensão VS Code
ImplantaçãoSelf-host em qualquer lugar, binário únicoSaaS (Cloud)SaaS ou self-hostBiblioteca
LicençaBUSL-1.1 (converte para Apache 2.0)Apache 2.0AGPL / proprietáriaMIT
Significado de negócio no modeloRegras compiladas na consulta que reporta suas descobertas; links SKOS para uma ontologia externaTestes de dados em nível de coluna; meta de forma livremeta de forma livre (ai_context)Anotações, não interpretadas

Recursos

Modelagem Semântica

  • Formato OBML — modelos semânticos baseados em YAML com objetos de dados, dimensões, medidas, métricas e joins
  • Consultas entre esquemas — modela objetos de dados em múltiplos bancos de dados e esquemas em um único modelo
  • Filtros estáticos de modelo — condições WHERE obrigatórias embutidas no modelo, aplicadas automaticamente com extensão de join
  • Regras de negócio — rules declarativos sobre dimensões, medidas e métricas (classificação, elegibilidade, validação, restrição) sem SQL; compilados na consulta que reporta suas descobertas, testados um a um ou todos de uma vez em um relatório, listados e avaliados na aba Regras de Negócio da UI
  • Grafo OBSL e SPARQL — exportação de grafo RDF e consulta SPARQL somente leitura para cada modelo carregado; mapeamentos de conceitos externos vinculam objetos de dados, dimensões, medidas e métricas a uma ontologia de negócio (FIBO, schema.org, um glossário corporativo) como correspondências SKOS
  • Interoperabilidade OSI — conversão bidirecional entre OBML e o formato Open Semantic Interchange, agora desenvolvido como Apache Ossie (incubando)

Compilação SQL

  • 8 dialetos SQL — BigQuery, ClickHouse, Databricks, Dremio, DuckDB/MotherDuck, MySQL, Postgres, Snowflake
  • Geração baseada em AST — AST SQL personalizado garante SQL correto e seguro contra injeção (não templates de string)
  • Star Schema e CFL — resolução automática de joins com Composite Fact Layer para consultas multi-fato
  • Tipos de dados e precisão — embrulho automático de CAST com renderização de tipos específica do dialeto e limitação de precisão
  • Formatação de exibição — padrões de formato numérico (#,##0.00, 0.00%) em medidas/métricas com renderização ciente de localidade
  • Configurações de fuso horário — detecção automática do fuso horário da sessão do banco com fallback defaultTimezone e serialização ISO 8601
  • Validação sqlglot — verificação de sintaxe pós-geração em todos os dialetos suportados

Superfície de Integração

  • API REST — endpoints FastAPI para gerenciamento de modelos, validação, compilação e execução
  • Servidor MCP — cliente fino separado para Claude, Copilot, Cursor, Windsurf
  • Integrações de IA — LangChain, OpenAI Agents SDK, CrewAI, Google ADK, Vercel AI SDK, n8n, ChatGPT
  • UI Gradio — interface web interativa para edição de modelos, teste de consultas e diagramas ER
  • DB-API 2.0 + Flight SQL — drivers PEP 249 e servidor Arrow Flight SQL para DBeaver, Tableau, Power BI; acompanha examples/obsql.py, um pequeno CLI de terminal para testar a superfície Flight sem uma ferramenta de BI
  • DuckDB como cliente (v2.27.1+) — um shell DuckDB simples consulta a camada, em qualquer superfície. ATTACH ... (TYPE postgres) monta o modelo como uma tabela (SELECT ... FROM obsl.sales.model, um SET pg_use_text_protocol = true primeiro); a extensão da comunidade adbc_scanner faz isso via Flight SQL com Arrow o caminho todo. Medidas governadas fazem join com tabelas locais e chegam em CREATE TABLE AS. Guia
  • Protocolo PostgreSQL Wire (v2.5.0+) — superfície nativa de protocolo Postgres em :5432. Toda ferramenta de BI já inclui um driver ODBC/JDBC Postgres, então o lado do usuário é "aponte sua conexão existente para OBSL e pronto" — Tableau, DBeaver, Superset, Power BI, psql simples, e Dremio como fonte Postgres federada (Dremio → OBSL → opcionalmente de volta ao lakehouse do Dremio, círculo completo)

API voltada a Agentes

  • Saúde do modelo no carregamento — todo carregamento de modelo retorna um bloco health com dataObjects órfãos, riscos de fan-trap e dimensões inalcançáveis — agentes pulam a segunda chamada defensiva
  • Endpoint de plano de consulta — POST /query/plan retorna o entendimento do planejador (escolha do planejador, tabelas físicas, caminho de join, would_compile) sem compilar SQL ou executar; include_database_explain opcional adiciona o EXPLAIN bruto do warehouse
  • Avisos estruturados — toda lista warnings na API usa uma forma estável {code, severity, message, path, hint, context} com uma taxonomia de códigos documentada; agentes ramificam em códigos em vez de analisar mensagens
  • Recuperação difusa /find — quando uma busca não produz correspondências exatas ou de sinônimos, fallback determinístico de Levenshtein + trigrama retorna candidatos próximos com pontuações e razões
  • Exemplos de modelo — bloco OBML opcional examples: de consultas canônicas; GET /examples (com filtragem ?intent=) dá aos agentes descoberta em uma única ida e volta do que um modelo foi projetado para responder

Cache de Resultados Orientado a Frescor

  • Contratos de frescor no nível da fonte — declare blocos refresh: em entradas dataObject (intervalo / heartbeat / estático); o cache deriva TTLs de consulta dos contratos das tabelas físicas que uma consulta tocou, não de suposições do chamador
  • Invalidação por heartbeat — um POST /v1/heartbeat para uma tabela física invalida toda consulta em cache que depende dela, em todos os dataObjects e sessões
  • Metadados DuckDB + resultados Parquet — cache com suporte a arquivos com serialização precisa de tipos, expiração preguiçosa, varredura de capacidade LRU; opcional via CACHE_BACKEND=file
  • Inverte o padrão Cube/dbt/Looker — contratos vivem na fonte, não na abstração semântica; uma única fonte de verdade em todo cubo/explore/consulta salva que lê a tabela

Experiência do Desenvolvedor

  • Erros com posição na fonte — erros de validação reportam linha e coluna exatas do YAML
  • Diagramas ER — diagramas Mermaid interativos com zoom e download (MD/PNG/Turtle)
  • Gerenciamento de sessões — sessões com escopo TTL e isolamento de modelo thread-safe
  • JSON Schema — esquema completo OBML e de consulta para autocompletar na IDE (yaml-language-server)

Exemplo

Definir um Modelo Semântico (OBML)

# yaml-language-server: $schema=https://raw.githubusercontent.com/ralforion/orionbelt-semantic-layer/main/schema/obml-schema.json
version: 1.0
dataObjects:
  Customers:
    code: CUSTOMERS
    database: WAREHOUSE
    schema: PUBLIC
    columns:
      Customer ID: { code: CUSTOMER_ID, abstractType: string }
      Country:     { code: COUNTRY, abstractType: string }

  Orders:
    code: ORDERS
    database: WAREHOUSE
    schema: PUBLIC
    columns:
      Order Customer ID: { code: CUSTOMER_ID, abstractType: string }
      Price:             { code: PRICE, abstractType: float }
      Quantity:          { code: QUANTITY, abstractType: int }
    joins:
      - joinType: many-to-one
        joinTo: Customers
        columnsFrom: [Order Customer ID]
        columnsTo: [Customer ID]

dimensions:
  Country:
    dataObject: Customers
    column: Country
    resultType: string

measures:
  Revenue:
    resultType: float
    aggregation: sum
    expression: "{[Orders].[Price]} * {[Orders].[Quantity]}"
    dataType: "decimal(18, 2)"

Compilar via API REST

# Create a session
curl -s -X POST http://localhost:8080/v1/sessions | jq .session_id
# -> "a1b2c3d4"

# Load the model
curl -s -X POST http://localhost:8080/v1/sessions/a1b2c3d4/models \
  -H "Content-Type: application/json" \
  -d '{"model_yaml": "..."}' | jq .model_id
# -> "abcd1234"

# Compile a query
curl -s -X POST http://localhost:8080/v1/sessions/a1b2c3d4/query/sql \
  -H "Content-Type: application/json" \
  -d '{"model_id":"abcd1234","query":{"select":{"dimensions":["Country"],"measures":["Revenue"]}},"dialect":"postgres"}' \
  | jq -r .sql
SQL gerado (Postgres)
SELECT
  "Customers"."COUNTRY" AS "Country",
  CAST(SUM("Orders"."PRICE" * "Orders"."QUANTITY") AS NUMERIC(18, 2)) AS "Revenue"
FROM WAREHOUSE.PUBLIC.ORDERS AS "Orders"
LEFT JOIN WAREHOUSE.PUBLIC.CUSTOMERS AS "Customers"
  ON "Orders"."CUSTOMER_ID" = "Customers"."CUSTOMER_ID"
GROUP BY "Customers"."COUNTRY"

Altere dialect para bigquery, clickhouse, databricks, dremio, duckdb, mysql ou snowflake para SQL específico do dialeto.


UI Gradio

OrionBelt Gradio UI showing side-by-side OBML model editor and compiled SQL output

  • Compilador SQL — editores de modelo OBML e consulta lado a lado com realce de sintaxe, seletor de 8 dialetos, compilação com um clique com saída SQL formatada e explicação da consulta
  • Execução de consultas — executa consultas compiladas contra um banco conectado, visualiza resultados com formatação numérica ciente de localidade, painel de metadados de resposta, download TSV e cópia para área de transferência (requer QUERY_EXECUTE=true)
  • Diagrama ER — diagrama ER Mermaid interativo com zoom, alternância de colunas e download (MD/PNG/Turtle)
  • Grafo de ontologia — visualização interativa vis-network do grafo OBML (objetos de dados, dimensões, medidas, métricas, joins) com camadas alternáveis e espaçamento de nós ajustável
  • Regras de negócio: as regras do modelo com estatísticas; clique em uma linha para selecioná-la, mostre sua definição OBML, teste-a ou teste todas as regras em um relatório
  • SPARQL: SELECT / ASK somente leitura sobre o grafo OBSL do modelo, em um editor com realce de sintaxe SPARQL e uma galeria de exemplos prontos para executar
  • Barra de ferramentas do editor — botões de limpar, desfazer, refazer, enviar, baixar e copiar em todos os editores de código
  • Importação/Exportação OSI — converte entre formatos OBML e OSI
  • Modo claro/escuro — alterna via botão no cabeçalho, estado persistido entre sessões

OrionBelt Business Rules tab listing the model's rules with statistics, a selected rule's OBML definition, and the report from testing all rules

OrionBelt Ontology Graph tab showing the semantic model as an interactive network of data objects, dimensions, measures, metrics, and join relationships

Modo embutido — a UI é montada em /ui no servidor da API:

pip install orionbelt-semantic-layer && orionbelt-api
# -> UI at http://localhost:8000/ui

Modo autônomo — execute API e UI como processos separados:

orionbelt-api                                              # API on :8000
orionbelt-ui                                               # UI on :7860 (connects to API on :8000)
API_BASE_URL=http://remote-api:8080 orionbelt-ui           # point UI to a remote API

Documentação

TópicoLink
Site completo da documentaçãoralforion.com/orionbelt-semantic-layer
Instalaçãogetting-started/installation
Início rápidogetting-started/quickstart
Docker e implantaçãogetting-started/docker
Desenvolvimentogetting-started/development
Formato de modelo OBMLguide/model-format
Linguagem de consultaguide/query-language
Dialetos SQLguide/dialects
Métricas período a períodoguide/period-over-period
Análise de tendências (rank / lag / lead / ntile, médias móveis particionadas, agregados estatísticos)guide/trend-analysis
Pipeline de compilaçãoguide/compilation
Grafo OBSL e SPARQLguide/obsl
Regras de negócioguide/business-rules
Mapeamentos de conceitos externosguide/concept-mappings
Interface Gradioguide/ui
Integrações de IAguide/integrations
Interoperabilidade OSIguide/osi
Endpoints da API RESTapi/endpoints
Drivers DB-API e Flight SQLdrivers
Arquiteturareference/architecture
Configuraçãoreference/configuration
Exemplo prático do modelo de vendasexamples/sales-model
Saída multi-dialetoexamples/multi-dialect
Multi-fato: vendas e devoluçõesexamples/multi-fact
Benchmark TPC-DSexamples/tpcds
Notebook de início rápidoexamples/quickstart.ipynb
Comparação: visão geralcomparison/
Comparação: vs. dbt Semantic Layercomparison/dbt
Comparação: vs. Malloycomparison/malloy
Comparação: vs. LookML / Lookercomparison/lookml
Comparação: vs. Cubecomparison/cube
Comparação: vs. AtScalecomparison/atscale

Status e roteiro

StatusÁrea
Lançado8 dialetos SQL, API REST, servidor MCP, interface Gradio, drivers DB-API, Flight SQL, protocolo wire PostgreSQL (v2.5.0+) — Tableau / DBeaver / Superset / Power BI / psql / Dremio como fonte Postgres federada, OBSL/SPARQL, interoperabilidade OSI v0.2 com validação bidirecional de esquemas, integrações de IA (LangChain, CrewAI, ADK, etc.), herança e extensão de modelos, tipos de dados e precisão numérica, configurações de fuso horário, sobreposições de contexto de grão e filtro, Análise de tendências — janelas rolantes particionadas, MetricType.WINDOW para rank/lag/lead/ntile, 9 agregados estatísticos (CORR, COVAR_, REGR_, STDDEV_, VAR_), Autenticação unificada (v2.12.0) em REST / Flight / pgwire / UI — AUTH_MODE=api_key com armazenamento de chaves compartilhado, pgwire SCRAM-SHA-256 + texto claro, Resolução de Composabilidade de Artefatos (ACR, v2.14.0): um endpoint composables que, dada a consulta até o momento, retorna quais dimensões / medidas / métricas ainda podem ser adicionadas (incluindo candidatos CFL), potencializando a construção guiada de consultas
PlanejadoAutenticação OIDC / SSO e escopos de autorização por token, CLI para automação e CI/CD, geração de visões DDL (CREATE VIEW a partir de consultas), dialetos adicionais, integrações adicionais de ferramentas de BI, camada de pré-agregação / materialização

Ofertas comerciais

O OrionBelt Semantic Layer tem código-fonte disponível sob BUSL-1.1 até sua conversão para Apache-2.0 — a distribuição gratuita tem paridade total na superfície v2.6 lançada e é de nível de produção para uso auto-hospedado. Para equipes que desejam suporte de produção, um runtime gerenciado ou termos de análise embarcada, a RALFORION oferece:

  • Licença de análise embarcada — termos de relicenciamento para distribuir OBSL dentro de um produto comercial
  • Oferta de nuvem comercial — runtime OrionBelt gerenciado com SLAs
  • Recursos empresariais — capacidades adaptadas para implantações corporativas
  • Consultoria e suporte — implementação, modelagem e suporte de produção

Entre em contato com RALFORION d.o.o. para obter detalhes.


Projeto complementar

OrionBelt Analytics

Um servidor MCP baseado em ontologias que analisa esquemas de bancos de dados relacionais e gera ontologias RDF/OWL. Junto com o OrionBelt Semantic Layer, ele permite que assistentes de IA naveguem pelo seu cenário de dados por meio de ontologias e compilem SQL analítico seguro e ciente de dialetos.

Architecture diagram showing OrionBelt Analytics generating ontologies from database schemas, feeding into OrionBelt Semantic Layer for SQL compilation


Desenvolvimento

Contribuindo para o OrionBelt ou executando a partir do código-fonte:

git clone https://github.com/ralforion/orionbelt-semantic-layer.git
cd orionbelt-semantic-layer
uv sync                           # install all deps (dev, docs, ui, flight, drivers)
uv run orionbelt-api              # start API on :8000
# Quality
uv run pytest                     # run tests
uv run ruff check src/            # lint
uv run ruff format src/ tests/    # format
uv run mypy src/                  # type check

# Docs
uv sync --extra docs && uv run mkdocs serve  # docs on :8080

# CI workflows
./scripts/check-action-pins.sh              # verify every Action pin
./scripts/check-action-pins.sh --offline    # skip the upstream tag lookups

Fixação do GitHub Actions

Cada uses: em .github/workflows é fixado a um SHA de commit de 40 caracteres em vez de uma tag, porque uma tag como v7 é um rótulo móvel: ela executa qualquer commit para o qual seu proprietário a apontou quando o job inicia. O comentário # vX.Y.Z ao lado de cada SHA nomeia a versão exata de patch da qual esse SHA foi cortado, e ela precisa ser uma versão de patch, pois uma tag principal se move a cada atualização upstream.

Fixar define qual código é executado, mas torna a referência ilegível, então scripts/check-action-pins.sh mantém o SHA e seu comentário honestos. Ele percorre cada linha uses: e exige um SHA de commit, um proprietário de sua lista de permissões ALLOWED_OWNERS e um comentário de versão de patch exata, então resolve essa tag upstream com git ls-remote e falha quando o commit que ela nomeia não é o fixado. Ações de contêiner devem ser fixadas por digest; ações locais ./ são ignoradas. --offline verifica apenas o formato do SHA e do comentário, sem chamadas de rede.

A verificação é executada como o job pins no CI e como o primeiro passo após o checkout nos workflows que publicam (Docker, PyPI, docs), para que uma tag nunca possa enviar artefatos construídos por etapas cujas fixações nunca foram verificadas. Adicionar um proprietário a ALLOWED_OWNERS é uma decisão deliberada: um SHA correspondente à sua própria tag não diz nada sobre se essa ação pertence a este repositório.


Licença

Copyright © 2026 RALFORION d.o.o.

OrionBelt® é uma marca registrada da RALFORION d.o.o.

Licenciado sob a Business Source License 1.1 (SPDX: BUSL-1.1). O Trabalho Licenciado será convertido para Apache License 2.0 em 2030-03-16.

Trabalhos de terceiros redistribuídos pelo OrionBelt e seus termos estão listados em THIRD_PARTY_NOTICES.md.

Ao contribuir para este projeto, você concorda com o Contrato de Licença de Contribuidor.

Para consultas de licenciamento comercial, entre em contato: licensing@ralforion.com


RALFORION d.o.o.