# Graph Card 제작 안내

# AI 에이전트로 컬렉션 만들기
에이전트가 카드 프로토콜을 읽고 JSON을 작성하게 하면, 파일을 통해 앱에 가져올 수 있습니다. 이 방식에는 MCP 연결이 필요하지 않습니다.

## 지금 사용할 수 있는 흐름
1. 에이전트에게 [카드 프로토콜](/ko/docs/protocol/) 문서와 [JSON Schema](/downloads/collection.schema.json)를 제공합니다.
2. 학습 대상과 범위, 카드에 담을 설명의 깊이를 알려 주세요.
3. 결과를 검토하고 `collection.json` 파일로 받습니다.
4. [파일 가져오기](/ko/docs/import/file/)로 앱에 추가합니다.

## 에이전트에게 전달할 요청 예시
```text
Graph Card 프로토콜 v2에 맞는 collection.json을 만들어 줘.
대상: 통계를 처음 배우는 성인.
범위: 평균, 분산, 표준편차.
설명: 정의만 나열하지 말고 필요한 이유 → 원리 → 숫자 예시 → 주의점 순서로.
관계: 선수 지식 관계를 연결하되, 현재 카드에서 필요한 선수 카드로 향하도록.
이미지 없이, 고유한 카드 ID를 사용하고 예제와 JSON Schema를 참고해 줘.
먼저 내용을 보여주고 내가 검토한 뒤 JSON 파일로 정리해 줘.
```

AI가 만든 설명의 사실성과 관계의 의미는 사람이 검토해야 합니다. JSON Schema가 맞아도 설명이 정확하다는 뜻은 아닙니다. 또한 스키마만으로 관계 대상·역할·순환 검사가 모두 끝나는 것은 아닙니다.

[에이전트용 제작 안내 다운로드](/downloads/agent-guide.md) · [예제 컬렉션](/downloads/collection.json)

## MCP로 초안 만들기
Graph Card MCP에 연결할 수 있는 승인된 클라이언트에서는 로그인한 계정의 초안을 만들 수 있습니다. 에이전트가 작성한 내용을 먼저 확인한 뒤 앱에서 초안을 열고 변경사항을 검토하세요. 기기의 컬렉션으로 반영하려면 앱에서 수락해야 합니다.

파일 방식은 MCP 연결 없이 사용할 수 있습니다.


# 카드 프로토콜
Graph Card 컬렉션은 카드와 관계, 이미지 자산을 담는 JSON 문서입니다. 현재 프로토콜 버전은 **2**입니다.

## 먼저 하나 가져와 보기
[검증된 예제 다운로드](/downloads/collection.json) · [JSON Schema 다운로드](/downloads/collection.schema.json)

예제는 평균 → 분산 → 표준편차를 설명합니다. 관계의 실제 저장 방향은 표준편차 → 분산 → 평균이며, 각 화살표는 **이해에 필요한 선수 지식**을 뜻합니다.

## 컬렉션의 필수 필드
| 필드 | 의미 |
| --- | --- |
| protocolVersion | 숫자 2 |
| collectionId | 컬렉션의 고유 ID. 기기 가져오기에는 영문·숫자·밑줄·하이픈, 최대 128자 |
| title, description | 제목과 설명 |
| publishedAt | 시간대가 포함된 ISO 8601 일시 |
| contentVersion | 비어 있지 않은 콘텐츠 버전 문자열 |
| assets | 이미지 자산 배열. 없으면 빈 배열 |
| cards | 카드 배열 |

`viewMode`는 `flashcard`, `graph`, `both` 중 선택합니다. `tags`는 활용 유형, `topics`는 자유로운 주제, `customRelations`는 컬렉션 전용 관계 정의입니다. 언어별 내용은 `localization`에 넣습니다.

## 카드 구조
```json
{
  "cardId": "variance",
  "role": "class",
  "title": "분산",
  "description": "값들이 평균에서 얼마나 흩어져 있는지 나타냅니다.",
  "descriptionFormat": "plain",
  "images": [],
  "relations": [{ "type": "prerequisite", "targetCardId": "mean" }]
}
```

이 카드는 같은 컬렉션에 cardId가 `mean`인 카드를 필요로 합니다. 단독으로 가져올 수 있는 전체 컬렉션이 아니라 카드 구조 예시입니다.

## 역할
| role | 앱의 표현 | 쓰는 경우 |
| --- | --- | --- |
| none | 역할 없음 | 단어, 질문·답변 등 역할 구분이 필요 없는 카드 |
| class | 분류 | 개념, 범주, 종류 |
| instance | 개체 | 구체적인 대상이나 사례 |
| property | 속성 | 대상이 갖는 특징이나 값의 항목 |

role이 none인 카드는 사용자 정의 관계로 연결할 수 있습니다. 기본 관계의 역할 규칙을 피하려고 엉뚱한 역할로 바꾸지는 마세요.

## 자세히 보기
- [관계·값·방향](/ko/docs/protocol/relations/)
- [본문·이미지·다국어](/ko/docs/protocol/media/)
- [검증과 한도](/ko/docs/protocol/validation/)

이 문서의 JSON Schema와 관계 역할 표는 앱의 공유 도메인 코드에서 사이트를 빌드할 때 생성합니다. JSON Schema를 통과한 뒤에도 참조·역할·순환 같은 의미 구조 검증이 필요합니다.


# 관계와 값
관계는 **출발 카드의 relations**에 저장합니다. targetCardId는 같은 컬렉션 안의 카드를 가리켜야 합니다.

```json
{
  "type": "has_property",
  "targetCardId": "mass",
  "value": 12.5,
  "unit": "kg"
}
```

위 예시는 출발 카드가 `class` 또는 `instance`, 대상 `mass` 카드가 `property`일 때의 값 관계입니다. unit은 value가 있을 때만 사용할 수 있습니다.

## 기본 관계와 역할
| type | 의미 | 출발 → 도착 |
| --- | --- | --- |
| `subclass_of` | 하위 분류 | 분류 → 분류 |
| `instance_of` | 분류의 개체 | 개체 → 분류 |
| `part_of` | 부분 | 분류 → 분류<br>개체 → 개체 |
| `has_property` | 특징 | 분류 → 속성<br>개체 → 속성 |
| `tier` | 티어 | 분류 → 속성<br>개체 → 속성 |
| `equivalent_to` | 동등 | 분류 → 분류<br>개체 → 개체<br>속성 → 속성 |
| `disjoint_with` | 배타 | 분류 → 분류 |
| `prerequisite` | 선수 지식 | 분류 → 분류·개체·속성<br>개체 → 분류·개체·속성<br>속성 → 분류·개체·속성 |

`subclass_of`는 하위에서 상위로, `part_of`는 부분에서 전체로 저장합니다. `prerequisite`는 **현재 카드 → 이해에 필요한 카드**입니다. ‘A를 배우고 B로 진행한다’는 학습 순서와 혼동하지 마세요.

## 컬렉션 전용 관계
동의어·유의어·반의어처럼 기본 관계와 의미가 다른 연결은 직접 정의합니다.

```json
{
  "customRelations": [
    {
      "id": "custom:synonym",
      "label": "동의어",
      "localizedLabels": { "en-US": "Synonym", "ja": "同義語", "zh-TW": "同義詞" }
    }
  ]
}
```

카드에서는 `{"type":"custom:synonym","targetCardId":"다른-카드-ID"}`로 사용합니다. 정의한 관계는 역할 없음 카드를 포함해 모든 역할끼리 연결할 수 있습니다. 같은 관계 이름도 다른 컬렉션에 자동으로 공유되지 않습니다.

## 의미를 정확하게 유지하기
`equivalent_to`는 단순히 비슷하다는 뜻이 아니고, `disjoint_with`는 반의어의 일반 표현이 아닙니다. 의미가 확인된 직접 관계만 저장하세요. 자동 추론 결과를 별도의 사실처럼 생성·저장하는 기능은 현재 프로토콜에 없습니다.

반대 방향을 자동으로 중복 저장할 필요는 없습니다. 관계지도의 표시 방향과 필터는 앱의 탐색 규칙이며 저장된 관계의 방향과 구분하세요.


# 검증과 한도
JSON 문법이 맞는 것과 학습에 적절한 컬렉션인 것은 다릅니다. 파일 형식, 참조 구조, 내용의 의미를 차례로 확인하세요.

## 확인 순서
1. **JSON 문법:** 쉼표·따옴표·괄호가 맞는지 확인합니다.
2. **스키마:** 필수 필드, role, 관계 type, 번역 키를 확인합니다.
3. **구조:** ID 중복, 없는 관계 대상, 역할 조합, 순환을 확인합니다.
4. **내용:** 사실·예제·관계의 의미와 번역이 정확한지 검토합니다.

[앱 코드에서 생성한 JSON Schema](/downloads/collection.schema.json)

## 구조 규칙
카드 ID는 컬렉션 안에서 고유해야 합니다. 관계 대상은 같은 컬렉션 안에 있어야 하며, 자기 자신을 대상으로 하거나 같은 type·target 조합을 중복할 수 없습니다. 사용자 정의 관계는 사용 전에 컬렉션에 정의합니다.

`subclass_of`, `part_of`, `prerequisite`의 순환은 금지됩니다. 동등 관계의 연결과 동일하게 취급하지 마세요. 이미지 ID·경로·해시는 실제 자산과 일치해야 합니다.

## 경로별 한도를 구분하세요
| 경로 | 확인할 한도 |
| --- | --- |
| 기기 파일 가져오기 | JSON 파일 최대 64 MiB |
| MCP·계정 초안 서버 | HTTP JSON 요청 2 MiB, 서명 봉투를 포함한 저장 객체 2 MiB |
| MCP 이미지 업로드 | 이미지 한 장 최대 5 MiB |
| 서버 초안의 텍스트 | 제목 200자, 설명 20,000자 |
| 서버 초안의 카드 | 카드당 이미지 최대 5개, 관계 최대 256개 |

컬렉션의 카드 장수 자체를 1,000장 등으로 제한하지 않습니다. 다만 전송·저장 크기 한도는 별도로 적용됩니다. 기기 파일 가져오기와 MCP 서버 한도를 하나의 공통 제한으로 안내하지 않습니다.

## 자주 만나는 문제
- **같은 컬렉션이 이미 있음:** 다른 내용으로 자동 덮어쓰지 않습니다. 새 컬렉션이면 새 ID를 사용하세요.
- **관계 대상 없음:** title이 아니라 정확한 cardId를 연결했는지 확인합니다.
- **역할이 맞지 않음:** [역할 표](/ko/docs/protocol/relations/)를 확인하거나 의미에 맞는 사용자 정의 관계를 정의합니다.
- **이미지를 찾지 못함:** 경로만 든 로컬 JSON 대신 이미지 포함 내보내기 파일을 사용하세요.
- **번역만 있고 기본 내용이 없음:** 기본 title과 description은 유지하고 언어별 내용을 추가하세요.
