에이전트 JSON 스키마 템플릿: LLM 출력 표준화로 분석→예측→결정 “끊김” 없이 연결하기

최종 수정: 작성자: Finyul

프롬프트는 잘 짰는데 결과가 들쭉날쭉해서 시스템화가 막힌다면, 문제는 대개 모델이 아니라 출력 규격(에이전트 JSON 스키마)이 없습니다. 이 글은 분석→예측→결정 파이프라인을 JSON 스키마(데이터 계약)로 고정해 연결·검증·로깅·리플레이까지 가능하게 만드는 “복붙용 템플릿”을 제공합니다.

전체 폐루프(분석→예측→결정→실행) 큰 그림이 먼저 필요하면 LLM 멀티에이전트 투자 시스템(MAS) 완전 가이드를 참고하세요.

에이전트 출력 표준화 전후 비교: 좌측 스키마 없음(출력 흔들림·파싱 실패), 우측 스키마 있음(계약→검증→로그·리플레이 가능)
스키마 없음(출력 흔들림) vs 스키마 있음(검증·로깅 가능) 비교.

출력이 흔들리는 진짜 원인: “좋은 프롬프트”가 아니라 “데이터 계약 부재”

현장에서 가장 많이 터지는 증상은 이렇습니다.

  • 같은 입력인데 필드명이 바뀜(confidence → score → prob)
  • 확률을 준다더니 문장으로만 말함
  • “결정”이 주문까지 말해버림(분석/예측/결정 경계 붕괴)
  • 로그를 남기려는데 출력 포맷이 매번 달라서 파싱 실패

이걸 프롬프트로만 잡으려 하면, 결국 “더 길고 더 빡센 프롬프트”로 가다가 유지보수가 망가집니다. 해결책은 간단합니다.

  • 스키마를 먼저 정하고 → 출력은 스키마에 맞춰 강제 → 검증 실패 시 HOLD/재시도 → 로그에 남겨 리플레이

역할 경계부터 잡고 싶다면 멀티에이전트 투자 시스템 역할 분리 설계: 분석·예측·의사결정 에이전트를 나누는 기준를 참고하세요.

에이전트 JSON 스키마, 정확히 뭐냐: “구조화 출력”이 아니라 “계약(Contract)”이다

용어 정리

  • Output Schema(출력 스키마): LLM이 내야 하는 JSON의 형식(필드/타입/enum/필수값)
  • Data Contract(데이터 계약): 단계 간(분석→예측→결정) 연결을 보장하는 입출력 약속
  • Validation(검증): (1) JSON 파싱 (2) 스키마 검증 (3) 도메인 규칙 검증(예: 확률 합=1)

스키마는 “예쁘게 만들기”가 목적이 아니라, 운영에서 실패를 안전하게 처리하기 위한 장치입니다.

분석→예측→결정 연결에 필요한 “최소 계약” 3개

이 글에서는 딱 3가지 계약만 잡아도 파이프라인이 안정화됩니다.

  • AnalysisOutput: 멀티소스 신호를 구조화(근거 포함)
  • PredictionOutput: T+1/T+5/T+20 Up/Down/Side 확률 분포
  • DecisionOutput: 예측을 “주문”이 아니라 이산 포지션 조절 액션으로 번역

Analysis Contract (분석)

근거 기반 신호를 구조화한다(행동 금지)

필수 필드

signals[], evidence[], confidence(0~1)

검증 포인트

evidence 최소 1개 필수

참고: 분석 에이전트 4종: announcement / event / price momentum / market

Prediction Contract (예측)

T+1/T+5/T+20 Up·Down·Side 확률만 출력

필수 필드

horizons.T1/T5/T20, up/down/side

검증 포인트

(도메인) up+down+side=1

참고: Nv≈30, qL/qU=30%/70%, τhigh≈1.4, τlow≈0.7, sideways≈33%

Decision Contract (결정)

주문이 아니라 "이산 포지션 조절 액션"만 출력

필수 필드

action(enum), rationale[], constraints_applied[]

검증 포인트

action은 7개 enum만 허용

참고: close / -40 / -20 / hold / +20 / +40 / upper limit

경계(금지행동) · 계약(JSON) · 검증(Validation)

데이터 계약 3단계 요약.

연구 참고: 중국 공모 REITs(저변동 시장) 대상 LLM 멀티에이전트 연구는 분석 에이전트 4종(announcement/event/price momentum/market) → 예측 에이전트가 다중 호라이즌 확률(T+1/T+5/T+20) → 의사결정은 이산 액션(close, ±20, ±40, upper limit) 구조로 “analysis–prediction–decision–execution” 폐루프를 구성합니다. 동적 임계값 θ 설정에서 Nv≈30일, qL/qU=30%/70%, τhigh≈1.4, τlow≈0.7, 약 33% 거래일이 sideways(횡보)로 분류된다고 서술합니다.

복붙용 템플릿 0: 모든 에이전트에 공통으로 넣을 “Envelope(봉투)”

스키마가 커질수록, 공통 필드는 일관되게 박아두는 게 유지보수에 유리합니다.

  • schema_id / schema_version (버전 관리)
  • run_id (리플레이/추적)
  • as_of (시점)
  • asset (종목/펀드)
  • inputs_hash (입력 스냅샷 식별)
  • output (실제 페이로드)
필드타입필수운영 목적예시 값
schema_idstring필수스키마 식별"analysis_output_v1"
schema_versionstring필수버전 관리"1.0.0"
run_idstring필수실행 추적/리플레이 키"2024-10-01_180102.SZ_run_0001"
as_ofstring(ISO-8601)필수의사결정 기준 시점"2024-10-01T09:30:00+08:00"
asset.codestring필수종목/펀드 식별"180102.SZ"
inputs_hashstring권장입력 스냅샷 고정(리플레이)"sha256:…"
upstream_refsarray[string]권장상위 단계 출력 참조["analysis_run_id:…"]
model_idstring권장사용 모델 기록"DeepSeek-R1" / "Qwen3-8B-FT"
data_windowobject권장윈도우/기간 기록"Oct 2024–Oct 2025"
transaction_cost_ratenumber권장비용 가정 기록0.0003 (0.03%)
notesstring선택사람용 메모"validation_retry"

템플릿 1: AnalysisOutput JSON 스키마 (분석 에이전트용)

1) JSON Schema(요약 버전)

아래는 “분석 에이전트 출력”에 필요한 최소 스키마 골격입니다. (필드는 확장 가능)

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "AnalysisOutput",
  "type": "object",
  "required": ["schema_id", "run_id", "as_of", "asset", "signals"],
  "properties": {
    "schema_id": { "type": "string", "const": "analysis_output_v1" },
    "run_id": { "type": "string" },
    "as_of": { "type": "string" },
    "asset": {
      "type": "object",
      "required": ["code"],
      "properties": { "code": { "type": "string" }, "market": { "type": "string" } }
    },
    "signals": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["topic", "claim", "confidence", "evidence"],
        "properties": {
          "topic": { "type": "string" },
          "claim": { "type": "string", "enum": ["positive", "neutral", "negative"] },
          "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
          "evidence": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": ["source", "ref"],
              "properties": {
                "source": { "type": "string", "enum": ["disclosure", "news", "price", "macro"] },
                "ref": { "type": "string" }
              }
            }
          },
          "risk_flags": { "type": "array", "items": { "type": "string" } }
        }
      }
    }
  }
}

2) 실제 연구 설정을 반영한 입력/피처(참고)

저변동 REITs 시장 분석 에이전트(가격 모멘텀)에서 사용된 대표 피처는 다음처럼 윈도우가 명시되어야 재현됩니다.

  • MA: 5/10/20/60
  • RSI: 6/12/24
  • MACD(DIF/DEA/Histogram)
  • Bollinger Bands: (20, 2σ)
  • Volume MA: 5/10/20
  • 구조 레벨: 고저점 롤링 윈도우 5/10/20/60

근거 팁

evidence의 ref는 “문서ID/기사ID/데이터스냅샷키”처럼 재조회 가능한 형태로 강제하세요.

템플릿 2: PredictionOutput JSON 스키마 (예측 에이전트용)

예측은 문장으로 쓰지 말고 확률 분포로만 고정하는 게 핵심입니다.

1) JSON Schema(요약 버전)

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "PredictionOutput",
  "type": "object",
  "required": ["schema_id", "run_id", "as_of", "asset", "horizons"],
  "properties": {
    "schema_id": { "type": "string", "const": "prediction_output_v1" },
    "run_id": { "type": "string" },
    "as_of": { "type": "string" },
    "asset": { "type": "object", "required": ["code"], "properties": { "code": { "type": "string" } } },
    "horizons": {
      "type": "object",
      "required": ["T1", "T5", "T20"],
      "properties": {
        "T1": { "$ref": "#/$defs/prob3" },
        "T5": { "$ref": "#/$defs/prob3" },
        "T20": { "$ref": "#/$defs/prob3" }
      }
    }
  },
  "$defs": {
    "prob3": {
      "type": "object",
      "required": ["up", "down", "side"],
      "properties": {
        "up": { "type": "number", "minimum": 0, "maximum": 1 },
        "down": { "type": "number", "minimum": 0, "maximum": 1 },
        "side": { "type": "number", "minimum": 0, "maximum": 1 }
      }
    }
  }
}

중요: JSON Schema만으로 “up+down+side=1”을 완벽히 강제하기 어렵습니다. 그래서 도메인 검증(런타임 체크)를 반드시 추가하세요.

검증 항목규칙(조건)실패 시 증상조치(폴백)로그에 남길 필드
확률 범위 체크up/down/side는 0~1 범위음수/1 초과예측 재생성 또는 HOLD 폴백run_id, offending_field, raw_output
확률합 체크up + down + side = 1합이 1이 아님(누락/중복/파싱 오류)예측 재생성 또는 HOLD 폴백sum_value, horizons, raw_output
호라이즌 누락 체크T1/T5/T20 모두 존재T5만 있고 T1/T20 없음 등누락 호라이즌 재생성(또는 전체 재생성)missing_horizons
side(횡보) 경고 체크side가 지속적으로 0 또는 1에 고정되는 패턴은 이상 신호참고: sideways 약 33%가 정상 범주경고 플래그만 세우고 진행(또는 인간 검토 큐)side_series_stats, warning_flag
side 정의 참조 존재 여부side_definition(또는 참조키)에 Nv≈30, qL/qU=30%/70%, τhigh≈1.4, τlow≈0.7 추적 가능side 기준이 빠져 재현 불가기준 키 누락 시 재생성 또는 run_config에서 주입side_definition_ref

2) sideways(횡보) 파라미터를 스키마에 포함시켜야 하는 이유

왜 예측 결과가 달라 보일까?

“횡보”란 가격이 크게 오르지도 내리지도 않고 옆으로만 움직이는 구간을 말합니다. 문제는 어디까지를 횡보로 볼지 사람마다·시스템마다 기준이 다르다는 점입니다. 그 기준이 머릿속에만 있으면, 같은 데이터를 넣어도 “예측이 왜 저번이랑 달라?” 하는 혼란이 생깁니다.

연구에서는 어떻게 하나?

실제 연구(예: 중국 공모 REITs 멀티에이전트)에서는 “횡보 기준”을 숫자로 고정해 둡니다. 예를 들면 “최근 30일 변동성”, “30%·70% 구간 경계”, “상승/하락 구간을 나누는 비율(τhigh≈1.4, τlow≈0.7)” 같은 값들이요. 이렇게 정해 두면, 그 설정에 따라 거래일의 약 33%가 횡보로 분류된다고 보고합니다.

그래서 출력에는 뭘 남기면 되나?

prediction_output에는 “횡보를 이렇게 정했다”는 요약(side_definition) 또는 그걸 가리키는 참조키를 넣는 것이 좋습니다. 그러면 나중에 같은 데이터로 다시 돌려도 “횡보 기준이 달라져서 결과가 바뀐 것처럼 보이는” 일을 막을 수 있습니다. 즉, “기준이 뭐였는지”가 출력에 남아 있어야 재현과 비교가 가능해집니다.

템플릿 3: DecisionOutput JSON 스키마 (의사결정 에이전트용)

의사결정은 “주문”이 아니라 포지션 조절 액션만 내야 안정적입니다.

1) JSON Schema(요약 버전)

아래 enum은 연구에서 제시된 이산 액션(예: close, reduce 40%, …, upper limit)을 그대로 시스템용 키로 옮긴 것입니다.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "DecisionOutput",
  "type": "object",
  "required": ["schema_id", "run_id", "as_of", "asset", "action", "rationale"],
  "properties": {
    "schema_id": { "type": "string", "const": "decision_output_v1" },
    "run_id": { "type": "string" },
    "as_of": { "type": "string" },
    "asset": { "type": "object", "required": ["code"], "properties": { "code": { "type": "string" } } },
    "action": {
      "type": "string",
      "enum": ["close", "reduce_40", "reduce_20", "hold", "increase_20", "increase_40", "increase_upper_limit"]
    },
    "rationale": {
      "type": "array",
      "minItems": 1,
      "items": { "type": "string" }
    },
    "constraints_applied": { "type": "array", "items": { "type": "string" } }
  }
}

2) 결정 스키마에 “리스크 제약 상태”를 어떻게 반영할까

결정은 예측만 보고 내리면 안 됩니다. 최소한 constraints_applied에 아래 같은 제약 발동 여부를 남기세요: position cap / step size / pace restriction / stop rule. 이건 단순 로깅이 아니라, 나중에 왜 hold가 나왔는지를 재현하는 핵심 힌트가 됩니다.

계정 상태(Account state)·주문 실행(Execution) 레이어 설계를 참고하세요.

검증(Validation) 파이프라인: “실패해도 안전하게”가 스키마의 목적이다

스키마 기반 운영의 정석은 이 4단계입니다.

  1. Parse: JSON 파싱 실패 → 즉시 재시도(최대 N회)
  2. Schema Validate: 필수 필드/타입/enum 검증 실패 → 재시도
  3. Domain Validate: 확률 합, 호라이즌 누락, 액션-제약 충돌 → HOLD 폴백
  4. Log: 어떤 단계에서 왜 실패했는지 저장(리플레이 가능)
실패 유형대표 원인탐지 방법조치(재시도/폴백)로그 필드
파싱 실패JSON 깨짐/불필요 텍스트 혼입parser error“JSON만 출력” 프롬프트로 재시도 → 실패 지속 시 HOLDraw_text, parser_error
필드 누락horizons 누락, evidence 누락 등schema validate 실패누락 필드만 재생성 또는 전체 재시도 → 실패 시 HOLDmissing_fields
확률합 불일치계산 실수/필드 중복/누락도메인 검증 실패예측 재생성 → 실패 시 HOLDsum_value, horizons
enum 위반허용되지 않은 액션(예: “increase_30”) 출력schema validate 실패(enum mismatch)“허용 enum 목록”을 시스템 메시지로 주입 후 재시도 → 실패 시 HOLDinvalid_enum, allowed_enum
evidence 누락분석이 결론만 출력evidence minItems 위반분석 재생성(근거 강제) → 실패 시 “needs_human_review” 플래그 + HOLDevidence_missing, sources_expected

폴백 기본값을 HOLD로 두고, 실패 사유를 로그에 남겨 리플레이 가능하게 만드는 것이 핵심.

실전 팁

“재시도”는 무조건 늘리면 비용만 올라갑니다. 보통 2회 재시도 + HOLD 폴백이 운영 안정성과 비용의 균형이 좋습니다. (재시도 사유는 반드시 로그에 남기기)

LLM 환각을 줄이는 “프롬프트 제약(용어/근거/형식)” 체크리스트를 참고하세요.

로그/리플레이를 위한 LogEvent 스키마(재현·추적의 핵심)

스키마를 잡았는데도 성과가 안 오르면, 원인은 대부분 “어디서 새는지”를 못 보는 겁니다. 그래서 로그도 스키마가 필요합니다.

  • 입력 스냅샷 키(inputs_hash)
  • 각 에이전트 출력 원문(JSON)
  • 검증 결과(성공/실패, 실패 사유)
  • 최종 액션과 실행 여부
  • 성과 지표(옵션): CR/Sharpe/MDD 등
한 번의 실행(run_id)에서 입력 스냅샷 → 분석·예측·결정 출력 → 검증 결과 → 실행 결과가 로그 저장소(RUN EVENT)로 흐르는 구조. run_id, inputs_hash, upstream_refs, raw_outputs 링크, replay_ready 포함.
에이전트 출력과 검증 결과를 포함한 트레이딩 로그 이벤트 구조.

전략 운영에서 로그/리플레이(리뷰) 구조 만들기를 참고하세요.

“이 구조가 실제로 의미 있나?”를 보여주는 공개 성과 수치

중국 공모 REITs 28개 펀드(각 계정 초기자본 RMB 1 million, 거래비용 0.03%(0.0003))를 대상으로 한 2024년 10월~2025년 10월 백테스트에서, 멀티에이전트 기반 전략이 Buy&Hold 대비 평균 성과 개선을 보고합니다.

  • 평균 CR(%): 15.50 / 13.75 / 10.69
  • 평균 Sharpe: 1.71 / 1.77 / 0.75
  • 평균 MDD(%): -4.09 / -3.46 / -11.12

CR (%)

-15%5%25%55%DeepSeek-R1Qwen3-8B-FTBuy & Hold15.5%13.75%10.69%

Sharpe

00.651.32.5DeepSeek-R1Qwen3-8B-FTBuy & Hold1.711.770.75

MDD (%)

-26%-19%-12%0%DeepSeek-R1Qwen3-8B-FTBuy & Hold-4.09%-3.46%-11.12%
MAS(Agent-DeepSeek-R1, Agent-Qwen3-8B-FT) vs Buy&Hold의 Mean CR·Sharpe·MDD 비교(28개 REITs 평균).

한계·주의

이 수치는 “수익 보장”이 아니라 특정 기간/시장/가정(거래비용 포함) 하에서의 결과입니다. 레짐 변화·체결·데이터 누락에 따라 실거래는 달라질 수 있습니다.

FAQ

자주 묻는 질문

JSON 스키마만 있으면 출력이 완벽히 고정되나요?
아니요. 스키마는 "형식"을 고정합니다. 확률 합=1 같은 규칙은 추가로 도메인 검증이 필요합니다.
function calling을 쓰면 스키마 검증이 필요 없나요?
function calling은 형식을 강제하는 데 매우 유리하지만, 여전히 도메인 규칙(합=1, 제약 충돌 등)은 검증해야 합니다.
스키마가 너무 빡빡하면 모델 성능이 떨어지지 않나요?
보통 반대입니다. 운영에서는 "성능"보다 일관성·검증 가능성이 더 큰 이득을 줍니다. 애매하면 필드에 notes(텍스트)를 따로 두고 핵심은 구조화하세요.
분석 에이전트마다 스키마를 다르게 가져가도 되나요?
가능하지만, 최소한 공통 Envelope(run_id/as_of/asset/evidence)를 공유해야 나중에 합치기 쉽습니다.
가장 작은 시작(최소 템플릿)은?
AnalysisOutput(근거 포함) + PredictionOutput(T5만) + DecisionOutput(hold/±20만) + 검증/로그부터 시작하세요.

결론: “스키마가 곧 시스템”이다

에이전트 JSON 스키마는 단순한 포맷이 아니라, 재현 가능한 폐루프를 만드는 데이터 계약입니다. 오늘 할 일은 하나입니다. 분석→예측→결정 3개 스키마를 고정하고, 검증 실패 시 안전하게 HOLD로 떨어지도록 만드세요.

데이터 기준 시점
2026-02-22
계산 방식
LLM·멀티에이전트 설계 개념 정리. 투자 권유 아님.
한계점
실제 구현·API는 환경에 따라 다르며, 과장·보장 표현 없음.