serialize-data-formats
Acerca de
Esta habilidad ayuda a los desarrolladores a serializar y deserializar datos en múltiples formatos como JSON, XML, YAML, Protobuf, MessagePack y Arrow/Parquet. Proporciona orientación para seleccionar el formato adecuado, implementar patrones de codificación/decodificación y comprender las compensaciones de rendimiento y la interoperabilidad. Úsela para elegir formatos de transmisión para APIs, persistir datos, intercambiar entre lenguajes u optimizar para tamaño y velocidad.
Instalación rápida
Claude Code
Recomendadonpx 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-formatsCopia y pega este comando en Claude Code para instalar esta habilidad
Documentación
Serialize Data Formats
Select+impl right serialization format → correct encode/decode + perf awareness.
Use When
- Wire format for API
- Persist structured data → disk|object storage
- Exchange between langs
- Optimize size|speed
- Migrate formats
In
- Required: Data structure (schema|example)
- Required: Use case (API|storage|stream|analytics)
- Optional: Perf reqs (size|speed|schema enforce)
- Optional: Target lang|runtime constraints
- Optional: Human readability
Do
Step 1: Select Format
| Format | Human Readable | Schema | Size | Speed | Best For |
|---|---|---|---|---|---|
| JSON | Yes | Optional (JSON Schema) | Medium | Medium | REST APIs, config, broad interop |
| XML | Yes | XSD, DTD | Large | Slow | Enterprise/legacy, SOAP, documents |
| YAML | Yes | Optional | Medium | Slow | Config files, CI/CD, Kubernetes |
| Protocol Buffers | No | Required (.proto) | Small | Fast | gRPC, microservices, mobile |
| MessagePack | No | None | Small | Fast | Real-time, embedded, Redis |
| Arrow/Parquet | No | Built-in | Very Small | Very Fast | Analytics, columnar queries, data lakes |
Decision tree:
- Human edit? → YAML (config) | JSON (data)
- Strict schema + fast RPC? → Protobuf
- Smallest wire? → MessagePack | Protobuf
- Columnar analytics? → Parquet
- In-memory interchange? → Arrow
- Legacy enterprise? → XML
→ Format selected w/ documented rationale.
If err: reqs conflict (human + fast) → prioritize primary use case + note tradeoff.
Step 2: JSON Serialize
import json
from datetime import datetime, date
from dataclasses import dataclass, asdict
@dataclass
class Measurement:
sensor_id: str
value: float
unit: str
timestamp: datetime
# Custom encoder for non-standard types
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)
# Serialize
measurement = Measurement("sensor-01", 23.5, "celsius", datetime.now())
json_str = json.dumps(asdict(measurement), cls=CustomEncoder, indent=2)
# Deserialize
data = json.loads(json_str)
# R: JSON with jsonlite
library(jsonlite)
# Serialize
df <- data.frame(sensor_id = "sensor-01", value = 23.5, unit = "celsius")
json_str <- jsonlite::toJSON(df, auto_unbox = TRUE, pretty = TRUE)
# Deserialize
df_back <- jsonlite::fromJSON(json_str)
→ Round-trip preserves all types accurately.
If err: type lost (dates → strings) → add explicit conversion in deserialize.
Step 3: Protobuf
.proto:
syntax = "proto3";
package sensors;
message Measurement {
string sensor_id = 1;
double value = 2;
string unit = 3;
int64 timestamp_ms = 4; // Unix milliseconds
}
message MeasurementBatch {
repeated Measurement measurements = 1;
}
Gen+use:
# Generate Python code
protoc --python_out=. sensors.proto
# Generate Go code
protoc --go_out=. sensors.proto
from sensors_pb2 import Measurement, MeasurementBatch
import time
# Serialize
m = Measurement(
sensor_id="sensor-01",
value=23.5,
unit="celsius",
timestamp_ms=int(time.time() * 1000)
)
binary = m.SerializeToString() # Compact binary
# Deserialize
m2 = Measurement()
m2.ParseFromString(binary)
→ Binary 3-10x smaller than JSON.
If err: protoc unavail → lang-native lib (betterproto Py).
Step 4: MessagePack
import msgpack
from datetime import datetime
# Custom packing for 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()}
# Serialize (smaller than JSON, faster than JSON)
packed = msgpack.packb(data, default=encode_datetime)
# Deserialize
unpacked = msgpack.unpackb(packed, object_hook=decode_datetime, raw=False)
→ Output 15-30% smaller than JSON for typical payloads.
If err: lang lacks MessagePack → fallback JSON+gzip.
Step 5: Parquet (Columnar)
import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd
# Create data
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")
})
# Write Parquet (columnar, compressed)
table = pa.Table.from_pandas(df)
pq.write_table(table, "measurements.parquet", compression="snappy")
# Read Parquet (can read specific columns without loading all data)
table_back = pq.read_table("measurements.parquet", columns=["sensor_id", "value"])
df_subset = table_back.to_pandas()
# R: Parquet with arrow
library(arrow)
# Write
df <- data.frame(sensor_id = rep("s-01", 1000), value = rnorm(1000))
arrow::write_parquet(df, "measurements.parquet")
# Read (with column selection — only reads selected columns from disk)
df_back <- arrow::read_parquet("measurements.parquet", col_select = c("value"))
→ Parquet 5-20x smaller than CSV for tabular.
If err: Arrow unavail → fastparquet (Py)|CSV+gzip fallback.
Step 6: Compare Perf
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")
→ Benchmarks guide format for prod.
If err: insufficient perf any format → consider compression (zstd, snappy) as orthogonal optimization.
Check
- Format matches use case (rationale documented)
- Round-trip preserves all types
- Edge cases: empty, null, Unicode, large nums
- Perf benchmarked for representative sizes
- Err handling for malformed (graceful fail)
- Schema documented (JSON Schema|.proto|equiv)
Traps
- Float precision: JSON = IEEE 754 doubles. String encoding for financial.
- Date/time: No native JSON datetime. Always document format (ISO 8601) + timezone.
- Schema evolution: Add|remove fields can break consumers. Protobuf good; JSON needs careful versioning.
- Binary in JSON: Base64 inflates ~33%. Binary format for binary-heavy.
- YAML security: Parsers may exec arbitrary code via
!!python/objecttags. Always safe loaders.
→
design-serialization-schema— schema design, versioning, evolutionimplement-pharma-serialisation— pharma serialisation (diff domain, same naming)create-quarto-report— data output for reports
Repositorio GitHub
Habilidades relacionadas
qmd
Desarrolloqmd es una herramienta CLI de búsqueda e indexación local que permite a los desarrolladores indexar y buscar en archivos locales mediante búsqueda híbrida que combina BM25, embeddings vectoriales y reranking. Es compatible tanto con uso desde la línea de comandos como con modo MCP (Model Context Protocol) para integración con Claude. La herramienta utiliza Ollama para los embeddings y almacena los índices localmente, lo que la hace ideal para buscar documentación o bases de código directamente desde la terminal.
subagent-driven-development
DesarrolloEsta habilidad ejecuta planes de implementación asignando un nuevo subagente para cada tarea independiente, con revisión de código entre tareas. Permite una iteración rápida mientras mantiene controles de calidad a través de este proceso de revisión. Úsala cuando trabajes en tareas mayormente independientes dentro de la misma sesión para garantizar un progreso continuo con verificaciones de calidad integradas.
mcporter
DesarrolloLa habilidad mcporter permite a los desarrolladores gestionar y llamar servidores del Protocolo de Contexto de Modelo (MCP) directamente desde Claude. Proporciona comandos para listar servidores disponibles, llamar a sus herramientas con argumentos, y manejar la autenticación y el ciclo de vida del daemon. Utiliza esta habilidad para integrar y probar la funcionalidad de servidores MCP en tu flujo de trabajo de desarrollo.
adk-deployment-specialist
DesarrolloEsta habilidad despliega y orquesta agentes Vertex AI ADK utilizando el protocolo A2A, gestionando el descubrimiento de AgentCard, el envío de tareas y soportando herramientas como el Sandbox de Ejecución de Código y el Banco de Memoria. Permite construir sistemas multiagente con patrones de orquestación secuencial, paralela o en bucle en Python, Java o Go. Úsela cuando se le solicite desplegar agentes ADK u orquestar flujos de trabajo de agentes en Google Cloud.
