<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>JSON Codec — 데이터스케쳐스 위키</title>
  <meta name="description" content="JSON Codec (커스텀 JSON 직렬화) LangChain4j는 &quot;tools&quot;와 &quot;structured output&quot; 기능이 쓰는 내부 JSON 직렬화기를 내장하고 있어요(기본값은 Jackson). 대부분의 경우 기본 직렬화기로 충분해요. 다만 일부 환경에서는 기본" />
  
  <link rel="canonical" href="https://data-sketchers.com/wiki/tech-stack.ai-llm.langchain4j.json" />
  

  <!-- Hreflang (KO/EN + x-default) — 대안 언어는 koUrl/enUrl(없으면 생략) -->
  <link rel="alternate" hreflang="ko" href="https://data-sketchers.com/wiki/tech-stack.ai-llm.langchain4j.json" />
  <link rel="alternate" hreflang="en" href="https://data-sketchers.com/en/wiki/tech-stack.ai-llm.langchain4j.json" />
  <link rel="alternate" hreflang="x-default" href="https://data-sketchers.com/wiki/tech-stack.ai-llm.langchain4j.json" />

  <!-- Open Graph -->
  <meta property="og:type" content="website" />
  <meta property="og:site_name" content="DataSketchers" />
  <meta property="og:title" content="JSON Codec — 데이터스케쳐스 위키" />
  <meta property="og:description" content="JSON Codec (커스텀 JSON 직렬화) LangChain4j는 &quot;tools&quot;와 &quot;structured output&quot; 기능이 쓰는 내부 JSON 직렬화기를 내장하고 있어요(기본값은 Jackson). 대부분의 경우 기본 직렬화기로 충분해요. 다만 일부 환경에서는 기본" />
  <meta property="og:url" content="https://data-sketchers.com/wiki/tech-stack.ai-llm.langchain4j.json" />
  <meta property="og:image" content="https://data-sketchers.com/assets/logo-black.png" />
  <meta property="og:image:width" content="2172" />
  <meta property="og:image:height" content="724" />
  <meta property="og:image:alt" content="JSON Codec — 데이터스케쳐스 위키" />
  <meta property="og:locale" content="ko_KR" />
  <meta property="og:locale:alternate" content="en_US" />

  <!-- Twitter -->
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:title" content="JSON Codec — 데이터스케쳐스 위키" />
  <meta name="twitter:description" content="JSON Codec (커스텀 JSON 직렬화) LangChain4j는 &quot;tools&quot;와 &quot;structured output&quot; 기능이 쓰는 내부 JSON 직렬화기를 내장하고 있어요(기본값은 Jackson). 대부분의 경우 기본 직렬화기로 충분해요. 다만 일부 환경에서는 기본" />
  <meta name="twitter:image" content="https://data-sketchers.com/assets/logo-black.png" />
  <meta name="twitter:image:alt" content="JSON Codec — 데이터스케쳐스 위키" />

  <!-- Organization JSON-LD — th:inline 금지(파싱 오류): 사이트 url 을 컨트롤러가 organizationJson 으로 주입.
       주입이 없으면 고정 생략(페이지별 통합 시 site/json 주입). -->
  <script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"DataSketchers","url":"https://data-sketchers.com","logo":"https://data-sketchers.com/assets/logo-black.png","sameAs":["https://github.com/data-sketchers"]}</script>
  <!-- 페이지별 커스텀 JSON-LD (BlogPosting/Article/BreadcrumbList) — 호출측에서 pageJson 통째로 주입 -->
  <script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":"1","name":"Home","item":"jdbc:postgresql://pg-dev.data-sketchers.dev:23452/data-sketchers-wiki?user=data-sketchers-land&password=OZcV%2Brr7rTR7vVJgDFkq6gFsZcBXyoKb1bBsEDIJw12%2BC6uo&sslmode=prefer/wiki/"},{"@type":"ListItem","position":"2","name":"tech-stack.ai-llm.langchain4j.json","item":"jdbc:postgresql://pg-dev.data-sketchers.dev:23452/data-sketchers-wiki?user=data-sketchers-land&password=OZcV%2Brr7rTR7vVJgDFkq6gFsZcBXyoKb1bBsEDIJw12%2BC6uo&sslmode=prefer/wiki/tech-stack.ai-llm.langchain4j.json"}]},{"@type":"Article","headline":"JSON Codec","description":"JSON Codec (커스텀 JSON 직렬화) LangChain4j는 \"tools\"와 \"structured output\" 기능이 쓰는 내부 JSON 직렬화기를 내장하고 있어요(기본값은 Jackson). 대부분의 경우 기본 직렬화기로 충분해요. 다만 일부 환경에서는 기본","mainEntityOfPage":"jdbc:postgresql://pg-dev.data-sketchers.dev:23452/data-sketchers-wiki?user=data-sketchers-land&password=OZcV%2Brr7rTR7vVJgDFkq6gFsZcBXyoKb1bBsEDIJw12%2BC6uo&sslmode=prefer/wiki/tech-stack.ai-llm.langchain4j.json","url":"jdbc:postgresql://pg-dev.data-sketchers.dev:23452/data-sketchers-wiki?user=data-sketchers-land&password=OZcV%2Brr7rTR7vVJgDFkq6gFsZcBXyoKb1bBsEDIJw12%2BC6uo&sslmode=prefer/wiki/tech-stack.ai-llm.langchain4j.json","dateModified":"2026-09-12T12:59:03.280321Z"}]}</script>

  <link rel="icon" type="image/png" href="/assets/favicon.png" />
  <link rel="preconnect" href="https://cdn.jsdelivr.net" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&display=swap" />
  <link rel="stylesheet" href="/ds/tokens.css" />
  <!-- 원본 디자인 시스템 재현 (기존 대비 95%+ 목표) -->
  <link rel="stylesheet" href="/ds/base.css" />
  <link rel="stylesheet" href="/ds/components.css" />
  <link rel="stylesheet" href="/ds/post.css" />
  <link rel="stylesheet" href="/ds/effects.css" />
  <script src="/ds/effects.js" defer></script>
  <script src="/ds/threads.js" defer></script>
</head>
<body>
  <html>
<header id="site-header" class="site-header">
  <div class="site-header__inner">
    <a href="/" class="site-header__logo" aria-label="DataSketchers 홈" data-logo-host>
      <img class="site-header__logo-word" src="/assets/logo-data-sketchers-light-bg.png" alt="" width="153" height="51" style="height:48px;width:auto" />
    </a>
    <nav class="site-header__nav" aria-label="주 메뉴">
      <!-- DB 관리 헤더 메뉴 (site_menu source-of-truth). 항목이 children 을 가지면 서브메뉴 렌더 -->
      <div class="site-header__nav-wrap">
        
        
          <a href="/about" class="site-header__nav-item">회사소개</a>
        
      </div>
      <div class="site-header__nav-wrap">
        
        
          <a href="/blog" class="site-header__nav-item">블로그</a>
        
      </div>
    </nav>
    <div class="site-header__utils">
      <button class="site-header__menu-btn" data-menu-open aria-label="전체 메뉴 열기" aria-expanded="false">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
          <line x1="4" y1="8" x2="20" y2="8" /><line x1="4" y1="16" x2="20" y2="16" />
        </svg>
      </button>
    </div>
  </div>
</header>

<!-- 전체 메뉴(햄버거) 풀 스크린 오버레이 — 데스크톱·모바일 모두 동작. hamburger_menu (DB) 기반 -->
<div class="site-menu-overlay" data-menu-overlay aria-hidden="true">
  <div class="site-menu-overlay__scrim" data-menu-close></div>
  <div class="site-menu-overlay__panel" role="dialog" aria-modal="true" aria-label="전체 메뉴">
    <div class="site-menu-overlay__head">
      <a href="/" class="site-menu-overlay__logo" data-menu-close>
        <img src="/assets/logo-data-sketchers-light-bg.png" alt="DataSketchers" width="132" height="44" style="height:36px;width:auto" />
      </a>
      <button class="site-menu-overlay__close" data-menu-close aria-label="전체 메뉴 닫기">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></svg>
      </button>
    </div>
    <nav class="site-menu-overlay__nav" aria-label="전체 메뉴 목록">
      <h2 class="site-menu-overlay__title">전체 메뉴</h2>
      <div class="site-menu-overlay__group">
        <a href="/about" class="site-menu-overlay__group-title"
           data-menu-close>회사소개</a>
        
      </div>
      <div class="site-menu-overlay__group">
        <a href="/services" class="site-menu-overlay__group-title"
           data-menu-close>사업영역</a>
        
      </div>
      <div class="site-menu-overlay__group">
        <a href="/products" class="site-menu-overlay__group-title"
           data-menu-close>D-SKET</a>
        <div class="site-menu-overlay__subs">
          <a href="/products/webbuilder"
             class="site-menu-overlay__sub" data-menu-close>웹빌더</a><a href="/products/canvas"
             class="site-menu-overlay__sub" data-menu-close>Canvas</a><a href="/products/events"
             class="site-menu-overlay__sub" data-menu-close>Events</a>
        </div>
      </div>
      <div class="site-menu-overlay__group">
        <a href="/clients" class="site-menu-overlay__group-title"
           data-menu-close>고객사</a>
        
      </div>
      <div class="site-menu-overlay__group">
        <a href="/blog" class="site-menu-overlay__group-title"
           data-menu-close>블로그</a>
        
      </div>
      <div class="site-menu-overlay__group">
        <a href="/" class="site-menu-overlay__group-title"
           data-menu-close>위키</a>
        
      </div>
      <div class="site-menu-overlay__group">
        <a href="/press" class="site-menu-overlay__group-title"
           data-menu-close>보도자료</a>
        
      </div>
      <div class="site-menu-overlay__group">
        <a href="/esg" class="site-menu-overlay__group-title"
           data-menu-close>ESG</a>
        
      </div>
    </nav>
  </div>
</div>
</html>

  <main class="ds-container" style="padding-top:calc(var(--header-h) + 24px);">
    <div class="wiki-layout" style="padding-top:0;">   <!-- layout CSS(columns/gap) 는 ds/effects.css 의 .wiki-layout 가 담당 -->

      <!-- ═══ 왼쪽: scope tree (재귀, 접기/펼치기) ═══ -->
      <aside id="wiki-scope" class="wiki-scope">
        <div style="padding:12px 12px 10px; font-family:var(--font-mono); font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ds-text-3);">Topics</div>
        <!-- 조상 breadcrumb (root=현재 페이지이므로 위로 이동 경로) -->
        <nav aria-label="위키 경로" style="display:flex; flex-wrap:wrap; gap:4px 2px; align-items:center; padding:0 12px 10px; border-bottom:1px solid var(--ds-line); margin-bottom:8px;">
          <a href="/wiki/tech-stack" style="font-size:11px; color:var(--ds-text-3); text-decoration:none; white-space:nowrap;">기술 스택</a><a href="/wiki/tech-stack.ai-llm" style="font-size:11px; color:var(--ds-text-3); text-decoration:none; white-space:nowrap;">AI·LLM 통합 (AI &amp; LLM)</a><a href="/wiki/tech-stack.ai-llm.langchain4j" style="font-size:11px; color:var(--ds-text-3); text-decoration:none; white-space:nowrap;">LangChain4j (모델·채팅·임베딩)</a>
          <span style="color:var(--ds-line-strong); font-size:10px;">›</span><span style="color:var(--ds-line-strong); font-size:10px;">›</span><span style="color:var(--ds-line-strong); font-size:10px;">›</span>
        </nav>
        <nav aria-label="위키 주제 트리" style="display:flex; flex-direction:column; gap:2px;">
          <ul class="wiki-tree" style="list-style:none; margin:0; padding:0;">
    
      <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      <button type="button" class="wiki-tree__toggle" data-wtree-toggle
              aria-label="하위 토글" aria-expanded="true">▾</button>
      

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j">LangChain4j (모델·채팅·임베딩)</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    <ul class="wiki-tree"
        style="list-style:none; margin:0; padding:0 0 0 14px;">
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.agentic-ai">Agents and Agentic AI</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.ai-services">AI Services</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.amazon-bedrock">Amazon Bedrock 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.anthropic">Anthropic 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.azure-open-ai">Azure OpenAI 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.chat-and-language-models">Chat and Language Models</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.chat-memory">Chat Memory</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.classification">분류</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.cohere">Cohere 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.customizable-http-client">커스터마이즈 가능한 HTTP 클라이언트</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.embedding-stores">Embedding</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.embed-ollama">Ollama 임베딩 모델 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.embed-open-ai">OpenAI 임베딩 모델 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.get-started">시작하기</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.google-ai-gemini">Google AI Gemini 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.guardrails">가드레일</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.helidon-integration">Helidon 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.image-models">Image Models</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.intro">LangChain4j 소개</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.jackson-3">Jackson 3 사용하기</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node is-active" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link is-active"
         href="/wiki/tech-stack.ai-llm.langchain4j.json">JSON Codec</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.kotlin">Kotlin 지원</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.logging">로깅</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.mcp">Model Context Protocol</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.mcp-stdio-server">자바 MCP stdio 서버 구축하기</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.micronaut-integration">Micronaut 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.mistral-ai">MistralAI 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.model-parameters">모델 파라미터</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.non-blocking">Non-blocking and Reactive</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.observability">Observability</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.ollama">Ollama 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.open-ai">OpenAI 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.quarkus-integration">Quarkus 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.rag">RAG</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.response-streaming">Response Streaming</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.skills">Skills</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.spring-boot-integration">Spring Boot 통합</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.structured-outputs">Structured Outputs</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.testing-and-evaluation">테스트와 평가</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
        <li class="wiki-tree__node" style="margin:0; padding:0;">

    <div class="wiki-tree__row">
      <!-- 접기/펼치기 토글: 자식 보유 노드만. 클릭 = 하위 토글(페이지 이동 없음) -->
      
      <span class="wiki-tree__dot" aria-hidden="true"></span>

      <!-- 제목: 문서 링크 또는 목차 앵커.
           th:if / th:else 는 이 템플릿에서 인접 정합이 깨져 둘 다 렌더되는 버그가 있음(중복 2열 노출).
           반드시 버튼/점 처럼 상호배타 th:if 두 개로 쓴다. -->
      
      <a class="wiki-tree__link"
         href="/wiki/tech-stack.ai-llm.langchain4j.tools">Tools</a>
    </div>

    <!-- 하위 트리: 펼침(isOpen)일 때만 재귀 렌더. 접힌 노드는 빈 placeholder `<ul>` 만 두고
         (data-wtree-lazy = 지연 로드 경로) 펼칠 때 /wiki/tree/{path} 프래그먼트로 로드.
         hidden 속성 금지 — hidden=false 가 요소를 숨김. CSS is-collapsed 로 숨김. -->
    
  </li>
      
    </ul>
  </li>
    
  </ul>
        </nav>
      </aside>

      <!-- ═══ 중앙: 콘텐츠 ═══ -->
      <article class="ds-doc" style="min-width:0;">
        <nav class="ds-breadcrumb" aria-label="breadcrumb" style="padding:12px 0 16px; font-size:12.5px; color:var(--ds-text-3);">
          <a href="/wiki/tech-stack" style="color:inherit; text-decoration:none;">기술 스택</a><a href="/wiki/tech-stack.ai-llm" style="color:inherit; text-decoration:none;">AI·LLM 통합 (AI &amp; LLM)</a><a href="/wiki/tech-stack.ai-llm.langchain4j" style="color:inherit; text-decoration:none;">LangChain4j (모델·채팅·임베딩)</a>
          <span style="color:var(--ds-line-strong);"> › </span><span style="color:var(--ds-line-strong);"> › </span><span style="color:var(--ds-line-strong);"> › </span>
        </nav>
        <h1 style="margin-bottom:20px;">JSON Codec</h1>
        <!-- 모바일 전용: 목차를 본문 상단(제목 하단)에 항상 펼침 -->
        <nav aria-label="페이지 목차" class="wiki-toc-mobile"
             style="display:none; border-bottom:1px solid var(--ds-line); padding-bottom:12px; margin-bottom:24px;">
          <div class="ds-label" style="font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ds-text-3); margin-bottom:8px;">목차</div>
          <div style="display:flex; flex-direction:column; gap:2px;">
            <a href="#json-codec-커스텀-json-직렬화" style="padding-left:0px">JSON Codec (커스텀 JSON 직렬화)</a><a href="#주의사항" style="padding-left:0px">주의사항</a><a href="#더-알아보기" style="padding-left:0px">더 알아보기</a>
          </div>
        </nav>
        <div><h2 id="json-codec-커스텀-json-직렬화">JSON Codec (커스텀 JSON 직렬화)</h2>
<p>LangChain4j는 &quot;tools&quot;와 &quot;structured output&quot; 기능이 쓰는 내부 JSON 직렬화기를 내장하고 있어요(기본값은 Jackson). 대부분의 경우 기본 직렬화기로 충분해요. 다만 일부 환경에서는 기본 Jackson 직렬화기가 다른 의존성 때문에 오류를 일으킬 수 있어요. 예를 들어 Jetbrains/IntelliJ 플러그인 개발자들이 그런 경우를 겪었어요.</p>
<p>자체 JSON 직렬화기(일명 JSON Codec)를 제공해야 한다면 다음 단계를 따르면 돼요.</p>
<ol>
<li>프로젝트에 <code>dev.langchain4j.spi.json.JsonCodecFactory</code> 구현을 만든다</li>
</ol>
<p>예를 들어 팩토리 클래스가 <code>example.MyJsonCodecFactory</code>라고 해 볼게요. LangChain4j가 내부적으로 쓰는 기본 코덱인 <code>dev.langchain4j.internal.JacksonJsonCodec</code>를 확인하고 필요에 맞게 변형할 수 있어요.</p>
<ol start="2">
<li>SPI 프로바이더 설정 파일을 추가한다</li>
</ol>
<p>리소스 폴더(예: <code>src/main/resources</code>)에 <code>META-INF/services</code> 폴더를 만들고 <code>dev.langchain4j.spi.json.JsonCodecFactory</code>라는 파일을 생성해요. 파일 내용은 팩토리 구현의 FQDN이어야 해요. 예시에서는 이렇게 하면 돼요.</p>
<pre><code>example.MyJsonCodecFactory
</code></pre>
<blockquote>
<p>출처: <a href="https://docs.langchain4j.dev/tutorials/json/">공식문서 - JSON Codec</a></p>
</blockquote>
<h2 id="주의사항">주의사항</h2>
<p><code>dev.langchain4j.spi.json.JsonCodecFactory</code>는 LangChain4j에서 <strong>내부용</strong>으로 표시돼 있어요. 이 접근 방식은 커스텀 JSON Codec이 확실히 필요한 환경에서만 써야 해요.</p>
<p>LangChain4j가 Jackson 2 대신 Jackson 3을 쓰게 하고 싶다면 아래 절차는 필요 없어요. 의존성 하나만 추가하면 끝나요(Jackson 3 문서 참고).</p>
<h2 id="더-알아보기">더 알아보기</h2>
<ul>
<li><a href="tech-stack.ai-llm.langchain4j.tools">Tools (Function Calling)</a> - JSON 직렬화를 쓰는 도구 호출</li>
<li><a href="tech-stack.ai-llm.langchain4j.structured-outputs">Structured Outputs</a> - JSON 직렬화를 쓰는 구조화된 출력</li>
</ul>
</div>
      </article>

      <!-- ═══ 오른쪽: TOC (H2/H3 목차, 접기/펼치기) ═══ -->
      <aside class="wiki-toc" data-toc
             style="position:sticky; top:calc(var(--header-h) + 24px); max-height:calc(100vh - var(--header-h) - 48px); overflow:auto; padding:8px 0; border-left:1px solid var(--ds-line); padding-left:16px;">
        <button type="button" class="wiki-toc__toggle" aria-expanded="true" aria-controls="wiki-toc-nav">
          <span class="wiki-toc__label">목차</span>
          <span class="wiki-toc__chevron">▾</span>
        </button>
        <nav id="wiki-toc-nav" class="wiki-toc__nav" aria-label="페이지 목차">
          <a href="#json-codec-커스텀-json-직렬화" style="padding-left:0px">JSON Codec (커스텀 JSON 직렬화)</a><a href="#주의사항" style="padding-left:0px">주의사항</a><a href="#더-알아보기" style="padding-left:0px">더 알아보기</a>
        </nav>
      </aside>
    </div>
  </main>

  <!-- ═══ scope tree 접기/펼치기 인터랙션 ═══ -->
  <script>
  (function () {
    // 페이지 이동 시 항상 최상단(제목/목차)에서 시작 — 모바일에서 트리가 하단에 있어도 뷰포트를 하단에 남기지 않음
    if ('scrollRestoration' in history) { history.scrollRestoration = 'manual'; }
    window.addEventListener('load', function () { window.scrollTo(0, 0); });

    document.querySelectorAll('[data-wtree-toggle]').forEach(function (btn) {
      btn.addEventListener('click', function (e) {
        e.preventDefault();
        e.stopPropagation();
        var li = btn.closest('.wiki-tree__node');
        if (!li) return;
        var sub = li.querySelector(':scope > .wiki-tree');
        if (!sub) return;
        var lazyPath = sub.getAttribute('data-wtree-lazy');
        if (lazyPath && sub.getAttribute('data-wtree-loaded') !== '1') {
          // 첫 펼침: 하위 트리를 lazy 프래그먼트로 로드 후 펼침
          fetch('/wiki/tree/' + lazyPath.replace(/^\/+/, ''))
            .then(function (r) { return r.text(); })
            .then(function (html) {
              sub.innerHTML = html;
              sub.setAttribute('data-wtree-loaded', '1');
              sub.removeAttribute('data-wtree-lazy');
              wireToggles(sub);
              openSub(sub, btn);
            })
            .catch(function () { openSub(sub, btn); });
          return;
        }
        openSub(sub, btn);
      });
    });

    function openSub(sub, btn) {
      var collapsed = sub.classList.toggle('is-collapsed');
      sub.hidden = collapsed;
      btn.textContent = collapsed ? '▸' : '▾';
      btn.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
    }

    // lazy 프래그먼트로 삽입된 하위 노드들의 토글도 이벤트 연결
    function wireToggles(scope) {
      scope.querySelectorAll('[data-wtree-toggle]').forEach(function (btn) {
        if (btn._wtreeBound) return;
        btn._wtreeBound = true;
        btn.addEventListener('click', function (e) {
          e.preventDefault();
          e.stopPropagation();
          var li = btn.closest('.wiki-tree__node');
          if (!li) return;
          var sub = li.querySelector(':scope > .wiki-tree');
          if (!sub) return;
          var lazyPath = sub.getAttribute('data-wtree-lazy');
          if (lazyPath && sub.getAttribute('data-wtree-loaded') !== '1') {
            fetch('/wiki/tree/' + lazyPath.replace(/^\/+/, ''))
              .then(function (r) { return r.text(); })
              .then(function (html) {
                sub.innerHTML = html;
                sub.setAttribute('data-wtree-loaded', '1');
                sub.removeAttribute('data-wtree-lazy');
                wireToggles(sub);
                openSub(sub, btn);
              })
              .catch(function () { openSub(sub, btn); });
            return;
          }
          openSub(sub, btn);
        });
      });
    }

    // TOC 접기/펼치기 토글
    var toc = document.querySelector('[data-toc]');
    if (toc) {
      var toggleBtn = toc.querySelector('.wiki-toc__toggle');
      var nav = toc.querySelector('.wiki-toc__nav');
      var chevron = toc.querySelector('.wiki-toc__chevron');
      if (toggleBtn && nav) {
        toggleBtn.addEventListener('click', function () {
          var collapsed = toc.classList.toggle('is-collapsed');
          toggleBtn.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
          if (chevron) chevron.textContent = collapsed ? '▸' : '▾';
        });
      }
    }
    // 페이지 진입 시 활성 노드로 스크롤 노출
    var active = document.querySelector('.wiki-tree__node.is-active');
    if (active && active.scrollIntoView) {
      try { active.scrollIntoView({ block: 'nearest' }); } catch (e) {}
    }
  })();
  </script>

  <style>
    /* scope tree 행 스타일: 활성 강조 + 들여쓰기 토글 정렬 */
    .wiki-tree__row { display:flex; align-items:center; gap:6px; border-radius:var(--r-xs); }
    .wiki-tree__row:hover { background:var(--ds-bg-subtle); }
    .wiki-tree__toggle {
      flex:0 0 auto; width:16px; height:22px; padding:0; border:none; background:none;
      cursor:pointer; color:var(--ds-text-3); font-size:10px; line-height:1;
      display:flex; align-items:center; justify-content:center;
    }
    .wiki-tree__dot { flex:0 0 auto; width:16px; height:1px; }
    .wiki-tree__link {
      flex:1 1 auto; min-width:0; padding:6px 6px; border-radius:var(--r-xs);
      font-size:13px; color:var(--ds-text-2); text-decoration:none; line-height:1.35; overflow:hidden; text-overflow:ellipsis;
    }
    .wiki-tree__node.is-active > .wiki-tree__row { background:var(--ds-text); }
    .wiki-tree__node.is-active > .wiki-tree__row .wiki-tree__link { color:var(--ds-bg-card); font-weight:700; }
    .wiki-tree.is-collapsed { display:none; }
    /* TOC 접기/펼치기 토글 버튼 */
    .wiki-toc__toggle {
      display:flex; align-items:center; justify-content:space-between; width:100%;
      padding:4px 6px; margin-bottom:6px; border:none; background:none; cursor:pointer;
      font-size:12px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
      color:var(--ds-text-2); border-radius:var(--r-xs); text-align:left;
    }
    .wiki-toc__toggle:hover { color:var(--ds-text); background:var(--ds-bg-subtle); }
    .wiki-toc__nav { display:flex; flex-direction:column; gap:2px; }
    .wiki-toc__chevron { font-size:10px; color:var(--ds-text-3); transition:transform .15s var(--ease-out); }
    .wiki-toc.is-collapsed .wiki-toc__chevron { transform:rotate(-90deg); }
    .wiki-toc.is-collapsed .wiki-toc__nav { display:none; }
  </style>

  <html>
<footer class="site-footer--compact" style="background:var(--ds-bg-strong); color:var(--ds-text-on-dark); margin-top:80px;">
  <div class="site-footer--compact__inner">
    <!-- 1줄 블록: 좌측 브랜드 + 우측 링크 가로 나열 -->
    <div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:20px 32px;">
      <div style="display:flex; align-items:center; gap:16px; flex-wrap:wrap;">
        <img src="/assets/logo-white.png" alt="DataSketchers" style="height:32px; width:auto;" />
        <span style="font-size:13px; color:#b0b0b2; max-width:320px;">AI·데이터·디자인으로 기업의 디지털 전환을 지원합니다. 서울시립대학교 캠퍼스타운 창업기업</span>
      </div>
      <nav style="display:flex; flex-wrap:wrap; gap:8px 24px; font-size:13px;" aria-label="푸터 링크">
        <a href="/about" style="color:#e5e5e6; text-decoration:none;">회사소개</a>
        <a href="/services" style="color:#e5e5e6; text-decoration:none;">사업영역</a>
        <a href="/products" style="color:#e5e5e6; text-decoration:none;">D-SKET</a>
        <a href="/clients" style="color:#e5e5e6; text-decoration:none;">고객사</a>
        <a href="/blog" style="color:#e5e5e6; text-decoration:none;">블로그</a>
        <a href="/" style="color:#e5e5e6; text-decoration:none;">위키</a>
        <a href="/press" style="color:#e5e5e6; text-decoration:none;">보도자료</a>
        <a href="/esg" style="color:#e5e5e6; text-decoration:none;">ESG</a>
        <a href="/contact" style="color:#e5e5e6; text-decoration:none;">문의</a>
      </nav>
    </div>
    <div style="margin-top:28px; padding-top:16px; border-top:1px solid rgba(255,255,255,0.12); display:flex; justify-content:space-between; flex-wrap:wrap; gap:12px; font-size:13px; color:#8a8a8d;">
      <span>© 데이터스케쳐스. All rights reserved.</span>
      <span>사업자등록번호 349-81-03411</span>
    </div>
  </div>
</footer>
</html>
</body>
</html>
