serialize-data-formats
정보
이 스킬은 개발자가 JSON, XML, YAML, Protobuf, MessagePack과 같은 일반적인 형식 간 데이터 직렬화 및 역직렬화를 수행하는 데 도움을 줍니다. API 통신, 데이터 지속성, 시스템 상호 운용성과 같은 사용 사례에 대해 형식 선택, 인코딩/디코딩 패턴, 성능 상충 관계를 다룹니다. 최적의 전송 형식 선택, 전송 크기/파싱 속도 최적화 또는 직렬화 형식 간 마이그레이션에 활용하세요.
빠른 설치
Claude Code
추천npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/serialize-data-formatsClaude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요
문서
name: serialize-data-formats description: > JSON、XML、YAML、Protocol Buffers、MessagePack、Apache Arrow/Parquetを含む 一般的なフォーマット間でデータをシリアライズ・デシリアライズする。 フォーマット選択基準、エンコード/デコードパターン、パフォーマンスの トレードオフ、相互運用性の考慮事項をカバー。API通信のワイヤーフォーマット 選択、構造化データのディスク永続化、異なる言語で書かれたシステム間の データ交換、転送サイズや解析速度の最適化、シリアライゼーション フォーマット間の移行に使用する。 license: MIT allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: data-serialization complexity: intermediate language: multi tags: json, xml, yaml, protobuf, messagepack, parquet, arrow, serialization locale: ja source_locale: en source_commit: 6f65f316 translator: claude-sonnet-4-6 translation_date: 2026-03-16
データフォーマットのシリアライズ
ユースケースに適したデータシリアライゼーションフォーマットを選択し、正しいエンコード/デコードとパフォーマンス意識を持って実装する。
使用タイミング
- API通信のワイヤーフォーマットを選択する場合
- 構造化データをディスクやオブジェクトストレージに永続化する場合
- 異なる言語で書かれたシステム間でデータを交換する場合
- データ転送サイズや解析速度を最適化する場合
- シリアライゼーションフォーマット間を移行する場合
入力
- 必須: シリアライズするデータ構造(スキーマまたは例)
- 必須: ユースケース(API、ストレージ、ストリーミング、分析)
- 任意: パフォーマンス要件(サイズ、速度、スキーマ強制)
- 任意: ターゲット言語/ランタイムの制約
- 任意: 人間可読性の要件
手順
ステップ1: 適切なフォーマットの選択
| フォーマット | 人間可読 | スキーマ | サイズ | 速度 | 最適な用途 |
|---|---|---|---|---|---|
| JSON | はい | 任意(JSON Schema) | 中 | 中 | REST API、設定、広範な相互運用 |
| XML | はい | XSD、DTD | 大 | 遅い | エンタープライズ/レガシー、SOAP、文書 |
| YAML | はい | 任意 | 中 | 遅い | 設定ファイル、CI/CD、Kubernetes |
| Protocol Buffers | いいえ | 必須(.proto) | 小 | 速い | gRPC、マイクロサービス、モバイル |
| MessagePack | いいえ | なし | 小 | 速い | リアルタイム、組み込み、Redis |
| Arrow/Parquet | いいえ | 内蔵 | 非常に小 | 非常に速い | 分析、カラムナクエリ、データレイク |
決定ツリー:
- 人間による編集が必要? -> YAML(設定)またはJSON(データ)
- 厳格なスキーマ + 高速RPC? -> Protocol Buffers
- 最小ワイヤーサイズ? -> MessagePackまたはProtobuf
- カラムナ分析? -> Apache Parquet
- インメモリ交換? -> Apache Arrow
- レガシーエンタープライズ統合? -> XML
期待結果: ユースケース要件に合致する根拠を文書化してフォーマットが選択される。 失敗時: 要件が矛盾する場合(例: 人間可読かつ高速)、主要なユースケースを優先し、トレードオフを記録する。
ステップ2: JSONシリアライゼーションの実装
import json
from datetime import datetime, date
from dataclasses import dataclass, asdict
@dataclass
class Measurement:
sensor_id: str
value: float
unit: str
timestamp: datetime
# 非標準型のカスタムエンコーダ
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, date):
return obj.isoformat()
if isinstance(obj, bytes):
import base64
return base64.b64encode(obj).decode('ascii')
return super().default(obj)
# シリアライズ
measurement = Measurement("sensor-01", 23.5, "celsius", datetime.now())
json_str = json.dumps(asdict(measurement), cls=CustomEncoder, indent=2)
# デシリアライズ
data = json.loads(json_str)
# R: jsonliteによるJSON
library(jsonlite)
# シリアライズ
df <- data.frame(sensor_id = "sensor-01", value = 23.5, unit = "celsius")
json_str <- jsonlite::toJSON(df, auto_unbox = TRUE, pretty = TRUE)
# デシリアライズ
df_back <- jsonlite::fromJSON(json_str)
期待結果: ラウンドトリップシリアライゼーションがすべてのデータ型を正確に保持する。 失敗時: 型が失われる場合(例: 日付が文字列になる)、デシリアライゼーションステップで明示的な型変換を追加する。
ステップ3: Protocol Buffersの実装
スキーマ(.protoファイル)を定義する:
syntax = "proto3";
package sensors;
message Measurement {
string sensor_id = 1;
double value = 2;
string unit = 3;
int64 timestamp_ms = 4; // Unixミリ秒
}
message MeasurementBatch {
repeated Measurement measurements = 1;
}
生成して使用する:
# Pythonコードを生成
protoc --python_out=. sensors.proto
# Goコードを生成
protoc --go_out=. sensors.proto
from sensors_pb2 import Measurement, MeasurementBatch
import time
# シリアライズ
m = Measurement(
sensor_id="sensor-01",
value=23.5,
unit="celsius",
timestamp_ms=int(time.time() * 1000)
)
binary = m.SerializeToString() # コンパクトなバイナリ
# デシリアライズ
m2 = Measurement()
m2.ParseFromString(binary)
期待結果: バイナリ出力が同等のJSONより3-10倍小さい。
失敗時: protocが利用できない場合、言語ネイティブのprotobufライブラリ(例: Pythonのbetterproto)を使用する。
ステップ4: MessagePackの実装
import msgpack
from datetime import datetime
# datetimeのカスタムパッキング
def encode_datetime(obj):
if isinstance(obj, datetime):
return {"__datetime__": True, "s": obj.isoformat()}
return obj
def decode_datetime(obj):
if "__datetime__" in obj:
return datetime.fromisoformat(obj["s"])
return obj
data = {"sensor_id": "sensor-01", "value": 23.5, "ts": datetime.now()}
# シリアライズ(JSONより小さく、JSONより速い)
packed = msgpack.packb(data, default=encode_datetime)
# デシリアライズ
unpacked = msgpack.unpackb(packed, object_hook=decode_datetime, raw=False)
期待結果: MessagePack出力が一般的なペイロードでJSONより15-30%小さい。 失敗時: 言語がMessagePackをサポートしない場合、圧縮付きJSON(gzip)にフォールバックする。
ステップ5: Apache Parquet(カラムナ)の実装
import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd
# データ作成
df = pd.DataFrame({
"sensor_id": ["s-01", "s-02", "s-01", "s-03"] * 1000,
"value": [23.5, 18.2, 24.1, 19.8] * 1000,
"unit": ["celsius"] * 4000,
"timestamp": pd.date_range("2025-01-01", periods=4000, freq="min")
})
# Parquet書き込み(カラムナ、圧縮)
table = pa.Table.from_pandas(df)
pq.write_table(table, "measurements.parquet", compression="snappy")
# Parquet読み込み(全データをロードせずに特定カラムを読み取れる)
table_back = pq.read_table("measurements.parquet", columns=["sensor_id", "value"])
df_subset = table_back.to_pandas()
# R: arrowによるParquet
library(arrow)
# 書き込み
df <- data.frame(sensor_id = rep("s-01", 1000), value = rnorm(1000))
arrow::write_parquet(df, "measurements.parquet")
# 読み込み(カラム選択付き — 選択されたカラムのみディスクから読み込む)
df_back <- arrow::read_parquet("measurements.parquet", col_select = c("value"))
期待結果: Parquetファイルが一般的な表形式データでCSVより5-20倍小さい。
失敗時: Arrowが利用できない場合、fastparquet(Python)またはgzip付きCSVをフォールバックとして使用する。
ステップ6: パフォーマンスの比較
特定のデータとユースケースでベンチマークを実行する:
import json, msgpack, time
import pyarrow as pa, pyarrow.parquet as pq
data = [{"id": i, "value": i * 0.1, "label": f"item-{i}"} for i in range(10000)]
# JSON
start = time.perf_counter()
json_bytes = json.dumps(data).encode()
json_time = time.perf_counter() - start
# MessagePack
start = time.perf_counter()
msgpack_bytes = msgpack.packb(data)
msgpack_time = time.perf_counter() - start
print(f"JSON: {len(json_bytes):>8} bytes, {json_time*1000:.1f} ms")
print(f"MsgPack: {len(msgpack_bytes):>8} bytes, {msgpack_time*1000:.1f} ms")
期待結果: ベンチマーク結果が本番使用のフォーマット選択を導く。 失敗時: いずれのフォーマットでもパフォーマンスが不十分な場合、圧縮(zstd、snappy)を直交する最適化として検討する。
バリデーション
- 選択したフォーマットがユースケース要件に合致する(根拠が文書化されている)
- ラウンドトリップシリアライゼーションがすべてのデータ型を保持する
- エッジケースが処理される: 空コレクション、null/None値、Unicode、大きな数値
- 代表的なペイロードサイズでパフォーマンスがベンチマークされている
- 不正入力のエラーハンドリング(クラッシュではなく優雅な失敗)
- スキーマが文書化されている(JSON Schema、.proto、または同等物)
よくある落とし穴
- 浮動小数点精度: JSONはすべての数値をIEEE 754倍精度で表現する。金融/10進数精度には文字列エンコーディングを使用する。
- 日付/時刻処理: JSONにはネイティブのdatetime型がない。フォーマット(ISO 8601)とタイムゾーン処理を常に文書化する。
- スキーマ進化: フィールドの追加や削除はコンシューマーを壊す可能性がある。Protobufはこれをうまく処理する; JSONには慎重なバージョニングが必要。
- JSONでのバイナリデータ: Base64エンコーディングはバイナリデータを約33%膨張させる。バイナリ重視のペイロードにはバイナリフォーマットを使用する。
- YAMLのセキュリティ: YAMLパーサーは
!!python/objectタグで任意のコードを実行する場合がある。常にセーフローダーを使用する。
関連スキル
design-serialization-schema— スキーマ設計、バージョニング、進化戦略implement-pharma-serialisation— 医薬品シリアライゼーション(異なるドメイン、同じ名称)create-quarto-report— レポート用データ出力フォーマッティング
GitHub 저장소
연관 스킬
qmd
개발qmd는 BM25, 벡터 임베딩, 재순위화를 결합한 하이브리드 검색을 통해 로컬 파일을 색인화하고 검색할 수 있는 로컬 검색 및 색인화 CLI 도구입니다. 명령줄 사용과 Claude 통합을 위한 MCP(Model Context Protocol) 모드를 모두 지원합니다. 이 도구는 임베딩에 Ollama를 사용하고 색인을 로컬에 저장하여 터미널에서 직접 문서나 코드베이스를 검색하는 데 이상적입니다.
subagent-driven-development
개발이 스킬은 각 독립적인 작업마다 새로운 하위 에이전트를 배치하고 작업 사이에 코드 리뷰를 진행하여 구현 계획을 실행합니다. 이 리뷰 프로세스를 통해 품질 게이트를 유지하면서 빠른 반복 작업을 가능하게 합니다. 동일한 세션 내에서 대부분 독립적인 작업을 진행할 때 내장된 품질 검증과 함께 지속적인 진행을 보장하기 위해 사용하세요.
mcporter
개발mcporter 스킬은 개발자가 Claude에서 직접 Model Context Protocol(MCP) 서버를 관리하고 호출할 수 있도록 합니다. 이 스킬은 사용 가능한 서버를 나열하고, 인수를 사용해 해당 서버의 도구를 호출하며, 인증 및 데몬 생명주기를 처리하는 명령어를 제공합니다. 개발 워크플로우에서 MCP 서버 기능을 통합하고 테스트할 때 이 스킬을 사용하세요.
adk-deployment-specialist
개발이 스킬은 A2A 프로토콜을 사용하여 Vertex AI ADK 에이전트를 배포하고 오케스트레이션하며, AgentCard 검색, 작업 제출, 코드 실행 샌드박스 및 메모리 뱅크와 같은 지원 도구를 관리합니다. Python, Java 또는 Go 언어로 순차, 병렬 또는 루프 오케스트레이션 패턴을 갖춘 다중 에이전트 시스템 구축을 가능하게 합니다. Google Cloud에서 ADK 에이전트 배포 또는 에이전트 워크플로우 오케스트레이션을 요청받았을 때 사용하세요.
