Open Envelope: AI 에이전트 팀 정의를 위한 오픈 스키마
요약
Open Envelope는 AI 에이전트 팀의 정의를 위한 오픈 스키마 표준(v1)을 제시합니다. 이 스키마는 에이전트, 역할, 계층 구조 등 다중 에이전트 시스템의 구성을 공식적이고 버전 관리되는 방식으로 설명할 수 있게 합니다. 이는 현재 코드 중심적인 시장의 한계를 극복하고 선언형 인프라 표준으로 자리매김하는 것을 목표로 합니다.
핵심 포인트
- 에이전트 팀 정의를 위한 오픈 스키마 표준(v1)을 제공합니다.
- 코드 대신 선언적 방식으로 에이전트 시스템을 정의할 수 있게 합니다.
- OpenAPI처럼, 플랫폼 독립적인 표준으로 생태계를 주도하고자 합니다.
- 단순 코드 생성보다는 협업 및 개발 도구 지원에 초점을 맞춰야 합니다.
https://schema.openenvelope.org/team/v1.json
SchemaStore에 등록되어 있어 VS Code, JetBrains 및 모든 SchemaStore 인식 편집기에서 별도의 설정 없이 *.envelope.json 파일을 자동으로 검증합니다.
구성 가능한 AI 에이전트 팀 정의를 위한 오픈 표준 — v1
Envelope 팀 정의는 에이전트, 역할, 계층 구조, 에스컬레이션 경로, 필수 비밀 정보(secrets), 어댑터 등을 설명하는 구조로, 공식적이고 버전 관리되는 오픈 소스 사양으로 게시됩니다. 누구나 이를 읽고, 검증하며, 주변 도구를 구축할 수 있습니다. 마켓플레이스, 결제, 배포 인프라 및 매칭 기능은 여전히 독점적인 영역입니다.
이는 Elastic 모델을 반영합니다: 엔진과 사양(Elasticsearch)은 오픈 소스로 공개하고, 관리형 배포판(Elastic Cloud)만 독점적으로 유지하는 방식입니다. 이 오픈 스키마가 채택률과 생태계를 주도하며, Envelope는 이를 게시하고 배포하는 표준적인 장소입니다.
현재 AI 에이전트 시장은 코드 중심적입니다. LangGraph, CrewAI, Vertex AI ADK 등 지배적인 플랫폼들은 개발자들에게 자신들의 에이전트를 정의하기 위해 Python이나 JavaScript를 작성하도록 요구합니다. 이는 개발자들이 초기 채택자이며 코드가 최대의 유연성을 제공하기 때문에 자연스러운 상태처럼 느껴집니다.
하지만 인프라는 항상 명령형(imperative)에서 선언형(declarative)으로 이동해 왔습니다. 예전에는 SSH로 접속하여 명령을 실행하며 서버를 프로비저닝했습니다. 그러다 Terraform이 등장했습니다 — 원하는 것을 설명하면 런타임이 방법을 알아냅니다. 컨테이너를 배포할 때는 셸 스크립트를 작성하는 것으로 시작했습니다. 그리고 Kubernetes 매니페스트가 나왔습니다. 명령형 접근 방식은 표현력이 뛰어나기 때문에 초기에 승리합니다. 하지만 선언형 접근 방식은 이식성이 높고, 감사 가능하며(auditable), 버전 관리가 가능하고, 원래 코드를 작성한 사람뿐만 아니라 누구나 도구를 만들 수 있기 때문에 대규모에서 승리합니다.
다중 에이전트 팀도 같은 궤적에 있습니다. 현재는 애플리케이션 코드입니다. 시간이 지남에 따라 인프라가 됩니다 — 반복 가능하고, 배포 가능하며, 관리되고(governed), 버전 관리가 되는 것입니다. 이러한 변화가 발생할 때, 선언형 표준을 소유한 플랫폼이 생태계를 소유하게 될 것입니다.
Envelope 스키마가 바로 핵심입니다. 빌더들을 특정 시스템에 가두는 독점적인 형식이 아닙니다. 어떤 런타임 환경에서도 구현할 수 있는 개방형 표준인 것입니다. OpenAPI가 어떤 프레임워크가 API를 제공하든 상관없이 API가 자신을 설명하는 방식으로 자리 잡았듯이, Envelope 팀 정의 스키마는 어떤 플랫폼에서 다중 에이전트 팀이 실행되든 상관없이 팀들이 자신을 설명하는 방식이 됩니다.
Envelope가 코드 생성(Code Generation)을 핵심 제품으로 삼지 말아야 하는 이유:
코드 생성 — 즉, Envelope 팀 정의를 받아 CrewAI나 LangGraph용 Python 코드를 출력하는 것 — 은 잘못된 영역에서 싸우는 것입니다. CrewAI를 원하는 Python 개발자들은 CrewAI를 사용할 것입니다. 여기에 코드 생성 계층을 추가한다고 해서 그 싸움에서 이길 만큼의 가치를 더하지 못하며, 오히려 Envelope가 다른 프레임워크들을 구현하는 표준이라기보다는 그 위에 덧씌워진(wrapper) 형태로 보이게 만듭니다. 구축되는 모든 코드 생성 통합은 임시방편일 뿐이며, 목표 플랫폼이 해당 스키마를 네이티브하게 채택하는 순간 쓸모없어집니다.
올바른 과도기적 움직임:
Python 개발자에게 넘겨줘야 하는 빌더들을 위해 코드를 생성하고, 복사 버튼이나 원클릭 GitHub 내보내기 기능을 제공하는 것입니다. 이것은 개발 도구라기보다는 협업을 위한 전달(handoff)입니다. 기술적 배경이 없는 Envelope 빌더들이 자신들의 팀 정의를 Python 개발자의 손에 넘겨주는 것을 돕는 역할을 합니다. 이는 Python IDE나 프레임워크 네이티브 도구와 경쟁하려는 경로가 아님을 명확히 합니다.
장기적인 결론:
다중 에이전트 팀이 배포되는 곳에서 존재하고 싶어 하는 코드 우선(Code-first) 플랫폼들은 Envelope 스키마를 네이티브하게 구현할 것입니다. 왜냐하면 그곳이야말로 팀들이 게시되고, 빌더들이 평판을 쌓으며, 배포자들이 찾아가는 장소이기 때문입니다. Envelope가 굳이 Python을 구사할 필요는 없습니다. 필요한 것은 이 스키마가 충분히 매력적이어서 Python 프레임워크들이 Envelope를 사용하도록 만드는 것입니다.
이는 형식을 독점적인 것이 아닌 표준으로 만듭니다. 다른 도구, 런타임 환경, 그리고 프레임워크들이 Envelope 팀 정의를 읽고 쓸 수 있게 되면, 빌더들은 벽으로 둘러싸인 정원(walled garden) 안에 있는 것이 아니라 생태계 안에서 작업하게 됩니다. 채택 장벽(Adoption friction)이 현저히 낮아집니다.
비즈니스를 노출하지 않으면서 커뮤니티의 레버리지를 창출합니다. 커뮤니티가 검증기(validators), 린터(linters), IDE 확장 기능, 시각적 편집기, 변환기 등을 구축하고, Envelope는 이 모든 것로부터 이점을 얻지만 그 어떤 것도 직접 구축할 필요가 없습니다.
이는 장기적인 해자(moat)입니다. 만약 Envelope 스키마가 멀티 에이전트 팀을 정의하는 표준 방식이 된다면 — OpenAPI가 API를 설명하는 표준이 된 것처럼 — Envelope는 해당 스키마의 표준 마켓플레이스로서 대체하기 매우 어렵습니다. 경쟁사들은 이 표준을 채택하거나 (이는 Envelope에 이익이 됩니다) 아니면 처음부터 시작해야 합니다 (이는 그들에게 비용이 많이 듭니다).
기업 도입을 가능하게 합니다. 기업들은 팀 정의를 자체 Git 저장소에 저장하고, 자체 CI/CD 파이프라인에서 검증하며, 준비가 되면 Envelope에 게시할 수 있습니다. 이러한 수준의 통제는 종종 기업 조달의 필수 전제 조건입니다.
빌더(builder)는 팀 정의 파일 상단에 스키마를 참조합니다. 이 경우 Envelope에 접속하지 않고도 IDE가 즉시 검증을 수행하며 — 필요한 필드를 표시하고, 에이전트 속성을 자동 완성하며, 유효하지 않은 어댑터 이름에 밑줄을 긋습니다.
{
"$schema": "https://schema.openenvelope.org/team/v1.json",
"name": "Support Tier",
...
npm install @openenvelope/schema
import { validate } from '@openenvelope/schema';
import { readFileSync } from 'fs';
const team = JSON.parse(readFileSync('team.json', 'utf-8'));
...
모든 풀 리퀘스트는 레지스트리에 도달하기 전에 팀 정의를 검증합니다. 유효하지 않은 정의는 절대 게시되지 않습니다.
# .github/workflows/validate.yml
- name: Validate team definition
run: |
...
팀 정의는 지원하는 코드와 함께 Git에 존재합니다. 스키마 버전 관리는 모든 정의가 어떤 사양(spec) 버전을 기반으로 구축되었는지 추적할 수 있게 합니다.
모든 .envelope.json 파일의 루트 객체입니다.
{
"$schema": "https://schema.openenvelope.org/team/v1.json",
"name": "Support Tier",
...
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
$schema | string | 예 | 항상 https://schema.openenvelope.org/team/v1.json이어야 합니다. |
name | string | 예 | 사람이 읽을 수 있는 표시 이름입니다. |
slug | string | 예 | 레지스트리 내에서 고유한 URL 안전 식별자입니다. 소문자 알파벳, 숫자, 하이픈만 사용 가능합니다 ([a-z0-9-]+). |
version | string | 예 | Semver 문자열 형식(MAJOR.MINOR.PATCH)을 사용합니다. |
description | string | 예 | 레지스트리에서 표시되는 짧은 설명입니다 (최대 300자). |
category | string | 아니요 | 레지스트리 카테고리 슬러그를 사용합니다 (카테고리 참조 참고). |
visibility | string | 예 | "public" — 레지스트리에 등록됩니다. "team" — 빌더의 조직 멤버에게만 접근 가능하며(공개적으로 검색 불가), "private" — 발행 API 키에만 접근 가능합니다. |
pricing | object | 아니요 | 무료 팀의 경우 생략합니다. 이 필드를 생략하면 해당 팀은 무료이며, pricing.model은 기본값으로 "free"가 설정됩니다. |
pricing.model | string | 예 | "free", "per_run", 또는 "per_k_tokens"를 사용합니다 (가격 모델 참고). "subscription"은 향후 릴리스에서 계획 중입니다. |
pricing.amount | number | 예 | 지정된 통화로 표시되는 가격입니다. |
pricing.currency | string | 아니요 | ISO 4217 코드를 사용합니다. 기본값은 "usd"입니다. |
forkable | boolean | 아니요 | 다른 빌더가 이 팀을 포크할 수 있는지 여부입니다. 공개 팀의 경우 기본값은 true입니다. 팀을 공개로 유지하면서 포크를 방지하려면 false로 설정합니다. |
forkedFrom | object | 아니요 | 이 팀이 다른 곳에서 파생된 경우에만 표시됩니다 (포킹 참고). |
timeout | object | 아니요 | 팀 내 모든 에이전트에 대한 기본 타임아웃 구성입니다. 개별 에이전트의 modelConfig.timeoutMs가 이를 재정의합니다. |
timeout.runMs | number | 아니요 | 전체 실행에 대한 최대 벽시계 시간(ms)입니다. 기본값: 30000. 런타임에서 강제하는 최대치입니다. |
timeout.agentMs | number | 아니요 | 단일 에이전트 호출에 대한 최대 시간(ms)입니다. 기본값: 30000. |
readme | string | 아니요 | 팀의 레지스트리 페이지에 표시되는 장문 Markdown 문서입니다. 하드 제한은 없지만, 가독성을 위해 10,000자 미만으로 유지하는 것이 좋습니다. |
|
icon | string | No | 레지스트리에서 표시되는 사각형 PNG 또는 SVG 아이콘의 URL (최소 256×256px). 공개적으로 접근 가능해야 합니다. |
inputs | object | No | 팀이 수락하는 이름 지정 입력 필드. 키는 필드 이름입니다. 레지스트리에서 허용되지만, v1에서는 스키마 유효성 검사가 적용되지 않습니다 — v2에서 계획되었습니다. |
outputs | object | No | 팀이 반환하는 이름 지정 출력 필드. 키는 필드 이름입니다. 레지스트리에서 허용되지만, v1에서는 출력 스키마 유효성 검사가 적용되지 않습니다 — v2에서 계획되었습니다. |
requiredSecrets | string[] | No | 배포자가 설치 시 제공해야 하는 비밀(Secret) 이름. 값은 스키마에 절대 포함되지 않습니다. |
requiredVariables | string[] | No | 배포자가 설치 시 제공해야 하는 비-비밀 변수 이름 (예: ["COMPANY_NAME", "SUPPORT_EMAIL"]). 사람이 읽기 쉬운 설명은 레지스트리 UI에 있으며, 스키마 파일에는 없습니다. |
tags | string[] | No | 검색을 위한 자유 형식 태그. 현재 레지스트리에서 허용되지만 필터링을 위해 아직 인덱싱되지 않았습니다. 레지스트리 v2에서 계획되었습니다. |
changelog | string | No | 이 버전에서 변경된 내용을 사람이 읽기 쉬운 설명으로 기술합니다. 레지스트리 UI에 표시되며 versions API를 통해 반환됩니다. 모범 사례: 배포자가 diff를 읽지 않고도 무엇이 바뀌었는지 이해할 수 있도록 모든 게시물에 포함하는 것입니다. |
agents | object[] | Yes | 하나 이상의 에이전트 정의 (아래 참조) |
metadata | object | No | 팀 수준의 메타데이터. 레지스트리에서 보존되며 API 응답에 반환됩니다. Envelope는 내보내기 시 metadata.generatedBy를 자동으로 채웁니다. |
metadata.generatedBy | string | No | 출처(Attribution) 문자열. Envelope가 내보낼 때의 표준 값: "Envelope · openenvelope.org" . |
workspace | object[] | No | 이 팀이 선언하는 워크스페이스 문서. 각 항목은 에이전트 실행 간에 상태를 누적시키는 영구적인 문서를 나타냅니다. 각 항목은 설치(install)에 범위가 지정됩니다. 아래의 workspace 블록 참조를 참조하십시오.
The workspace
배열은 에이전트 실행 전반에 걸쳐 상태를 축적하는 영구적인 문서를 선언합니다. 각 항목은 설치에 범위가 지정된 별도의 문서입니다.
{
"workspace": [
{
...
**워크스페이스 문서 필드:**
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| `name` | string | 예 | 설치 내 고유 문서 이름. 소문자 알파벳, 숫자 및 하이픈만 사용 가능 (`[a-z0-9-]+`), 최대 60자. 에이전트 도구 호출 및 조건 트리거에서 문서를 참조하는 데 사용됨. |
| `type` | string | 아니요 | UI 렌더링 및 스키마 부팅을 위한 문서 유형 힌트. 런타임에 검증되지 않음. 예시: `"contact-list"` , `"content-queue"` , `"task-backlog"` . |
| `columns` | object[] | 아니요 | 소유권을 가진 선언된 열 목록. 에이전트는 자신이 소유한 열에만 쓸 수 있으며, 인간 사용자는 모든 열을 편집할 수 있음. |
| `columns[].name` | string | 예 | 열 이름. 행 데이터 객체에서 키로 사용됨. |
| `columns[].owner` | string | 예 | `"agent"` — 에이전트가 이 열에 작성; 인간은 읽고 편집 가능. `"human"` — 인간만 작성; 에이전트는 읽지만 절대 덮어쓰지 않음. `"both"` — 둘 다 작성 가능하며, 충돌 감지 기능 제공. |
| `columns[].type` | string | 아니요 | 값 타입 힌트: `"string"` (기본값), `"number"` , 또는 `"boolean"` . 렌더링 및 내보내기 형식 지정에 사용됨. |
| `columns[].id` | boolean | 아니요 | `true`인 경우, 이 열은 행 주소 지정의 고유 식별자임. 문서당 오직 하나의 열만 `id: true`여야 함. |
| `columns[].pii` | boolean | 아니요 | 해당 열이 개인 식별 정보(Personally Identifiable Information)를 포함함을 표시함. 내보내기 및 API 응답에서 적절한 처리를 가능하게 하며, 삭제 요청 시 하드 삭제 처리를 수행함. |
| `statusValues` | string[] | 아니요 | 상태 유형 열의 유효 값 목록. 런타임에 강제됨 — 선언되지 않은 상태 값을 가진 에이전트 작성은 거부됨. `triggers`가 올바르게 작동하는 데 필수적임. |
| `triggers` | object[] | 아니요 | 문서의 상태 인덱스를 기반으로 평가되는 조건 트리거 목록. 비활성화되지 않은 행에 일치하는 열/상태 조합이 있을 때 발동함. |
| `triggers[].column` | string | 예 | 평가할 선언된 열. |
| `triggers[].status` | string | 예 | 트리거를 발생시키는 상태 값. |
선언된 `statusValue`여야 합니다. |
`triggers[].action` | 문자열 (string) | 필수 아님 (No) | `"run"` (기본값, default) — 전체 팀을 실행합니다. `"notify"` — 실행 없이 알림(notification)만 보냅니다. |
`hypotheses` | 문자열 배열 (string[]) | 필수 아님 (No) | 예측된 결과(predicted outcomes)를 위한 순방향 호환성 필드(Forward-compatibility field). v1.2.0 런타임에서는 무시됩니다. |
**내장 행 필드 (항상 사용 가능하며, 스키마에 선언되지 않음):**
AI 자동 생성 콘텐츠
본 콘텐츠는 HN Design Systems의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기