TrendShift 딥다이브 · 2026-07-18 · Daily #24

apache/ossie 딥다이브
— 회사마다 다른 "매출"의 정의를, 50개 벤더가 합의한 하나의 YAML

Apache Ossie(구 Open Semantic Interchange, OSI)는 "이 회사의 매출(revenue)이란 무엇인가" 같은 비즈니스 정의를 도구에 종속되지 않는 YAML 파일로 적어 서로 주고받게 만드는 표준 규격이다. Snowflake·Databricks·dbt Labs·Salesforce·Oracle·BlackRock 등 평소엔 경쟁하는 50개 이상의 조직이 함께 만들고 있고, 2025년 11월 Apache 소프트웨어 재단의 인큐베이팅 프로젝트로 넘어갔다. 가장 먼저 각인할 것 — 이 저장소는 라이브러리도 서버도 아닌 "규격 문서 + JSON Schema + 검증기 + 벤더별 변환기 7종"이다. 쿼리를 실행하는 엔진은 아직 없고, 로드맵의 "미래 과제"로만 적혀 있다. 그래서 이 문서는 코드 성능이 아니라 표준을 설계하고 합의시키는 방법을 파고든다. (저장소: apache/ossie · Python 19.8k줄 + Java 6.6k줄 + Go 295줄 · Apache-2.0 · 스펙 v0.2.0.dev0(최신 정식 릴리스 0.1.1) · 별 1,158 · 포크 146 · 생성 2025-11-18 · 최신 push 2026-07-17 · TrendShift Daily #24)
목차
  1. 프로젝트 한 줄 요약
  2. 왜 지금 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석 — 허브 앤 스포크와 5계층 데이터 모델
  5. 디렉토리 구조 해부
  6. 학습 포인트 — 기술별 배울 것
  7. 시스템 · 실행 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

이 저장소가 정확히 무엇인가

Apache Ossie"시맨틱 모델(semantic model)을 어떤 YAML 형식으로 적을 것인가"를 정하는 규격 하나와, 그 규격을 기계가 검증할 수 있게 만든 JSON Schema, 그리고 기존 도구들의 형식을 이 규격으로 오가게 해주는 변환기 7종이 전부인 저장소다. 코드베이스라기보다 규격서(specification)에 가깝다.

TERM
시맨틱 모델 (semantic model)
데이터베이스에 있는 날것의 테이블·컬럼 위에 얹는 "비즈니스 의미 층". 예를 들어 DB에는 fct_orders.amount_usd라는 컬럼만 있지만, 시맨틱 모델은 "총매출 = SUM(orders.amount) 단, 취소 주문 제외"라고 사람 말로 정의한다. BI 대시보드·AI 에이전트가 이 정의를 읽어 같은 숫자를 낸다.
한 문장 비유

"나라마다 다른 콘센트 규격을, 여행용 만능 어댑터 하나로 통일하려는 시도."

dbt는 dbt대로, Snowflake는 Snowflake대로, Tableau는 Tableau대로 "매출"을 각자의 형식으로 적어 왔다. 도구 A에서 B로 옮기려면 매번 새 변환기를 만들어야 했다. Ossie는 가운데에 중립 규격 하나를 세워 두고 각 도구가 그것 하나만 지원하면 되게 만들려 한다.

왜 하필 지금? — AI 에이전트 때문이다. 사람은 "이 대시보드의 매출은 취소분이 빠졌나?"를 눈치껏 확인하지만, LLM은 정의가 흔들리면 그대로 틀린 숫자를 자신 있게 말한다. Ossie의 스펙에 ai_context라는 필드가 모든 계층에 1급 시민으로 들어가 있는 이유다.

저장소는 크게 네 덩어리로 나뉜다.

덩어리실체상태
규격 문서core-spec/spec.md(594줄) + spec.yaml(주석 달린 예시 233줄) + osi-schema.json(JSON Schema, 330줄)v0.2.0.dev0 (초안). 정식 릴리스는 0.1.1
온톨로지 레이어ontology/ontology.md(612줄) + ontology.json(313줄) — 물리 테이블과 무관한 순수 개념 층제안 단계
도구validation/validate.py(290줄, 실제 동작) + cli/(Go, 전부 스텁)검증기만 실동작
변환기converters/ — dbt, GoodData, Salesforce, Snowflake, Polaris, Omni, OrionBelt, Honeydew대부분 동작, 품질 편차 큼
착각 주의
"Apache 프로젝트니까 완성됐겠지" — 아니다

Go로 만든 ossie CLI는 validate·convert·plugin 세 명령이 전부 "not yet implemented"만 출력한다. 플래그 설계와 디렉토리 관리(~/.ossie/plugins)까지만 되어 있는 골격이다. 지금 실제로 쓸 수 있는 건 Python 스크립트 validation/validate.py 하나다.

또한 DISCLAIMER 파일이 명시하듯 이건 인큐베이팅(incubating) 단계다. Apache 재단이 "정식 프로젝트로 졸업시킬지 아직 검토 중"이라는 뜻이며, 안정성·거버넌스 성숙도가 보장되지 않는다.

2왜 지금 주목받는가

트렌딩 이유 · 경쟁 규격 대비 차별점

이유 1 — "AI 에이전트가 틀린 숫자를 말한다"는 절박함

README가 직접 지목하는 문제는 세 가지다: 도구마다 다르게 정의된 같은 KPI, 정의를 수동으로 맞추느라 낭비되는 시간, 그리고 "일관성 없는 비즈니스 로직에 기반해 신뢰할 수 없는 결과를 내놓는 AI 에이전트"다. 세 번째가 2026년의 결정타다.

비유

사내에 "매출"이라는 단어가 일곱 가지 뜻으로 돌아다니는 회사를 상상하자. 사람 애널리스트는 회의에서 "어느 매출이요?"라고 되묻는다. 하지만 LLM은 되묻지 않는다. 아무거나 하나 골라서 자신 있게 보고한다. 시맨틱 레이어 표준화는 원래 BI 업계의 오래된 숙제였는데, AI가 그 숙제를 "안 하면 큰일 나는 일"로 바꿔 놓았다.

이유 2 — 경쟁사 50곳이 한 테이블에 앉았다는 사건성

docs/index.md에 적힌 참여 조직에는 Alation, Anomalo, Atlan, AtScale, BlackRock, Cloudera, Databricks, dbt Labs, Snowflake, GoodData, Informatica, Mistral AI, Oracle, Qlik, Salesforce, Starburst가 함께 들어 있다. 데이터 웨어하우스 시장에서 서로를 잡아먹으려는 회사들이 같은 규격을 만든다는 것 자체가 뉴스거리다.

TERM
벤더 중립 (vendor-neutral)
특정 회사가 소유·통제하지 않는 규격. Ossie가 내세우는 핵심 차별점은 기술이 아니라 거버넌스다 — "누구의 것도 아니어서 모두가 채택할 수 있다". 반대 사례가 dbt Semantic Layer(dbt Labs 소유)나 Cube(Cube Dev 소유)다.

이유 3 — 이관 직후의 폭발적 활동량

이 저장소는 원래 open-semantic-interchange/OSI 조직에 있다가 Apache로 옮겨왔다. 커밋 로그에 그 흔적이 그대로 남아 있다.

9738b1e  Welcome Apache Ossie (incubating)
267638d  docs: flag repository as legacy, point to apache/ossie
710da10  feat(cli): scaffold ossie CLI            # (#151)
309acbf  [OSI][Omni] Add Omni semantic model converter  # (#175)
07be017  chore: add EditorConfig tab indentation for Go files  # (#225)

수치로 보면 총 212커밋 중 최근 30일(2026-06-18~07-18)에만 52커밋이 몰려 있고, 마지막 push는 이 글을 쓰기 하루 전이다. 열린 이슈 55개도 대부분 "새 변환기 추가"류다 — #227 Lightdash 변환기, #224 Databricks Unity Catalog 변환기, #222 sqlglot 기반 OSI SQL 딜렉트, #228 uv 전환.

경쟁·유사 규격과의 관계

대상Ossie와의 관계
dbt Semantic Layer
/ MetricFlow
경쟁이 아니라 "스포크"로 취급. converters/dbt가 dbt Labs의 metricflow_semantic_interfaces 패키지를 그대로 import해 양방향 변환한다. 단 dbt의 cumulative 메트릭 등은 변환 시 정보가 손실되며, 이를 숨기지 않고 ConverterIssue로 기록한다.
Cube참여 조직 목록엔 있으나 저장소에 변환기 코드 없음.
Malloy직접 비교 서술 없음. 다만 Malloy 창시자 Lloyd Tabb이 워킹그룹 참가자 명단에 있다.
OpenMetadata
/ DataHub
영역이 다르다. 저들은 "데이터 카탈로그(발견·거버넌스)", Ossie는 "모델 교환 포맷". 로드맵의 "Catalog Integration" 항목에서 향후 통합만 언급.
FIBO 등 도메인 온톨로지미정리 상태. 이슈 #220 "clarify Ossie's relationship with FIBO"가 열려 있다.
냉정한 평가
기술적 우위가 아니라 정치적 우위를 파는 프로젝트

스펙 자체를 보면 dbt·Cube보다 표현력이 뛰어나지 않다. dimensionis_time: boolean 필드 하나뿐이고, 계층(hierarchy)·단위·통화는 로드맵에만 있다. Ossie의 승부수는 "더 좋은 규격"이 아니라 "아무도 소유하지 않은 규격"이다. 따라서 이 프로젝트의 성패는 코드 품질이 아니라 벤더들이 실제로 자기 제품에 import/export를 붙여 주느냐에 달려 있다. 역사적으로 이런 컨소시엄 표준은 성공(SQL, OpenTelemetry)과 실패(수많은 XML 표준)가 반반이다.

3기술 스택 전체 지도

언어 구성 · 의존성 · 빌드 · CI

언어 구성 (실측 LOC)

언어줄 수어디에 쓰이나
Python19,802참조 구현 패키지(python/), 검증기, 변환기 6종(dbt·GoodData·Omni·OrionBelt·Honeydew·Snowflake)
YAML/JSON8,929이게 사실상 본체. 스펙 스키마, 예제 모델(TPC-DS 594줄, flights 1,155줄), 테스트 픽스처
Java6,642변환기 2종 — Apache Polaris 카탈로그 연동, Salesforce/Tableau
Go295CLI 골격. 기능이 스텁이라 줄 수가 적다

백엔드 — Python 계층

검증기 validation/validate.py

의존성 선언 방식이 재미있다. requirements.txtpyproject.toml도 없이, 파일 맨 위 주석에 의존성을 적는 PEP 723 인라인 메타데이터를 쓴다.

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "jsonschema>=4.26.0",
#   "pyyaml>=6.0.3",
#   "sqlglot>=30.12.0",
# ]
# ///
TERM
PEP 723 (인라인 스크립트 메타데이터)
파이썬 단일 파일 스크립트가 자기 의존성을 주석 블록에 적어 두는 최신 표준. uv run validate.py 한 줄이면 uv가 알아서 가상환경을 만들고 jsonschema·sqlglot을 설치해 실행한다. 사용자에게 "pip install 먼저 하세요"를 요구하지 않는 것이 핵심 — 표준 채택률을 높이려는 프로젝트에 딱 맞는 선택이다.

참조 구현 패키지 python/ (PyPI명 apache-ossie)

의존성은 pydanticpyyaml 둘뿐. 스펙을 파이썬 객체로 읽고 쓰는 얇은 층이다.

dbt 변환기 converters/dbt/

dependencies = [
  "apache-ossie>=0.2.0.dev0",
  "metricflow>=0.209.0",   # dbt Labs 패키지를 그대로 의존!
  "sqlglot>=20.0",
  "jinja2>=3.0",
  "PyYAML>=6.0",
]
# 빌드 백엔드: hatchling · 패키지 매니저: uv (uv.lock 존재)

프론트엔드 / CLI 계층 — Go

// cli/go.mod
go 1.26.2
require github.com/spf13/cobra v1.10.2   // + mousetrap, pflag
// 배포: GoReleaser (cli/.goreleaser.yaml)

Cobra의 플래그 설계는 이미 꽤 정교하다 — --from/--to 상호배타(MarkFlagsMutuallyExclusive), --input 필수, --plugin으로 변환기 경로 직접 지정, --timeout, --max-input-size. 이 설계는 "변환기를 플러그인으로 설치하고 CLI가 오케스트레이션한다"는 미래 그림을 드러낸다. 다만 실행 로직은 비어 있다.

Java 계층

converters/polaris/pom.xml, converters/salesforce/pom.xml 둘 다 Maven이고 ASF 부모 POM(org.apache:apache:39)을 상속한다. Salesforce 변환기는 HandlerFactory + PipelineStep의 파이프라인 패턴으로 구성돼 있다.

인프라 · CI · 거버넌스 설정

파일역할
.github/workflows/cli-ci.yml유일한 CI 워크플로. cli/** 경로가 바뀔 때만 돌며 go build / go vet / go test 수행. Python 변환기용 CI는 저장소에서 확인 불가
.asf.yamlASF 인프라 설정. main 브랜치 보호, 리뷰 1명 필수, dismiss_stale_reviews, required_linear_history, merge는 squash만 허용, Copilot 코드리뷰 활성화
DISCLAIMER / NOTICE / LICENSEApache 인큐베이팅 필수 3종 세트
배울 점
CI가 하나뿐인 게 오히려 정직하다

이 저장소의 핵심 산출물은 코드가 아니라 YAML 스펙과 JSON Schema다. 그래서 무거운 테스트 파이프라인 대신, 사람이 읽는 스펙 문서 변경에 7일 토론 + [VOTE] 스레드라는 훨씬 무거운 사회적 CI를 걸어 놓았다. "무엇을 자동화하고 무엇을 사람 합의에 남길 것인가"의 좋은 사례다.

4아키텍처 심화 분석

허브 앤 스포크 · 5계층 데이터 모델 · 온톨로지 층

설계 패턴 1 — 허브 앤 스포크 (hub-and-spoke)

Ossie가 존재하는 이유를 한 장의 그림으로 요약하면 이렇다. converters/README.md에 실린 다이어그램을 옮긴다.

┌─────────────┐ │ Snowflake │ └──────┬──────┘ │ ┌─────────────┐ ┌──────┴──────┐ ┌──────────────┐ │ dbt ├────┤ Ossie ├────┤ Salesforce │ └─────────────┘ └──────┬──────┘ └──────────────┘ │ ┌──────┴──────┐ │ Databricks │ └─────────────┘

수학이 단순하다. 도구가 N개일 때 서로 직접 변환기를 만들면 N × (N-1)개가 필요하다. 도구 8개면 56개다. 가운데 중립 허브를 두면 각 도구가 "허브로 내보내기 1개 + 허브에서 읽기 1개"만 만들면 되므로 2 × N = 16개로 줄어든다.

비유

항공사 노선과 같다. 모든 도시를 직항으로 잇는 대신 인천 같은 허브 공항 하나를 두면 노선 수가 급감한다. 대가는 경유의 불편 — 허브를 거치면서 원본에만 있던 정보가 깎여 나간다. dbt 변환기가 CUMULATIVE_SEMANTICS_LOSS 같은 이슈 코드를 남기는 게 정확히 이 경유 손실이다.

설계 패턴 2 — 5계층 데이터 모델

스펙의 핵심 개념은 다섯 개다. 위에서 아래로 내려가며 읽으면 된다.

semantic_model (최상위 컨테이너: 이름, 설명, ai_context) │ ├─ datasets[] "엔티티" — 물리 테이블 하나에 대응 │ ├─ source database.schema.table 또는 쿼리 │ ├─ primary_key[] 단일 / 복합 키 │ ├─ unique_keys[][] 복수의 유니크 키 │ └─ fields[] "속성/차원" — 행 단위 값 │ ├─ expression 딜렉트별 SQL 식 │ ├─ dimension { is_time: bool } ← 지금은 이게 전부 │ └─ ai_context synonyms / instructions / examples │ ├─ relationships[] 데이터셋 간 외래키 조인 │ from / to / from_columns[] / to_columns[] │ ├─ metrics[] 집계 측정치 (여러 데이터셋에 걸칠 수 있음) │ expression + ai_context │ └─ custom_extensions[] 벤더별 탈출구 { vendor_name, data }

딜렉트(dialect) — 하나의 개념, 여러 개의 SQL

Ossie는 "표현식을 하나의 언어로 통일"하지 않는다. 대신 같은 개념에 대해 여러 딜렉트의 표현식을 나란히 적게 한다.

dialects:
  - "ANSI_SQL"
  - "SNOWFLAKE"
  - "DATABRICKS"
  - "BIGQUERY"
  - "MDX"        # 다차원 큐브 질의어
  - "TABLEAU"
  - "MAQL"       # GoodData 전용
설계 트레이드오프
"여러 딜렉트 병기"는 타협의 산물이다

이상적으로는 중립 표현식 언어 하나를 정하고 각 엔진용 SQL로 컴파일해야 한다(core-spec/expression_language.md 761줄이 그 제안서다). 하지만 MDX나 MAQL처럼 SQL이 아닌 언어까지 포용하려니 "각자 자기 언어로 적되 같은 이름표를 붙이자"로 후퇴했다. 결과적으로 같은 메트릭을 4개 딜렉트로 적으면 4벌을 손으로 동기화해야 하는 부담이 생긴다. 이슈 #222(sqlglot 기반 OSI SQL 딜렉트)가 이 문제를 정면으로 다루는 중이다.

실제 YAML — 이렇게 생겼다

semantic_model:
  - name: retail_analytics
    ai_context: "소매 주문·상품 분석용 모델"
    datasets:
      - name: orders
        source: PROD.PUBLIC.FCT_ORDERS
        primary_key: [order_id]
        fields:
          - name: order_date
            expression:
              dialects:
                - dialect: ANSI_SQL
                  expression: order_date
            dimension:
              is_time: true
            ai_context:
              synonyms: ["purchase date", "transaction date"]

    relationships:
      - name: order_lines_to_products
        from: orders            # many 쪽
        to: products             # one 쪽
        from_columns: [product_id, variant_id]   # 복합 FK 지원
        to_columns:   [id, variant_id]

    metrics:
      - name: total_revenue
        expression:
          dialects:
            - dialect: ANSI_SQL
              expression: SUM(orders.amount)
        ai_context:
          synonyms: ["total sales", "revenue"]

    custom_extensions:
      - vendor_name: SNOWFLAKE
        data: '{"warehouse": "ANALYTICS_WH", "database": "PROD"}'

설계 패턴 3 — ai_context를 1급 시민으로

모델·데이터셋·필드·관계·메트릭 모든 계층ai_context가 들어간다. 그리고 JSON Schema에서 oneOf로 문자열과 객체를 둘 다 허용한다.

# 간단하게 쓰고 싶으면 문자열 하나
ai_context: "매출 분석에 사용하세요"

# 자세히 쓰고 싶으면 객체
ai_context:
  instructions: "Use this for sales analysis"
  synonyms: ["orders", "purchases", "sales"]
  examples: ["Show total sales last month"]
배울 점
"쉬운 길과 자세한 길을 동시에 열어 두기"

JSON Schema의 oneOf스칼라와 객체를 둘 다 받는 이 패턴은 설정 파일 DSL 설계의 정석이다. 입문자는 문자열 한 줄로 시작하고, 고급 사용자는 객체로 확장한다. 스키마가 조금 복잡해지는 대가로 채택 장벽을 크게 낮춘다.

설계 패턴 4 — 온톨로지 층 (두 번째 스택)

여기서 Ossie의 야심이 드러난다. Dataset/Field는 결국 물리 테이블에 묶인 논리 층인데, 그 위에 물리 스키마와 완전히 무관한 순수 개념 층을 하나 더 두려 한다(ontology/).

name: EnterpriseOntology
ontology:
  - concept:
      name: SocialSecurityNr
      type: ValueType        # 의미가 붙은 데이터 타입
      extends: [Integer]
  - concept:
      name: Employee
      type: EntityType       # 실세계 개념
      extends: [Person]
온톨로지 개념의미
EntityType실세계에 존재하는 개념 — Employee, Customer, Product
ValueType부가 의미를 가진 데이터 타입 — SocialSecurityNr는 그냥 Integer가 아니다
내장 개념Any, Boolean, Date, DateTime, Decimal, Float, Integer, String
MultiplicityManyToOne / OneToOne
개념 속성extends(상위 개념), derived_by, identify_by, requires(제약 표현식)

이 층은 별도 JSON Schema(ontology/ontology.json)를 갖고, ontology_mappings로 물리 시맨틱 모델과 연결된다. 즉 Ossie는 "물리에 붙은 시맨틱 레이어"와 "물리와 무관한 온톨로지" 두 스택을 모두 가지려 한다.

검증기 파이프라인 — 실제로 도는 유일한 코드

YAML 파일 │ ├─ 1. validate_schema() jsonschema.Draft202012Validator │ → 구조·필수 필드·타입 검사 │ ├─ 2. validate_unique_names() dataset/field/metric/relationship │ 이름 중복 검사 │ ├─ 3. validate_references() relationship의 from/to가 │ 실재하는 dataset인지 확인 │ └─ 4. validate_sql() sqlglot으로 표현식 실제 파싱 (파싱 불가 딜렉트는 건너뜀)
# validation/validate.py — 딜렉트 매핑
DIALECT_MAP = {
    "ANSI_SQL": None,      "SNOWFLAKE": "snowflake",
    "DATABRICKS": "databricks", "BIGQUERY": "bigquery",
    "MDX": None, "TABLEAU": None, "MAQL": None,
}
# sqlglot이 파싱 못하는 딜렉트는 SQL 검증 자체를 건너뛴다
SKIP_SQL_VALIDATION = {"MDX", "TABLEAU", "MAQL"}

참조 모델 — 불변(frozen) pydantic

# python/src/ossie/models.py
class OSIRelationship(BaseModel):
    model_config = ConfigDict(frozen=True, populate_by_name=True)
    name: str
    from_dataset: str = Field(..., alias="from")  # from은 파이썬 예약어!
    to: str
    from_columns: list[str]
    to_columns: list[str]

class OSIDocument(BaseModel):
    version: str = "0.2.0.dev0"
    semantic_model: list[OSISemanticModel]

    def to_osi_yaml(self, **kwargs):
        data = self.model_dump(by_alias=True, exclude_none=True,
                               mode="json", **kwargs)
        return yaml.dump(data, default_flow_style=False,
                         sort_keys=False, allow_unicode=True)

포인트 셋: frozen=True로 모델을 불변화(스펙 문서는 값 객체다), alias="from"으로 파이썬 예약어 회피, exclude_none=True로 빈 필드를 출력에서 제거해 왕복 변환(round-trip) 시 YAML이 지저분해지지 않게 한다. 그리고 OSIAIContext = Union[str, OSIAIContextObject]로 스키마의 oneOf를 파이썬 타입으로 그대로 미러링한다.

5디렉토리 구조 해부

186개 파일이 어디에 어떻게 놓여 있나
ossie/ ├── core-spec/ ★ 진짜 "표준" 본체 │ ├── spec.md 사람이 읽는 스펙 (594줄) │ ├── spec.yaml 주석 달린 YAML 예시 (233줄) │ ├── osi-schema.json 기계 검증용 JSON Schema (330줄, Draft 2020-12) │ ├── expression_language.md SQL 서브셋 제안서 (761줄, Proposed Final) │ └── img/ossie_layers.png │ ├── ontology/ ★ 개념 층 (물리 스키마와 무관) │ ├── ontology.md (612줄) │ └── ontology.json (313줄) │ ├── converters/ ★ 벤더 변환기 8종 (허브의 스포크) │ ├── dbt/ Python · MetricFlow 직접 의존 · 양방향 │ ├── gooddata/ Python · LDM ↔ Ossie · 양방향 │ ├── honeydew/ Python │ ├── omni/ Python · topic/view YAML │ ├── orionbelt/ Python · OBML 양방향 (외부 레포 미러) │ ├── polaris/ Java · Apache Polaris 카탈로그 │ ├── salesforce/ Java · Tableau/Salesforce │ └── snowflake/ Python · Cortex Analyst YAML (단방향) │ ├── validation/validate.py ★ 실제로 도는 검증 CLI (290줄) │ ├── python/ 참조 구현 패키지 (apache-ossie) │ └── src/ossie/models.py pydantic 모델 (182줄) │ ├── cli/ Go CLI — 전부 스텁 │ ├── cmd/{root,validate,convert}.go │ ├── cmd/plugin/{install,list,remove}.go │ ├── internal/ossiedir/ ~/.ossie/plugins 관리 (여긴 구현됨) │ └── go.mod, .goreleaser.yaml │ ├── examples/ 완전한 예제 모델 │ ├── tpcds_semantic_model.yaml (594줄) TPC-DS 벤치마크 스키마 │ └── flights.yaml (1,155줄) │ ├── docs/ index.md, working_groups.md 등 │ (정적 사이트는 별도 ossie-website 레포) ├── compliance/ README 1줄뿐 — 준수성 테스트용, 아직 텅 빔 │ └── CONTRIBUTING.md, ROADMAP.md, DISCLAIMER, NOTICE, LICENSE, .asf.yaml

어디부터 읽어야 하나 — 읽는 순서 추천

순서파일
1core-spec/spec.yaml주석이 많은 예시라 스펙 전체 모양을 10분에 파악할 수 있다
2examples/tpcds_semantic_model.yaml장난감이 아닌 실제 규모(594줄)의 모델이 어떻게 생겼는지
3validation/validate.py스펙이 어떻게 강제되는지 — 290줄이라 통독 가능
4core-spec/osi-schema.jsonJSON Schema 작성법 학습용 교재로 훌륭하다
5converters/README.md"Writing a Converter" 8단계 가이드 + 허브앤스포크 근거
6ROADMAP.md / CONTRIBUTING.md미결 논쟁이 뭔지, Apache 거버넌스가 어떻게 도는지
함정
compliance/가 비어 있다는 사실의 무게

표준 프로젝트에서 준수성 테스트 스위트(compliance test suite)는 규격 문서만큼 중요하다. "우리 제품은 Ossie를 지원합니다"라는 주장을 검증할 수단이 없으면, 각 벤더가 제멋대로 해석한 방언들이 생겨나 표준이 무의미해진다. 지금 이 디렉토리는 README 한 줄뿐이다. 이 프로젝트가 진짜인지 판단하려면 compliance/가 채워지는지를 지켜보면 된다.

6학습 포인트

기술별로 무엇을 배울 수 있는가

1) JSON Schema로 "검증 가능한 규격" 만들기

osi-schema.json은 JSON Schema 학습 교재로 쓸 만하다. 실제로 쓰인 기법들:

기법Ossie에서의 쓰임
$defs + $refDataset·Field·Metric·Relationship을 재사용 가능한 정의로 분리
oneOfai_context를 문자열 또는 객체 둘 다 허용
additionalProperties: false오타 난 필드를 조용히 무시하지 않고 에러로 잡아냄
중첩 배열unique_keys가 "배열의 배열" — 복수의 복합 유니크 키 표현
free-form 문자열vendor_name을 일부러 enum으로 안 함 → 스펙 개정 없이 새 벤더 확장 가능
TERM
additionalProperties: false
스키마에 정의되지 않은 필드가 있으면 검증 실패시키는 옵션. 켜면 discription 같은 오타를 즉시 잡지만, 벤더가 임의 필드를 넣을 수 없어 확장성이 떨어진다. Ossie는 엄격하게 잠그되 custom_extensions라는 공식 탈출구를 따로 판 절충안을 택했다.

2) 이중 표현 전략 — 사람용과 기계용을 나란히

같은 스펙을 세 벌로 유지한다. spec.md(산문 설명) / spec.yaml(주석 많은 예시) / osi-schema.json(기계 검증). 중복처럼 보이지만 각각 독자가 다르다 — 의사결정자, 구현자, 도구.

비유

가구 조립 설명서와 같다. 완성 사진(spec.md), 단계별 그림(spec.yaml), 그리고 나사 규격표(osi-schema.json). 셋 다 필요하고, 셋이 어긋나면 아무도 조립하지 못한다. 표준 프로젝트의 실질적 난이도는 이 세 벌을 동기화하는 데 있다.

3) pydantic으로 불변 도메인 모델 만들기

배울 것: frozen=True(값 객체), alias로 예약어 회피, Union 타입으로 스키마 oneOf 미러링, model_dump(by_alias=True, exclude_none=True, mode="json")으로 깔끔한 왕복 직렬화.

4) sqlglot으로 다중 SQL 딜렉트 다루기

sqlglot은 20종 이상의 SQL 방언을 파싱·변환하는 파이썬 라이브러리다. Ossie는 검증에만 쓰지만, 이 라이브러리 자체가 "SQL을 문자열이 아니라 AST로 다루는" 세계로 들어가는 관문이다. 이슈 #222는 여기서 더 나아가 sqlglot에 OSI 전용 딜렉트를 등록해 표현식을 자동 트랜스파일하자는 제안이다.

5) 손실을 숨기지 않는 변환기 설계

dbt 변환기의 msi_to_osi.py는 dbt의 PydanticSemanticManifest를 순회하며 Entity/Dimension/Measure를 Ossie Field로, dbt Metric을 OSIMetric으로 옮긴다. 이때 옮길 수 없는 것을 조용히 버리지 않고 명시적으로 기록한다.

ConverterIssueType.CUMULATIVE_SEMANTICS_LOSS
ConverterIssueType.CONVERSION_METRIC_DROPPED
배울 점
"무손실인 척하지 않기"가 신뢰를 만든다

포맷 변환기를 만들 때 가장 흔한 죄는 변환 못 하는 걸 조용히 버리는 것이다. 사용자는 나중에 숫자가 틀어지고 나서야 알게 된다. Ossie 변환기는 손실 항목을 타입이 붙은 이슈 객체로 리포팅한다. 어떤 ETL·마이그레이션 코드를 짜든 그대로 훔쳐 쓸 수 있는 패턴이다.

6) Apache 거버넌스 실물 관찰

CONTRIBUTING.md가 유난히 상세해서, 오픈소스 거버넌스를 글이 아니라 실물로 볼 수 있다.

개념Ossie에서의 실제
PPMCPodling PMC — 인큐베이팅 프로젝트의 운영위
Mentors / IPMC인큐베이터 PMC가 상위 감독. 릴리스는 dev@ossie.apache.org 투표 → general@incubator.apache.org 투표 2단계
lazy consensus일반 코드 PR — committer 1명 이상 +1, veto 없으면 병합
스펙 변경7일 토론 + [VOTE] 스레드 + PPMC +1 3표 이상
ICLA / CCLA개인/회사 기여자 라이선스 동의서

7) PEP 723 · uv · hatchling — 2026년 파이썬 패키징 관행

validate.py의 인라인 메타데이터, 변환기들의 uv.lock, 빌드 백엔드 hatchling. setup.py 시대를 건너뛰고 현재 관행을 바로 배울 수 있는 샘플이다. (열린 이슈 #228이 "저장소 전체를 uv로 전환"이다.)

8) Cobra(Go) CLI 스캐폴딩

기능은 비었지만 골격은 배울 만하다. MarkFlagsMutuallyExclusive(상호배타 플래그), MarkFlagsOneRequired, PersistentPreRunE. 특히 Cobra가 PersistentPreRunE를 부모→자식으로 자동 상속하지 않는다는 함정을 코드 주석으로 직접 경고해 둔 부분이 실전 지식이다.

7시스템 · 실행 요구사항

돌려보려면 무엇이 필요한가

다행히 요구사항이 거의 없다. GPU도 클라우드 계정도 필요 없고, YAML 파일을 읽고 검증하는 것이 전부다.

구성요소요구사항비고
검증기Python 3.11+ (uv 권장)의존성 3개(jsonschema, pyyaml, sqlglot). uv가 있으면 설치 불필요
참조 패키지Python 3.11+, pydanticpip install apache-ossie
dbt 변환기Python + uvmetricflow를 끌어오므로 의존성이 무거움
OrionBelt 변환기Python 3.12+다른 변환기보다 요구 버전이 높다
Java 변환기Maven + JDKpolaris, salesforce
CLIGo 1.26.2빌드는 되지만 실행하면 "not yet implemented"
메모리/디스크사실상 무관저장소 전체 1.3MB
좋은 점
진입 장벽이 거의 0에 가깝다

대부분의 트렌딩 AI 저장소가 GPU·API 키·도커를 요구하는 것과 달리, Ossie는 노트북에서 텍스트 파일 하나 고치고 python validate.py 한 줄이면 끝난다. 표준을 배우기에 이보다 좋은 조건은 없다.

8직접 해볼 수 있는 실습 과제

난이도별 5개
과제 1난이도 ★☆☆☆☆ · 20분

예제를 검증하고, 일부러 망가뜨려 보기

git clone --depth 1 https://github.com/apache/ossie.git
cd ossie
python validation/validate.py examples/tpcds_semantic_model.yaml

통과를 확인한 뒤 일부러 세 가지를 망가뜨려 각각 어느 검증 단계에서 잡히는지 관찰한다: ① 필드 이름 하나를 다른 필드와 같게 만들기(→ validate_unique_names), ② relationship의 to를 없는 데이터셋 이름으로 바꾸기(→ validate_references), ③ 메트릭 표현식을 SUM(orders.amount처럼 괄호를 빠뜨리기(→ validate_sql).

배우는 것: "스키마 검증"과 "의미 검증"이 왜 별개인지. JSON Schema는 ②③을 절대 못 잡는다.

과제 2난이도 ★★☆☆☆ · 1~2시간

내 데이터를 Ossie 모델로 직접 작성하기

가계부 CSV, 운동 기록, 게임 전적 등 자기 데이터를 골라 datasets 2개 이상 + relationship 1개 + metric 3개로 모델링한다. 검증을 통과시키는 것이 목표.

여기서 진짜 배우는 건 문법이 아니라 "내 메트릭의 정의가 사실은 모호했다"는 자각이다. "이번 달 지출"에 환불은 포함인가? 카드 결제일 기준인가 승인일 기준인가? — 이걸 ai_context.instructions에 문장으로 적어 보면 시맨틱 레이어가 왜 필요한지 몸으로 알게 된다.

과제 3난이도 ★★★☆☆ · 반나절

참조 패키지로 "모델 리포트 생성기" 만들기

from ossie.models import OSIDocument
import yaml

doc = OSIDocument(**yaml.safe_load(open("examples/tpcds_semantic_model.yaml")))
for model in doc.semantic_model:
    for m in (model.metrics or []):
        print(m.name, "|", m.expression.dialects[0].expression)

여기서 확장: ① ai_context가 비어 있는 메트릭 목록(= AI가 오해할 위험 지점) 뽑기, ② 어떤 relationship에도 참여하지 않는 고아 데이터셋 찾기, ③ 결과를 마크다운 표로 출력. 배우는 것: 스펙을 "읽는 도구"를 만들면 스펙 구조가 머리에 박힌다.

과제 4난이도 ★★★★☆ · 며칠

Go CLI의 validate 명령을 실제로 구현하기

cli/cmd/validate.gorunValidate가 지금 "not yet implemented"만 출력한다. Python validate.py의 4단계 파이프라인을 Go로 이식한다 — gopkg.in/yaml.v3로 파싱, santhosh-tekuri/jsonschema로 스키마 검증, 이름 유일성·참조 무결성은 직접 구현.

배우는 것: 같은 로직을 두 언어로 짜 보면 "스펙 준수 구현이 여러 개 있을 때 생기는 미묘한 불일치"라는 표준의 진짜 어려움을 체감한다. (SQL 검증까지는 무리다 — Go에 sqlglot 대응물이 마땅치 않다는 것 자체가 발견이다.)

과제 5난이도 ★★★★★ · 1~2주

새 변환기를 작성해 실제로 PR 보내기

converters/README.md의 "Writing a Converter" 8단계 가이드를 따라 아직 없는 도구용 변환기를 만든다 — Metabase, Superset, Looker(LookML), Lightdash(이슈 #227에 이미 요청이 있다) 등.

최소 스코프: 대상 도구의 모델 파일을 파싱해 dataset/field/metric만 Ossie YAML로 내보내고, 손실 항목을 ConverterIssue로 기록. converters/dbt를 구조 템플릿으로 삼으면 된다.

배우는 것: Apache 기여 프로세스 실전(ICLA 서명, dev 메일링 리스트, PR 리뷰). 이력서에 "Apache 프로젝트 컨트리뷰터"를 적을 수 있는 현실적으로 가장 쉬운 경로 중 하나다 — 이 프로젝트는 지금 변환기를 절실히 원한다.

9관련 기술 심화 학습 로드맵

4주 코스
주차주제할 것
1주차시맨틱 레이어 개념Ossie 스펙 통독 + 과제 1·2. 병행해서 dbt의 MetricFlow 문서, Cube 문서를 훑어 "같은 문제를 다르게 푼 세 가지"를 비교. 핵심 질문: 차원(dimension)과 메트릭(metric)을 왜 분리하는가?
2주차스키마 언어와 DSL 설계JSON Schema Draft 2020-12 공식 문서 + osi-schema.json 정독. 직접 작은 설정 파일 스키마를 설계해 보기. oneOf/anyOf/allOf 차이, $ref 순환 참조 문제를 실습으로 확인
3주차SQL을 AST로 다루기sqlglot 튜토리얼 — 파싱, 딜렉트 변환(transpile), AST 순회. 과제 3을 확장해 "모든 메트릭 표현식에서 참조되는 컬럼 목록 추출" 구현. 이게 되면 lineage(계보) 분석의 기초를 잡은 것
4주차데이터 카탈로그 · 거버넌스OpenMetadata나 DataHub를 도커로 띄워 보고, "카탈로그"와 "시맨틱 레이어"의 역할 차이를 정리. 병행해서 Ossie의 ROADMAP.md·GitHub Discussions를 읽으며 미결 논쟁 파악 → 과제 5로 기여
코스 설계 의도

이 로드맵은 "AI 시대의 데이터 엔지니어"가 되는 경로다. 파이프라인을 짜는 기술(Airflow·Spark)은 이미 성숙했고, 지금 부족한 인력은 "비즈니스 정의를 기계가 읽을 수 있는 형태로 옮기는 사람"이다. Ossie는 그 일을 배우기에 가장 부담 없는 교재다 — 인프라가 필요 없으니까.

10핵심 키워드 사전

이 문서에 나온 용어 정리
용어
OssieApache Ossie. 구명 OSI(Open Semantic Interchange). 시맨틱 모델 교환 규격
시맨틱 모델물리 테이블 위에 얹은 비즈니스 의미 층. 데이터셋·필드·관계·메트릭으로 구성
datasetOssie의 "엔티티". 대개 물리 테이블 하나에 대응. sourcedb.schema.table 지정
field행 단위 속성. dimension.is_time이 붙으면 시간 차원으로 취급
metric집계 측정치. SUM(orders.amount) 같은 표현식. 여러 데이터셋에 걸칠 수 있음
relationship데이터셋 간 외래키 조인. from(many) → to(one), 복합 컬럼 지원
dialect표현식을 적을 SQL 방언. ANSI_SQL/SNOWFLAKE/DATABRICKS/BIGQUERY/MDX/TABLEAU/MAQL
ai_contextLLM 그라운딩용 필드. instructions·synonyms·examples. 모든 계층에 존재
custom_extensions벤더 확장용 탈출구. vendor_name(자유 문자열) + data
ontology물리 스키마와 무관한 순수 개념 층. EntityType / ValueType
EntityType / ValueType실세계 개념(Employee) vs 의미가 붙은 데이터 타입(SocialSecurityNr)
허브 앤 스포크중립 허브를 둬 변환기 수를 N×(N-1)에서 2×N으로 줄이는 통합 패턴
MetricFlow / MSIdbt Labs의 시맨틱 레이어 엔진과 그 인터페이스 패키지. Ossie dbt 변환기가 직접 의존
sqlglot다중 SQL 방언 파서/트랜스파일러(Python). Ossie 검증기가 표현식 문법 검사에 사용
JSON SchemaJSON/YAML 구조를 검증하는 표준. Ossie는 Draft 2020-12 사용
PEP 723파이썬 단일 파일 스크립트가 주석에 의존성을 선언하는 표준. uv run으로 즉시 실행
uvRust로 만든 초고속 파이썬 패키지/프로젝트 매니저
hatchling현대적 파이썬 빌드 백엔드. setuptools 대체
CobraGo CLI 프레임워크. kubectl·docker 등이 사용
인큐베이팅Apache 재단 정식 프로젝트 이전의 검증 단계. DISCLAIMER 파일 필수
PPMC / IPMCPodling PMC(인큐베이팅 운영위) / Incubator PMC(상위 감독)
lazy consensus명시적 반대(veto)가 없으면 승인으로 간주하는 Apache 의사결정 방식
Apache Polaris오픈소스 Iceberg 카탈로그. Ossie가 변환기를 제공하는 ASF 자매 프로젝트
Cortex AnalystSnowflake의 자연어 질의 기능. Ossie Snowflake 변환기의 출력 대상
TPC-DS의사결정 지원 시스템 표준 벤치마크 스키마. Ossie의 대표 예제 모델
준수성 테스트구현이 규격을 지키는지 검사하는 테스트 스위트. Ossie compliance/는 아직 비어 있음

11참고 링크

더 파고들 곳
분류링크
저장소github.com/apache/ossie
공식 사이트ossie.apache.org
TrendShifttrendshift.io/repositories/44755
스펙 문서core-spec/spec.md · core-spec/osi-schema.json · core-spec/expression_language.md
변환기 가이드converters/README.md ("Writing a Converter" 8단계)
로드맵 · 기여ROADMAP.md · CONTRIBUTING.md · GitHub Discussions
메일링 리스트dev@ossie.apache.org
연관 학습JSON Schema 공식 문서 · sqlglot(github.com/tobymao/sqlglot) · dbt MetricFlow 문서 · Apache Polaris