<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Back to the Basics</title>
    <link>https://bcuts.tistory.com/</link>
    <description>B급 개발자 이야기, 인생은 B 컷이 전부다.</description>
    <language>ko</language>
    <pubDate>Wed, 15 Apr 2026 04:07:22 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>B컷개발자</managingEditor>
    <item>
      <title>소프트웨어 아키텍처 시리즈 16화 &amp;ndash; 마이크로서비스 경계 설계와 바운디드 컨텍스트 적용 전략</title>
      <link>https://bcuts.tistory.com/509</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스 아키텍처에서 경계 설계는 성공과 실패를 가르는 핵심 요소입니다. 이번 글에서는 DDD의 바운디드 컨텍스트 개념을 기반으로, 서비스 경계를 올바르게 설정하는 실전 전략을 소개합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 경계 설계가 중요한가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스의 핵심은 &lt;span&gt;&lt;b&gt;작고 독립적인 서비스&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &amp;ldquo;작다&amp;rdquo;는 것은 단순히 코드 라인이 적다는 뜻이 아니라, &lt;span&gt;&lt;b&gt;명확한 비즈니스 책임을 가진다&lt;/b&gt;&lt;/span&gt;는 의미입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘못된 경계 설계는 다음과 같은 문제를 만듭니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 간 데이터 공유와 의존성이 과도하게 발생&lt;/li&gt;
&lt;li&gt;배포/변경이 다른 서비스에 파급&lt;/li&gt;
&lt;li&gt;마이크로서비스가 오히려 &amp;ldquo;분산 모놀리식&amp;rdquo;으로 변질&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;바운디드 컨텍스트(Bounded Context)란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDD에서 바운디드 컨텍스트는 &lt;span&gt;&lt;b&gt;특정 도메인 모델이 유효하게 적용되는 경계&lt;/b&gt;&lt;/span&gt;를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 컨텍스트 안에서는 **유비쿼터스 언어(Ubiquitous Language)**가 일관되게 사용&lt;/li&gt;
&lt;li&gt;컨텍스트 밖에서는 모델 의미가 변하거나, 다른 해석이 필요할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;즉, 바운디드 컨텍스트는 도메인 경계를 명확히 하여,&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;모델의 혼란과 오염을 방지&lt;/b&gt;&lt;span&gt;하는 개념입니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;바운디드 컨텍스트와 마이크로서비스의 관계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;이상적인 경우&lt;/b&gt;&lt;/span&gt;: 하나의 바운디드 컨텍스트 = 하나의 마이크로서비스&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;현실적인 경우&lt;/b&gt;&lt;/span&gt;: 하나의 컨텍스트가 여러 마이크로서비스로 분할될 수도 있음 (규모나 비즈니스 복잡도에 따라)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;경계 설계 절차 (실전 접근)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 도메인 분석&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비즈니스의 핵심 기능과 하위 기능 나열&lt;/li&gt;
&lt;li&gt;업무 용어, 규칙, 데이터 흐름 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 서브도메인 분류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;핵심(Core) 도메인&lt;/b&gt;&lt;/span&gt;: 비즈니스 경쟁력의 핵심 로직&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지원(Supporting) 도메인&lt;/b&gt;&lt;span&gt;: 핵심을 보조하는 기능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;일반(Generic) 도메인&lt;/b&gt;&lt;/span&gt;: 범용 솔루션으로 대체 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 바운디드 컨텍스트 정의&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 도메인별 모델 경계와 용어집(Ubiquitous Language) 설정&lt;/li&gt;
&lt;li&gt;경계 내 모델과 로직은 다른 컨텍스트와 공유하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 서비스 경계 매핑&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 컨텍스트를 독립 서비스로 매핑&lt;/li&gt;
&lt;li&gt;컨텍스트 간 통신 방식(Event, API 등) 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예시 &amp;ndash; 전자상거래 도메인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;바운디드 컨텍스트&lt;/b&gt;&lt;b&gt;주요 기능&lt;/b&gt;&lt;b&gt;마이크로서비스 예시&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;주문(Order)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;주문 생성/취소, 상태 변경&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Order Service&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;결제(Payment)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;결제 승인, 결제 취소, 영수증 발급&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Payment Service&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;재고(Inventory)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;재고 확인, 입출고 관리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Inventory Service&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;배송(Shipping)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배송 요청, 추적, 반품 처리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Shipping Service&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;컨텍스트 간 관계 패턴&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;파트너십(Partnership)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 컨텍스트가 긴밀하게 협력&lt;/li&gt;
&lt;li&gt;예: 주문(Order) &amp;harr; 결제(Payment)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;공개 호스트 서비스(Open Host Service)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 컨텍스트가 표준 API를 제공&lt;/li&gt;
&lt;li&gt;예: 배송(Shipping)이 API로 추적 서비스 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;발행-구독(Publish-Subscribe)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트 기반 통신&lt;/li&gt;
&lt;li&gt;예: 주문 완료 이벤트 &amp;rarr; 재고 차감, 결제 요청&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;헥사고날 아키텍처와의 연결&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 마이크로서비스 내부 구조는 헥사고날 아키텍처로 구성 가능&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Inbound Port&lt;/b&gt;&lt;/span&gt;: 외부 요청(API, 이벤트) 수신&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Outbound Port&lt;/b&gt;&lt;/span&gt;: 다른 서비스 호출, 이벤트 발행&lt;/li&gt;
&lt;li&gt;경계 밖의 통신은 포트/어댑터를 통해 의존성 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;경계 설계 시 흔한 실수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 중심 경계 설정&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&amp;rarr; &amp;ldquo;DB 테이블 단위&amp;rdquo;로 서비스를 나누면 경계가 비즈니스 흐름과 어긋남&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기능 너무 세분화&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&amp;rarr; 불필요하게 작은 서비스는 운영 복잡도만 증가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모델 언어 혼재&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&amp;rarr; 다른 컨텍스트의 용어를 그대로 가져와 모델 혼란 초래&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;서비스 경계는 전략적 결정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스의 경계는 단순한 개발 편의가 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;조직 구조, 배포 전략, 확장성&lt;/b&gt;&lt;/span&gt;에 직결되는 전략적 결정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDD의 바운디드 컨텍스트 개념을 토대로 경계를 설계하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기술뿐 아니라 &lt;span&gt;&lt;b&gt;비즈니스의 언어와 흐름&lt;/b&gt;&lt;/span&gt;까지 코드에 녹일 수 있습니다.&lt;/p&gt;</description>
      <category>기술과 산업/아키텍처</category>
      <category>ddd</category>
      <category>도메인분석</category>
      <category>마이크로서비스경계</category>
      <category>바운디드컨텍스트</category>
      <category>서비스매핑</category>
      <category>서비스설계전략</category>
      <category>소프트웨어아키텍처</category>
      <category>이벤트기반통신</category>
      <category>헥사고날아키텍처</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/509</guid>
      <comments>https://bcuts.tistory.com/509#entry509comment</comments>
      <pubDate>Thu, 14 Aug 2025 17:20:23 +0900</pubDate>
    </item>
    <item>
      <title>Spring AI 시리즈 11화 &amp;ndash; ChatClient 고급 프롬프트 구성 전략과 문서 삽입 기법</title>
      <link>https://bcuts.tistory.com/508</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;RAG 시스템에서 검색된 문서를 프롬프트에 어떻게 구성하느냐에 따라 LLM의 응답 품질이 결정됩니다. 이 글에서는 Spring AI의 ChatClient를 활용한 고급 프롬프트 구성 방식과 문서 삽입 전략을 실전 예제 중심으로 소개합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;단순하게 &amp;ldquo;문서를 넣자&amp;rdquo;는 위험한 생각&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 초보 구현에서 이런 식의 프롬프트가 사용됩니다.&lt;/p&gt;
&lt;pre class=&quot;dust&quot;&gt;&lt;code&gt;[문서들]

{document1}
{document2}
{document3}

질문: 사용자가 입력한 질문
답변:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 구조, 잘못되진 않았지만 &lt;/span&gt;&lt;b&gt;지나치게 단순하고, 모델에게 역할이 명확하지 않으며, 문맥 유지가 어렵습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 여러 문서를 삽입하면 모델은 어디까지를 참고해야 할지 혼란스러워합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고급 RAG 시스템은 단순히 &amp;ldquo;문서를 붙이는&amp;rdquo; 수준을 넘어서야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring AI의 &lt;span&gt;ChatClient&lt;/span&gt;와 &lt;span&gt;PromptTemplate&lt;/span&gt;은 이를 구조화하고 반복 가능한 방식으로 프롬프트를 설계하는 데 유리한 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;구성 전략 1 &amp;ndash; 역할(Role)과 목표(Objective)를 명확히 명시하자&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;prolog&quot;&gt;&lt;code&gt;당신은 고객 문서 기반으로 질문에 정확히 답하는 AI 비서입니다.  
아래 제공된 문서를 기반으로만 답변해주세요.  
추측하지 말고, 문서에 명확히 존재하는 정보만 사용하세요.

[문서 내용]
{context}

[질문]
{question}

[답변]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM은 맥락과 역할, 제한사항을 명확히 설명할수록 더 안정적이고 일관된 응답을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;구성 전략 2 &amp;ndash; 문서들을 구조화된 형태로 삽입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 나열이 아닌, 각 문서를 명시적으로 구분하고, 출처 또는 제목을 붙여줍니다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;StringBuilder context = new StringBuilder();
int i = 1;
for (Document doc : topKDocuments) {
    context.append(&quot;문서 &quot;).append(i++).append(&quot;:\n&quot;);
    context.append(doc.getContent()).append(&quot;\n\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LLM의 입장에서는 구분점이 명확한 것이 문맥 해석에 훨씬 유리&lt;/b&gt;&lt;span&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;구성 전략 3 &amp;ndash; 템플릿화를 통해 프롬프트를 재사용 가능하게 만들기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring AI의 &lt;span&gt;PromptTemplate&lt;/span&gt;을 활용하면 다음처럼 설계할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;ceylon&quot;&gt;&lt;code&gt;PromptTemplate template = new PromptTemplate(&quot;&quot;&quot;
당신은 문서를 기반으로 질문에 정확히 답하는 AI입니다.

문서 목록:
{context}

사용자 질문:
{question}

문서를 참고하여 답변해주세요:
&quot;&quot;&quot;);
template.add(&quot;context&quot;, contextString);
template.add(&quot;question&quot;, userInput);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 방식은 &lt;/span&gt;&lt;b&gt;프롬프트를 쉽게 테스트하거나 튜닝할 수 있으며&lt;/b&gt;&lt;span&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유닛 테스트 또는 A/B 테스트 적용에도 매우 유리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;구성 전략 4 &amp;ndash; 문서 요약 후 삽입 (Intermediate Summarization)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서가 너무 길거나 많을 경우, &lt;span&gt;&lt;b&gt;각 문서를 간략히 요약한 뒤 요약만 넣는 전략&lt;/b&gt;&lt;/span&gt;이 유효합니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;for (Document doc : docs) {
    String summary = chatClient.call(&quot;다음 문서를 3줄로 요약해줘:\n&quot; + doc.getContent())
                          .getResult().getOutput().getContent();
    context.append(summary).append(&quot;\n---\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 하면 &lt;/span&gt;&lt;b&gt;보다 간결한 프롬프트로 모델의 집중도를 높이고, 토큰 소모도 줄일 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;구성 전략 5 &amp;ndash; JSON/표/포맷 지정 요청&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답의 포맷을 지정하는 것도 매우 효과적입니다.&lt;/p&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;답변은 다음과 같은 형식을 지켜주세요:

- 핵심 요약 (한 문장)
- 문서 내 근거 인용
- 표 형식 비교 (가능한 경우)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;답변은 반드시 JSON 형식으로 다음 구조를 따르세요:
{
  &quot;summary&quot;: &quot;...&quot;,
  &quot;source&quot;: &quot;...&quot;,
  &quot;reasoning&quot;: &quot;...&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 하면 &lt;/span&gt;&lt;b&gt;후처리 코드 작성도 쉬워지고, LLM이 혼동할 가능성도 줄어듭니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 예시: 프롬프트 통합 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;julia&quot;&gt;&lt;code&gt;String context = prepareContext(docs);
PromptTemplate promptTemplate = new PromptTemplate(&quot;&quot;&quot;
당신은 사내 지식 문서를 기반으로 질문에 답변하는 AI입니다.
다음은 참고할 문서들입니다:

{context}

사용자 질문:
{question}

문서를 참고하여 구체적으로 답변해주세요.
답변은 반드시 문서에서 근거를 찾은 경우에만 작성해주세요.
&quot;&quot;&quot;);

promptTemplate.add(&quot;context&quot;, context);
promptTemplate.add(&quot;question&quot;, userInput);

String answer = chatClient.call(promptTemplate.create())
                .getResult().getOutput().getContent();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전에서 자주 발생하는 문제와 개선 팁&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;b&gt;개선 방법&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;답변이 문서와 무관하거나 추측 기반임&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&amp;ldquo;문서에 기반한 정보만 사용&amp;rdquo; 강조, role 설정 강화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;너무 긴 문서로 인해 토큰 초과 발생&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;TextSplitter&lt;/span&gt;로 분할 &amp;rarr; 요약 &amp;rarr; 삽입&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;여러 문서에 대한 응답 정확도 저하&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;각 문서 요약 후 비교 요청 or 하나씩 비교하는 방식&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;응답 일관성 부족&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;응답 포맷 지정 (JSON, Markdown, List 등)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요약&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전략 요소&lt;/b&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Role 정의&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;모델의 역할, 제한 명확히 전달&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;문서 삽입 방식&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;구분된 청크 구조, 번호 부여&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;프롬프트 템플릿화&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;테스트와 반복 개선을 위한 기반&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;문서 요약 삽입&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;토큰 제한 대응, 응답 품질 향상&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;출력 포맷 요청&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;일관된 결과, 자동화/후처리 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기술과 산업/AI</category>
      <category>chatclient</category>
      <category>java</category>
      <category>LLM</category>
      <category>prompt-template</category>
      <category>rag</category>
      <category>spring-ai</category>
      <category>springboot</category>
      <category>vectorsearch</category>
      <category>문서기반응답</category>
      <category>프롬프트엔지니어링</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/508</guid>
      <comments>https://bcuts.tistory.com/508#entry508comment</comments>
      <pubDate>Wed, 13 Aug 2025 10:55:58 +0900</pubDate>
    </item>
    <item>
      <title>소프트웨어 아키텍처 시리즈 15화 &amp;ndash; Saga 패턴과 프로세스 오케스트레이션: 분산 트랜잭션을 다루는 전략</title>
      <link>https://bcuts.tistory.com/507</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;분산 환경에서 트랜잭션 일관성을 유지하기 위해 자주 사용되는 Saga 패턴을 분석합니다. 오케스트레이션과 코레오그래피의 차이, 설계 시 주의할 점을 실전 중심으로 설명합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;분산 환경의 트랜잭션 문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스나 이벤트 기반 시스템에서는 하나의 비즈니스 로직이 여러 서비스에 걸쳐 수행되는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 &lt;span&gt;&lt;b&gt;주문 처리&lt;/b&gt;&lt;/span&gt;를 생각해 봅시다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;주문 서비스 &amp;ndash; 주문 생성&lt;/li&gt;
&lt;li&gt;결제 서비스 &amp;ndash; 결제 승인&lt;/li&gt;
&lt;li&gt;재고 서비스 &amp;ndash; 재고 차감&lt;/li&gt;
&lt;li&gt;배송 서비스 &amp;ndash; 배송 요청&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 네 단계는 논리적으로 하나의 트랜잭션처럼 보이지만, 실제로는 &lt;span&gt;&lt;b&gt;서로 다른 시스템&lt;/b&gt;&lt;/span&gt;에서 독립적으로 처리됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 강한 일관성을 유지하려고 하면 분산 락&amp;middot;2PC(2 Phase Commit) 같은 복잡하고 성능 저하를 유발하는 방법이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 현실적인 대안으로 &lt;span&gt;&lt;b&gt;Saga 패턴&lt;/b&gt;&lt;/span&gt;이 등장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Saga 패턴이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Saga 패턴은 &lt;span&gt;&lt;b&gt;긴 트랜잭션을 여러 개의 로컬 트랜잭션으로 나누고&lt;/b&gt;&lt;/span&gt;, 각 단계 실패 시 &lt;span&gt;&lt;b&gt;보상 트랜잭션&lt;/b&gt;&lt;/span&gt;을 수행해 전체 프로세스를 논리적으로 일관성 있게 유지하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 로컬 트랜잭션은 자신의 데이터베이스에서만 커밋&lt;/li&gt;
&lt;li&gt;실패 시 이전 단계들을 취소하는 보상 액션 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Saga 패턴의 두 가지 접근 방식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 오케스트레이션 기반(Orchestration-based)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;**중앙 조정자(Orchestrator)**가 전체 흐름을 제어&lt;/li&gt;
&lt;li&gt;각 단계 서비스는 오케스트레이터의 명령에 따라 동작&lt;/li&gt;
&lt;li&gt;예: 주문 오케스트레이터가 결제 요청 &amp;rarr; 재고 차감 요청 &amp;rarr; 배송 요청 순서로 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;흐름이 명확하고 추적 쉬움&lt;/li&gt;
&lt;li&gt;장애 처리 로직 중앙 집중화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오케스트레이터가 병목&amp;middot;단일 장애점(SPOF) 될 가능성&lt;/li&gt;
&lt;li&gt;중앙 집중 구조로 유연성 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 코레오그래피 기반(Choreography-based)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중앙 조정자 없이 &lt;span&gt;&lt;b&gt;이벤트 기반&lt;/b&gt;&lt;/span&gt;으로 각 서비스가 다음 단계를 트리거&lt;/li&gt;
&lt;li&gt;예: 주문 생성 이벤트 &amp;rarr; 결제 서비스가 결제 &amp;rarr; 결제 완료 이벤트 &amp;rarr; 재고 서비스 차감&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중앙 집중 제어 없이 확장성 높음&lt;/li&gt;
&lt;li&gt;서비스 간 결합도 낮음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;흐름이 분산돼 가시성 낮음&lt;/li&gt;
&lt;li&gt;복잡한 비즈니스 로직에서 순서 제어 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 예시: 주문 처리 Saga (오케스트레이션 방식)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Order Orchestrator&lt;/b&gt;&lt;span&gt;: 주문 생성 &amp;rarr; 상태: &lt;/span&gt;&lt;span&gt;PENDING_PAYMENT&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Payment Service&lt;/b&gt;&lt;span&gt;: 결제 승인 &amp;rarr; 상태: &lt;/span&gt;&lt;span&gt;PAID&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Inventory Service&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 재고 차감 &amp;rarr; 상태: &lt;/span&gt;INVENTORY_CONFIRMED&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Shipping Service&lt;/b&gt;&lt;span&gt;: 배송 요청 &amp;rarr; 상태: &lt;/span&gt;&lt;span&gt;SHIPPED&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실패 시:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결제 실패 &amp;rarr; 주문 취소 이벤트 발행&lt;/li&gt;
&lt;li&gt;재고 부족 &amp;rarr; 결제 취소 요청 후 주문 취소&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;보상 트랜잭션 설계 팁&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;원래 작업의 반대 작업&lt;/b&gt;&lt;/span&gt;이어야 하지만 완벽한 역연산이 아닐 수 있음&lt;/li&gt;
&lt;li&gt;(예: 결제 취소, 재고 복원)&lt;/li&gt;
&lt;li&gt;보상 트랜잭션은 항상 &lt;span&gt;&lt;b&gt;멱등성&lt;/b&gt;&lt;/span&gt; 보장 필요&lt;/li&gt;
&lt;li&gt;보상 불가능한 작업(이메일 전송 등)은 별도 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Saga 패턴 적용 시 고려사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;오케스트레이션 vs. 코레오그래피 선택&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;흐름 단순&amp;middot;명확성이 중요 &amp;rarr; 오케스트레이션&lt;/li&gt;
&lt;li&gt;유연성과 서비스 자율성이 중요 &amp;rarr; 코레오그래피&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장애와 재시도 전략&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 단계에서 재시도와 타임아웃 설계&lt;/li&gt;
&lt;li&gt;재시도 시 멱등성 필수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모니터링과 가시성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산 트랜잭션 추적 시스템(예: OpenTelemetry, Zipkin) 필요&lt;/li&gt;
&lt;li&gt;Saga 상태 대시보드 구축&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;헥사고날 아키텍처와의 연결&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Saga 오케스트레이터는 Application Layer의 유즈케이스로 구현 가능&lt;/li&gt;
&lt;li&gt;각 단계 서비스는 자신의 Inbound Port를 통해 명령 수신&lt;/li&gt;
&lt;li&gt;Outbound Port로 다른 서비스 호출 또는 이벤트 발행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;일관성을 유지하는 &amp;lsquo;프로세스 설계&amp;rsquo;의 힘&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Saga 패턴은 단순히 트랜잭션 관리 기법이 아니라, &lt;/span&gt;&lt;b&gt;비즈니스 프로세스를 안정적으로 운영하기 위한 아키텍처적 설계 패턴&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스가 많아지고 데이터 경계가 복잡해질수록, Saga는 선택이 아니라 필수가 될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 보상 트랜잭션과 장애 처리 로직을 포함한 &lt;span&gt;&lt;b&gt;운영 전략&lt;/b&gt;&lt;/span&gt;까지 설계에 포함해야 진정한 효과를 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기술과 산업/아키텍처</category>
      <category>데이터일관성</category>
      <category>마이크로서비스</category>
      <category>보상트랜잭션</category>
      <category>분산트랜잭션</category>
      <category>비즈니스프로세스</category>
      <category>사가패턴</category>
      <category>오케스트레이션</category>
      <category>이벤트기반아키텍처</category>
      <category>코레오그래피</category>
      <category>헥사고날아키텍처</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/507</guid>
      <comments>https://bcuts.tistory.com/507#entry507comment</comments>
      <pubDate>Wed, 13 Aug 2025 10:54:53 +0900</pubDate>
    </item>
    <item>
      <title>제조 프로세스 이해 시리즈 23화 &amp;ndash; 식품 가공: 반조리, 조리식품 중심 배치 라인의 실제</title>
      <link>https://bcuts.tistory.com/506</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;냉동만두, 소스, 도시락, 즉석국밥&amp;hellip;. 우리가 마트나 편의점에서 쉽게 접하는 많은 식품들이 실제로는 복잡한 배치공정을 거쳐 만들어집니다. 이 산업은 대량 생산과 유연한 SKU 대응을 동시에 요구하며, 특히 위생, 유통기한, 품질 일관성이라는 조건을 만족해야 하기에 정형화된 연속공정보다는 배치공정이 더욱 적합한 구조로 작동합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 식품 가공 산업에서의 배치공정 흐름, 핵심 설비, 생산관리 시스템의 특징까지 차분히 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 식품 가공과 배치공정의 만남&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식품 가공 산업은 아래와 같은 특성으로 인해 배치공정 중심 구조를 채택하고 있습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;메뉴/제품 다양성&lt;/b&gt;&lt;/span&gt;: 반찬류, 탕류, 면류, 소스 등 제품 간 차이가 큼&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;소재 다양성과 계절성&lt;/b&gt;&lt;/span&gt;: 식자재 특성에 따라 공정 조건 다름&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;위생 및 세척 필요성&lt;/b&gt;&lt;/span&gt;: 공정 간 세척 필수 &amp;rarr; 연속 흐름 곤란&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;포장 단위 다양성&lt;/b&gt;&lt;/span&gt;: 낱개, 다인분, 리필팩 등 납품 대상별로 상이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식품 산업은 의약품만큼 규제가 강하진 않지만, &lt;span&gt;&lt;b&gt;HACCP, 식품위생법, 냉장/냉동 보관조건 등 물리적 제한 요소가 많아&lt;/b&gt;&lt;/span&gt;, 배치단위 공정 제어가 품질을 담보하는 주요 수단이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 전형적인 식품 가공 공정 흐름&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품군마다 차이는 있으나, 일반적인 조리식품 가공 공정은 다음과 같은 배치 단위 흐름으로 이루어집니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;원료 입고 및 선별&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;계량 및 전처리&lt;/b&gt;&lt;/span&gt; (세척, 절단 등)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;조리&lt;/b&gt;&lt;/span&gt; (끓이기, 볶기, 찌기 등 - 배치 반응)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;혼합/소스 투입&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;충진 및 냉각&lt;/b&gt;&lt;/span&gt; (예: 레토르트 팩 충진 후 냉각)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포장 및 밀봉&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이물 검출 및 금속 검출기 통과&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;라벨링 및 출하 적재&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  특히 조리공정은 &amp;lsquo;시간 + 온도 + 습도&amp;rsquo;라는 조건이 핵심 변수로 작용하며, &lt;span&gt;&lt;b&gt;중간 중간 세척과 위생 점검이 배치의 일부처럼 삽입&lt;/b&gt;&lt;/span&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 설비 구성과 제어 포인트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;핵심 설비&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;배합기(Mixer, Tumbler)&lt;/b&gt;&lt;span&gt;: 야채&amp;middot;고기 혼합&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가열탱크(Steam Kettle)&lt;/b&gt;&lt;span&gt;: 볶음, 끓임 공정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;레토르트(Autoclave)&lt;/b&gt;&lt;span&gt;: 고온 고압 살균&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;충진기/밀봉기&lt;/b&gt;&lt;/span&gt;: 용기/포장재에 정확한 양 투입&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;메탈 디텍터&lt;/b&gt;&lt;/span&gt;: 금속 이물 검출&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;중요 제어 항목&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;온도 유지 범위: 식중독균 사멸 온도 확보&lt;/li&gt;
&lt;li&gt;조리 시간 관리: 미/과조리 방지&lt;/li&gt;
&lt;li&gt;배합 순서: 양념의 분산 균일도 확보&lt;/li&gt;
&lt;li&gt;세척 공정 통제: 알레르겐 교차 오염 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 배치 단위 생산의 운영 전략&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식품 가공 산업에서 배치 단위 운영을 최적화하려면 다음과 같은 전략이 필요합니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;레시피 기반 공정 제어&lt;/b&gt;&lt;/span&gt;: 배치 마다 동일한 배합/시간 확보&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;이력 추적성 확보&lt;/b&gt;&lt;/span&gt;: 원재료, 배합, 가열, 충진 조건 기록&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;CIP 운영 최적화&lt;/b&gt;&lt;/span&gt;: 공정 간 세척시간 최소화&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;포장 및 라벨 관리&lt;/b&gt;&lt;/span&gt;: 유통기한, 알레르겐 정보 등 포함&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;검사 결과 연계&lt;/b&gt;&lt;/span&gt;: 품질검사 및 이탈 로트 식별&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  특히 혼합제품이나 도시락류의 경우, &lt;/span&gt;&lt;b&gt;각 구성요소가 서로 다른 배치에서 생산되어 조립되는 구조&lt;/b&gt;&lt;span&gt;이므로, &lt;/span&gt;&lt;b&gt;MES와 LIMS, WMS 간 통합 운영이 중요&lt;/b&gt;&lt;span&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. MES와 식품 가공의 연결 구조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식품 배치공정에서 MES는 다음과 같은 역할을 수행합니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;레시피 관리 시스템(RMS)&lt;/b&gt;과 통합&lt;/li&gt;
&lt;li&gt;&lt;b&gt;생산 로트 추적 및 불량 리콜 대응 구조 마련&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포장단위&amp;middot;제품코드 기준 설비 자동 세팅 지원&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;작업자 이력 및 세척 로깅 기능&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스케줄링 연동으로 공정 병목 완화&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에는 &lt;span&gt;&lt;b&gt;스마트 스케줄러, AI 기반 수율 개선, 이미지 검사 연동&lt;/b&gt;&lt;/span&gt; 등도 식품 MES에 도입되고 있어, 비교적 전통 산업이었던 식품 가공도 빠르게 디지털화되고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 주방 같지만 공장이고, 시스템이다&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식품 가공 산업은 얼핏 보면 &amp;lsquo;조리의 연장선&amp;rsquo; 같지만, 그 이면에는 &lt;span&gt;&lt;b&gt;정확한 온도 제어, 반복 가능한 배합, 규격화된 포장과 유통 흐름이 연결된 복잡한 시스템&lt;/b&gt;&lt;/span&gt;이 자리하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소량 다품종과 위생 조건, 유통기한까지 고려해야 하는 환경 속에서 배치공정은 가장 현실적인 전략이자 기본 프레임입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식품 제조는 곧 &amp;lsquo;조리의 과학화&amp;rsquo;, 그리고 &amp;lsquo;맛의 표준화&amp;rsquo; 과정이기도 합니다. 그 과정을 배치 기반으로 안정적으로 운영하는 것이야말로 이 산업의 경쟁력이라 할 수 있겠습니다.&lt;/p&gt;</description>
      <category>기술과 산업/도메인</category>
      <category>레토르트공정</category>
      <category>반조리식품</category>
      <category>배치공정</category>
      <category>식품MES</category>
      <category>식품가공</category>
      <category>식품제조설비</category>
      <category>알레르겐관리</category>
      <category>온도제어</category>
      <category>위생설비</category>
      <category>조리식품라인</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/506</guid>
      <comments>https://bcuts.tistory.com/506#entry506comment</comments>
      <pubDate>Tue, 12 Aug 2025 19:19:18 +0900</pubDate>
    </item>
    <item>
      <title>AI/ML 기반 데이터 분석 시리즈 14화 &amp;ndash; ML 학습을 위한 데이터셋 생성 자동화</title>
      <link>https://bcuts.tistory.com/505</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;좋아요. 이제 슬슬 본격적인 머신러닝 파이프라인 구축 이야기를 해볼 때가 됐죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번엔 &lt;/span&gt;&lt;b&gt;모델 학습에 필요한 &amp;lsquo;데이터셋을 자동으로 만드는 방법&amp;rsquo;&lt;/b&gt;&lt;span&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중에서도 실무에서 진짜 많이 쓰이는 방식들을 중심으로 이야기해보려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 분석을 하다 보면 이런 경험, 누구나 한 번쯤은 있을 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&amp;ldquo;전처리는 다 했는데, 모델 학습을 돌리려니 또 다른 데이터셋이 필요하네?&amp;rdquo;&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&amp;ldquo;매번 새로운 조건으로 학습 데이터를 다시 만들어야 해서 너무 번거로워&amp;hellip;&amp;rdquo;&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;&amp;ldquo;파이프라인이 중간에 꼬여서 지난주 결과랑 이번 주 결과가 아예 다르다는데요&amp;hellip;?&amp;rdquo;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 모델링은 생각보다 반복 작업이 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건 바뀔 때마다 데이터셋을 다시 만들고, 버전 관리하고, 중간 데이터 저장하고&amp;hellip;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그냥 돌려서 나오는 게 아니라, &lt;/span&gt;&lt;b&gt;학습에 맞는 구조로 데이터를 &amp;lsquo;꾸준히, 자동으로&amp;rsquo; 준비해주는 파이프라인&lt;/b&gt;&lt;span&gt;이 정말 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에선 바로 이 부분 &amp;mdash; &lt;span&gt;&lt;b&gt;ML 학습을 위한 데이터셋 생성 자동화 구조&lt;/b&gt;&lt;/span&gt;에 대해 이야기해볼게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;왜 &amp;lsquo;자동화된 학습 데이터셋 생성&amp;rsquo;이 중요한가요?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 분석이 어느 정도 궤도에 오르면, 학습을 반복적으로 돌리는 일이 많아져요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A/B 테스트, 기간 조건 변경, 새로운 파생 피처 추가 등.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때마다 사람이 손으로 데이터를 짜 맞추다 보면&amp;hellip;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;버전이 꼬이고&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실험 결과 재현이 안 되고&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중복 작업이 늘고&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모델 성능 비교가 애매해지고&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무엇보다 분석가의 시간이 새어 나갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 실무에선 다음과 같은 &amp;lsquo;요구&amp;rsquo;들이 자연스럽게 생겨요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 조건에 맞는 데이터를 매번 손 안 대고 자동으로 만들어줘&lt;/li&gt;
&lt;li&gt;학습 데이터는 항상 같은 기준에서 만들어져야 해&lt;/li&gt;
&lt;li&gt;중간 결과도 캐싱해두고 재사용 가능하게 해줘&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 해결하는 방법이 바로 &lt;span&gt;&lt;b&gt;학습용 데이터셋 생성 자동화&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;자동화 파이프라인, 어떻게 구성하면 좋을까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통은 이렇게 단계적으로 나눠요:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;원천 데이터 불러오기&lt;/b&gt;&lt;/span&gt; (SQL, CSV, API 등)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;필요한 행/열 필터링&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전처리 (결측값 처리, 타입 변환 등)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;피처 엔지니어링 (날짜 분해, 파생 변수 생성 등)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타겟(라벨) 정의 및 조합&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최종 데이터셋 저장 (CSV, feather, parquet 등)&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 단순 스크립트로 짜도 되지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수형으로 짜고 config로 관리하거나, 데이터 파이프라인 툴을 쓰는 게 유지보수에 훨씬 좋아요.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;예시: Python + Config 기반 자동화 구성&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# settings.yaml
filter:
  start_date: &quot;2023-01-01&quot;
  end_date: &quot;2023-12-31&quot;
target:
  type: &quot;binary&quot;
  condition: &quot;purchase_count &amp;gt; 0&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# generate_dataset.py
def load_data():
    return pd.read_csv(&quot;raw_data.csv&quot;)

def apply_filter(df, config):
    return df[(df[&quot;date&quot;] &amp;gt;= config[&quot;start_date&quot;]) &amp;amp; (df[&quot;date&quot;] &amp;lt;= config[&quot;end_date&quot;])]

def create_target(df, config):
    df[&quot;target&quot;] = df[&quot;purchase_count&quot;] &amp;gt; 0 if config[&quot;type&quot;] == &quot;binary&quot; else df[&quot;purchase_count&quot;]
    return df

def build_dataset(config_path):
    config = yaml.safe_load(open(config_path))
    df = load_data()
    df = apply_filter(df, config[&quot;filter&quot;])
    df = create_target(df, config[&quot;target&quot;])
    df.to_parquet(&quot;training_data.parquet&quot;)

build_dataset(&quot;settings.yaml&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구성하면, 날짜나 조건만 바꿔서 여러 실험을 자동으로 돌릴 수 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 재현성도 확보되고, 팀 협업도 쉬워지고요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;대용량 데이터라면? Dask / Polars / PySpark 활용도 고려해보자&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 커질수록 pandas는 힘들어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 땐 &lt;span&gt;&lt;b&gt;Dask&lt;/b&gt;&lt;/span&gt;나 &lt;span&gt;&lt;b&gt;Polars&lt;/b&gt;&lt;/span&gt;, 또는 분산 처리가 가능한 &lt;span&gt;&lt;b&gt;PySpark&lt;/b&gt;&lt;/span&gt; 쪽으로 넘어가야 해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Dask 예시&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;import dask.dataframe as dd

df = dd.read_csv(&quot;big_data.csv&quot;)
df_filtered = df[df['date'] &amp;gt; '2023-01-01']
df_filtered.to_parquet(&quot;filtered_data.parquet&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Polars 예시 (속도 빠름)&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;import polars as pl

df = pl.read_csv(&quot;big_data.csv&quot;)
df = df.filter(pl.col(&quot;amount&quot;) &amp;gt; 0)
df.write_parquet(&quot;dataset.parquet&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ML 실험 주기, 어떻게 관리할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터셋을 자동으로 만드는 건 기본이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에는 다음 같은 것도 고려하면 좋아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;학습용 데이터셋의 &lt;span&gt;&lt;b&gt;버전 관리&lt;/b&gt;&lt;/span&gt; (날짜 기반, hash 기반 등)&lt;/li&gt;
&lt;li&gt;실험 결과(accuracy, auc, f1 등)를 &lt;span&gt;&lt;b&gt;로그로 저장&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;실험 환경(하이퍼파라미터 등)을 &lt;span&gt;&lt;b&gt;yaml / json으로 기록&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;모델 + 데이터셋 매칭 정보 저장 (MLflow 등 활용 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 구조가 갖춰지면 분석이 훨씬 &amp;lsquo;공학적으로&amp;rsquo; 정리됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마무리하며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 머신러닝 모델보다 더 중요한 건 &lt;span&gt;&lt;b&gt;&amp;lsquo;데이터&amp;rsquo;&lt;/b&gt;&lt;/span&gt; 그 자체라는 말, 많이 들으셨을 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 데이터를 &lt;/span&gt;&lt;b&gt;지속적으로 만들고 다듬고, 같은 기준으로 학습시키고 실험을 반복할 수 있도록 자동화하는 구조&lt;/b&gt;&lt;span&gt;가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 퀄리티를 완전히 바꿔놓습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석가 혼자만 알 수 있는 코드가 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 사람도 보고 이해할 수 있고, 조건만 바꾸면 반복 학습도 가능한 구조.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그게 바로 실무에서 말하는 &amp;ldquo;자동화된 데이터셋 생성&amp;rdquo;의 진짜 가치입니다.&lt;/p&gt;</description>
      <category>기술과 산업/AI</category>
      <category>dask</category>
      <category>ML실험관리</category>
      <category>ML자동화</category>
      <category>pandas</category>
      <category>polars</category>
      <category>yaml구성</category>
      <category>데이터셋자동화</category>
      <category>데이터엔지니어링</category>
      <category>데이터파이프라인</category>
      <category>머신러닝전처리</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/505</guid>
      <comments>https://bcuts.tistory.com/505#entry505comment</comments>
      <pubDate>Thu, 7 Aug 2025 18:00:30 +0900</pubDate>
    </item>
    <item>
      <title>제조 프로세스 이해 시리즈 22화 &amp;ndash; 화장품 제조: 소량 다품종 배치공정의 정석</title>
      <link>https://bcuts.tistory.com/504</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;화장품 공장은 우리가 생각하는 것보다 훨씬 복잡한 흐름을 가지고 있습니다. 겉보기에는 부드럽고 감각적인 제품이지만, 그 안에는 정밀한 배합, 반복 가능한 품질, 유통기한까지 고려된 체계적인 제조 시스템이 작동하고 있죠. 이번 화에서는 화장품 제조가 왜 전형적인 &amp;lsquo;소량 다품종 배치공정&amp;rsquo;인지, 그리고 이 배치공정이 어떤 특징과 도전과제를 가지고 있는지 구체적으로 들여다보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 왜 화장품은 배치공정으로 생산되는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장품은 다음과 같은 특성 때문에 배치 기반 생산이 중심입니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;다품종 소량 생산 구조&lt;/b&gt;&lt;/span&gt;: 계절 한정, 컬러별/피부타입별 제품 등&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;고빈도 SKU 변경&lt;/b&gt;&lt;/span&gt;: 라벨, 향, 색상, 제형 등 세부 변형 많음&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;레시피 기반 제조&lt;/b&gt;&lt;/span&gt;: 원료 혼합 비율과 순서가 핵심&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;높은 유연성 필요&lt;/b&gt;&lt;/span&gt;: 생산라인 전환 빈번 &amp;rarr; 연속공정 부적합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 화장품은 &amp;lsquo;공정 조건이 바뀌어도 일관된 품질을 보장&amp;rsquo;해야 하기 때문에, &lt;span&gt;&lt;b&gt;공정별로 명확한 단위가 있는 배치 시스템&lt;/b&gt;&lt;/span&gt;이 자연스럽게 도입된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 화장품 제조의 전형적 공정 흐름&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장품은 크게 &amp;lsquo;내용물(포뮬러) 제조&amp;rsquo;와 &amp;lsquo;충진 및 포장&amp;rsquo; 두 영역으로 나뉩니다. 아래는 일반적인 공정 흐름 예시입니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[1] 내용물 제조 (배합 및 안정화)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;원료 계량 및 저장&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;믹싱 (혼합 및 유화)&lt;/b&gt;&lt;/span&gt; &amp;ndash; 온도, 순서, 속도 제어 필수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;진공 탈포 / 균질화 (Homogenizing)&lt;/b&gt;&lt;span&gt; &amp;ndash; 입자 분산 및 안정화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;저장 / 숙성 (Maturation)&lt;/b&gt;&lt;span&gt; &amp;ndash; pH 안정화 및 품질 체크&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[2] 충진 및 포장 (Fill &amp;amp; Pack)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;충진 (Filling)&lt;/b&gt;&lt;/span&gt; &amp;ndash; 용기별 정확한 충전량 조절&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캡핑 / 실링 (Sealing)&lt;/b&gt;&lt;span&gt; &amp;ndash; 외부 오염 방지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;라벨링 / 박스 포장&lt;/b&gt;&lt;/span&gt; &amp;ndash; 제품정보 부착 및 박싱&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출하 전 검사 및 샘플 보관&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  공정 간에는 &amp;lsquo;청소(Cleaning)&amp;rsquo; 절차가 반복되며, 이는 배치 사이클의 일환으로 간주됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 주요 설비와 제어 요건&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장품 배치공정은 조용하지만 까다로운 제어 요건이 많습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대표 설비&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;믹서(Mixer)&lt;/b&gt;&lt;/span&gt;: 가열/냉각 겸용, 교반 속도 제어 가능해야 함&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;균질기(Homogenizer)&lt;/b&gt;&lt;/span&gt;: 미립자 분산, 유화 품질 좌우&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;충진기(Filler)&lt;/b&gt;&lt;/span&gt;: 고점도/저점도 모두 대응 가능해야 함&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;CIP 장비&lt;/b&gt;&lt;/span&gt;: Clean-In-Place 자동 세척 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제어 포인트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;온도: 섭씨 &amp;plusmn;1도 단위로 민감함&lt;/li&gt;
&lt;li&gt;점도: 고형분 비율, 사용감 결정&lt;/li&gt;
&lt;li&gt;교반 시간: 입자 크기와 안정성에 영향&lt;/li&gt;
&lt;li&gt;위생 조건: 장비 재질, 세척 주기 등 품질과 직결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 배치공정으로서의 특징과 도전 과제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장품 생산의 배치공정은 다음과 같은 점에서 매우 도전적입니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;배치 간 조건 차이 최소화&lt;/b&gt;&lt;/span&gt;: 생산 조건 일관성 유지가 관건&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;SKU 변경 대응&lt;/b&gt;&lt;/span&gt;: 빠른 생산 전환과 세척 &amp;rarr; 다운타임 최소화 요구&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;레시피 관리&lt;/b&gt;&lt;/span&gt;: 각 배합 기준이 조정 가능하고 추적 가능해야 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소량 파일럿 생산과 대량 생산의 스케일 차이 극복&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;산업공학적으로 보면, 이 산업은 &lt;/span&gt;&lt;b&gt;설비유휴율, 세척시간, 납기압박, 유통기한 등 다양한 제약을 동시에 고려해야 하는 고난도 운영 구조&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. MES와 레시피 기반 생산관리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장품 공장에서 MES는 단순 실적 입력이 아니라 &amp;lsquo;레시피 중심 운영 시스템&amp;rsquo; 역할을 수행합니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;배치 레시피 관리&lt;/b&gt;&lt;/span&gt;: 조성비, 순서, 공정시간 등 기준화&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;공정 이벤트 추적&lt;/b&gt;&lt;/span&gt;: 온도 초과, 시간 지연 등 이탈 기록&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;이력 관리&lt;/b&gt;&lt;/span&gt;: 어떤 로트로 무엇을 만들었는지 추적 가능&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;포장단위/로트 관리&lt;/b&gt;&lt;/span&gt;: SKU별 패킹구조 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MES는 보통 WMS(창고관리), LIMS(시험분석), ERP(자재)와 연결되어 있으며, 최근에는 &lt;span&gt;&lt;b&gt;AI 기반 수요예측과 연계한 생산량 최적화&lt;/b&gt;&lt;/span&gt;도 적용되고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 감성 산업 뒤에 숨은 정교한 배치 전략&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장품은 감성과 감각의 산업입니다. 하지만 그 안의 제조 시스템은 &lt;span&gt;&lt;b&gt;과학, 공정, 품질보증이 유기적으로 연결된 정밀한 체계&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소량 다품종의 복잡한 SKU, 높은 품질 기준, 짧은 납기, 유연한 설비 운영이 요구되는 이 산업에서 배치공정은 단지 선택이 아닌 &amp;lsquo;운영을 지탱하는 구조&amp;rsquo;로 작동하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품 하나하나가 설비 흐름과 레시피, 품질검사의 결과라는 점에서, 화장품 공정은 배치공정의 정수를 보여주는 산업이라고 해도 과언이 아닙니다.&lt;/p&gt;</description>
      <category>기술과 산업/도메인</category>
      <category>공정추적성</category>
      <category>균질화공정</category>
      <category>레시피관리</category>
      <category>배치공정</category>
      <category>배합제어</category>
      <category>소량다품종</category>
      <category>점도관리</category>
      <category>충진라인</category>
      <category>화장품MES</category>
      <category>화장품제조</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/504</guid>
      <comments>https://bcuts.tistory.com/504#entry504comment</comments>
      <pubDate>Thu, 7 Aug 2025 16:48:04 +0900</pubDate>
    </item>
    <item>
      <title>제조 프로세스 이해 시리즈 21화 &amp;ndash; 의약품 생산: 배치 기반 정제와 조제 프로세스의 본질</title>
      <link>https://bcuts.tistory.com/503</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;의약품 제조는 배치(Batch) 공정의 전형이라 할 수 있습니다. 사람의 생명과 직접 연결되는 만큼 &lt;span&gt;&lt;b&gt;정확성, 반복성, 이력 추적성&lt;/b&gt;&lt;/span&gt;이 그 무엇보다 중요하며, 따라서 고도로 규제된 환경 안에서 이루어지는 구조적 생산 체계를 갖추고 있습니다. 이번 글에서는 의약품 배치 생산의 기본 흐름과 설비 구조, 배치공정 특유의 제어 방식, 그리고 GMP와 같은 규제 시스템이 어떻게 공정과 연결되어 있는지를 산업공학적 관점에서 풀어봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 왜 의약품은 배치공정을 택하는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의약품 제조에서 배치공정이 기본이 되는 이유는 다음과 같습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;규제 요건(GMP, GxP 등)&lt;/b&gt;&lt;/span&gt;: 모든 생산 이력과 조건이 재현 가능해야 함&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;소량 고가 제품 구조&lt;/b&gt;&lt;/span&gt;: 대량 연속 생산보다 적정 규모 배치 생산이 효율적&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;혼합&amp;middot;반응 기반 생산&lt;/b&gt;&lt;/span&gt;: 정량의 원료 혼합과 정제, 건조, 코팅 등 시간/조건 제어 필요&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;품질검사 통과 후 포장 가능&lt;/b&gt;&lt;/span&gt;: 실시간 연속 흐름보다 샘플 기반 품질 확인 후 이송 구조가 일반적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배치공정은 &amp;lsquo;한 번에 일정량&amp;rsquo;의 작업을 순차적으로 처리하므로, &lt;span&gt;&lt;b&gt;제품별 특성에 맞춘 유연한 조건 설정과 품질 확보에 유리&lt;/b&gt;&lt;/span&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 의약품 배치 생산의 대표 공정 흐름&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의약품은 원료 의약품(API)과 완제 의약품(Final Drug Product) 생산으로 나뉘며, 각각 다음과 같은 단계로 구성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[1] API 생산 공정 (원료의약품)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;원료 계량&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;반응&lt;/b&gt;&lt;/span&gt; (화학적 합성 or 생물학적 발효)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정제/여과&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;농축/결정화&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;건조/분쇄&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포장 및 라벨링 (비의약 포장)&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[2] 완제 의약품 생산 공정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;계량 및 혼합 (Blend)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;과립화 (Granulation)&lt;/b&gt;&lt;span&gt;: 습식 or 건식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;건조 (Drying)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정제 압축 (Tableting)&lt;/b&gt;&lt;span&gt; 또는 캡슐 충진&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코팅 (Coating)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;포장 (Blister, 병 포장)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이력 등록 및 출하 승인&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공정 중 각 단계는 &lt;span&gt;&lt;b&gt;명확한 배치 단위&lt;/b&gt;&lt;/span&gt;로 관리되며, &lt;span&gt;&lt;b&gt;Batch No. 기준의 이력관리&lt;/b&gt;&lt;/span&gt;가 철저하게 수행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 주요 설비와 배치 제어 구조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[A] 핵심 설비 예시&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;믹서(Mixer)&lt;/b&gt;&lt;span&gt;: 원료 혼합&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;반응기(Reactor)&lt;/b&gt;&lt;span&gt;: 합성, 정제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;건조기(Dryer)&lt;/b&gt;&lt;span&gt;: 수분 제거&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타정기(Tablet Press)&lt;/b&gt;&lt;span&gt;: 정제 성형&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코팅기(Coating Machine)&lt;/b&gt;&lt;span&gt;: 피막 형성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;충진기(Filler)&lt;/b&gt;&lt;/span&gt;: 액상 or 분말 주입&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;[B] 배치 제어 구조&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의약품 산업에서 주로 사용하는 배치 제어는 &lt;span&gt;&lt;b&gt;ISA-88 표준&lt;/b&gt;&lt;/span&gt;에 기반한 구조입니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Procedure Module&lt;/b&gt;&lt;span&gt;: 전체 공정 단계 정의&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Unit Procedure&lt;/b&gt;&lt;/span&gt;: 설비 단위 작업 정의 (예: &amp;ldquo;정제 혼합&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Control Module&lt;/b&gt;&lt;/span&gt;: 밸브, 펌프 등 하위 제어 장치 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  배치 제어 시스템은 DCS나 Batch MES와 통합되어 있고, 공정마다 &lt;span&gt;&lt;b&gt;스텝별 승인, 확인, 이탈 기준&lt;/b&gt;&lt;/span&gt;이 내장되어 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. GMP, GxP와 공정의 연결 구조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의약품 제조는 단순한 기술이 아니라, &lt;span&gt;&lt;b&gt;규제 프레임워크 속의 기술 활동&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주요 규제 요소&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;GMP (Good Manufacturing Practice)&lt;/b&gt;&lt;span&gt;: 제조&amp;middot;품질관리 기준&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;GxP&lt;/b&gt;&lt;/span&gt;: FDA에서 사용하는 포괄 개념 (GMP, GLP, GCP 포함)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;eBR (전자 배치기록)&lt;/b&gt;&lt;span&gt;, &lt;/span&gt;&lt;b&gt;Audit Trail&lt;/b&gt;&lt;span&gt; 필수&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 규제는 다음과 같은 공정 및 시스템에 반영됩니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;작업지시서 기반 수행&lt;/b&gt;&lt;/span&gt; + 실시간 기록 시스템(eBR)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이상 발생 시 Deviations 기록&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;릴리스 전 QA 승인 절차&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전자 서명, 사용자 권한, 접근 로그 철저 관리&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  즉, &lt;/span&gt;&lt;b&gt;GMP는 품질 시스템이 아닌, 공정 시스템의 일부로 작동해야&lt;/b&gt;&lt;span&gt; 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 배치 MES의 핵심 구성 요소&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의약품 제조에 특화된 배치 MES는 다음 기능을 중심으로 설계됩니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전자 배치 기록(eBR)&lt;/b&gt;&lt;span&gt; 기능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;작업 순서 제어(SOP 기반 워크플로우)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Batch Execution &amp;amp; Exception Handling 기능&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실시간 품질 조건 수집 (온도, 압력, 시간 등)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이탈관리(Deviation Tracking)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이력조회(Traceability) + 릴리스 승인 절차 통합&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 MES는 LIMS, ERP, SCADA 등과 통합되며, &lt;span&gt;&lt;b&gt;품질과 생산의 연결 고리&lt;/b&gt;&lt;/span&gt; 역할을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 공정, 품질, 규제를 잇는 구조가 핵심이다&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의약품 생산은 단순히 배치 단위로 생산하는 것이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배치라는 구조를 통해, 규제 요건을 충족시키면서도 반복 가능하고, 이력 관리가 가능한 공정을 구축하는 것&lt;/b&gt;&lt;span&gt;이 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;산업공학적으로 보면 이는 &amp;lsquo;표준화된 흐름을 품질로 연결하는&amp;rsquo; 구조이며, 그 기반에는 GMP, 배치제어, MES, eBR이 함께 작동하고 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배치 기반의 조제/정제 공정은 제조 방식 그 자체가 &amp;lsquo;신뢰를 구축하는 메커니즘&amp;rsquo;임을 이해할 필요가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기술과 산업/도메인</category>
      <category>EBR</category>
      <category>GMP</category>
      <category>ISA88</category>
      <category>배치공정</category>
      <category>배치제어</category>
      <category>의약품생산</category>
      <category>의약품제조</category>
      <category>제약MES</category>
      <category>제약공정</category>
      <category>품질이력관리</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/503</guid>
      <comments>https://bcuts.tistory.com/503#entry503comment</comments>
      <pubDate>Tue, 5 Aug 2025 12:11:36 +0900</pubDate>
    </item>
    <item>
      <title>제조 프로세스 이해 시리즈 20화 &amp;ndash; 공정 흐름 기반 대시보드 설계 전략: 제조 KPI 시각화의 실전 구조</title>
      <link>https://bcuts.tistory.com/502</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;스마트팩토리는 데이터를 모으는 것으로 끝나지 않습니다. 그 데이터를 &lt;span&gt;&lt;b&gt;어떻게 해석하고, 누구에게 어떤 방식으로 보여주느냐&lt;/b&gt;&lt;/span&gt;가 실질적인 성과로 이어집니다. 이번 20화에서는 제조 공정의 흐름을 시각화하는 대시보드 설계 전략을 중심으로, KPI 기반 시각화, 운영 현장과의 연결성, 사용자 맞춤형 인터페이스 구성 방법 등을 통합적으로 다룹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 제조 대시보드의 진화: 보고서에서 운영도구로&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적으로 제조 대시보드는 단순한 모니터링, 정기 리포트 수준이었습니다. 그러나 스마트팩토리 환경에선 다음과 같은 기능으로 진화하고 있습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실시간 이벤트 기반 반응&lt;/li&gt;
&lt;li&gt;현장 오퍼레이터 중심 인터페이스 구성&lt;/li&gt;
&lt;li&gt;KPI 간 상호관계 연동 및 원인 분석 기능 탑재&lt;/li&gt;
&lt;li&gt;AI 기반 예측/알림 연계&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, &lt;/span&gt;&lt;b&gt;대시보드는 단순 시각화가 아닌 &amp;lsquo;의사결정 시스템&amp;rsquo;으로 전환되고 있는 중&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 공정 흐름 기반 대시보드란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 제조 대시보드는 KPI 나열형으로 설계됩니다. 예: OEE, Takt Time, NG률, MTTR 등. 하지만 이것만으론 공정의 &amp;lsquo;흐름&amp;rsquo;을 파악하기 어렵습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;흐름 기반 대시보드 특징:&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;공정 순서에 따라 시각화 구조 배치&lt;/b&gt;&lt;span&gt; (라인 맵 기반)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;단계 간 연계 지표 구성&lt;/b&gt;&lt;/span&gt; (예: 공정 A 이상 &amp;rarr; 공정 B 납기 영향)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;알림/경고 발생시 흐름 변화 강조&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 사용자는 단일 KPI가 아닌, &lt;span&gt;&lt;b&gt;프로세스 상 흐름 구조로 문제를 인식&lt;/b&gt;&lt;/span&gt;하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 핵심 KPI 설계 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공정 흐름 대시보드의 KPI는 단순 수치 나열이 아닌, &lt;span&gt;&lt;b&gt;행동 유도형 구조&lt;/b&gt;&lt;/span&gt;로 설계되어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;설계 기준:&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;측정 목적 명확화&lt;/b&gt;&lt;/span&gt; (단순 확인 vs 개선 유도)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;시간 기준 설정&lt;/b&gt;&lt;/span&gt; (Shift, Batch, Day 등)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;역할별 KPI 정의&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업자: 실적, Takt Time, 불량 경고&lt;/li&gt;
&lt;li&gt;관리자: 설비 가동률, 라인 수율, 병목 공정&lt;/li&gt;
&lt;li&gt;경영진: 공장 전반 OEE, 납기율, 재작업 비용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이벤트 기반 KPI 표시&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변화 발생 시점에 색상/경고 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 대시보드 구조 설계 사례&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) 레이아웃 중심 &amp;ndash; 공정 맵 방식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공정 흐름도 형태로 배치&lt;/li&gt;
&lt;li&gt;각 공정에 실시간 KPI 삽입&lt;/li&gt;
&lt;li&gt;흐름 중단 시 경고 흐름 애니메이션 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2) 역할 중심 &amp;ndash; 사용자별 맞춤 뷰&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오퍼레이터: 간단/즉각적 인터페이스, 모바일 우선 설계&lt;/li&gt;
&lt;li&gt;엔지니어: Drill-down 기능, 세부 공정 분석&lt;/li&gt;
&lt;li&gt;관리자: 종합 KPI 요약 + 현장 지표 비교&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3) AI 연동 &amp;ndash; 예측 기반 강조 뷰&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;품질 예측 결과 강조 영역&lt;/li&gt;
&lt;li&gt;예지보전 스코어와 설비 OEE 연결&lt;/li&gt;
&lt;li&gt;재작업 위험 공정 강조 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 주요 도입 플랫폼과 연동 전략&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제조 대시보드 구축 시 주요 연동 대상:&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;MES&lt;/b&gt;&lt;/span&gt;: 실적, 공정 이력, 생산 이벤트&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;SCADA/IoT&lt;/b&gt;&lt;/span&gt;: 설비 상태, 센서 값, 알람&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;ERP&lt;/b&gt;&lt;/span&gt;: 납기, 주문 정보, 원가 분석&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AI 플랫폼&lt;/b&gt;&lt;/span&gt;: 예측 결과, 이상탐지 결과&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기술 구성 요소:&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Frontend: React, Angular, Vue 기반 대시보드 툴&lt;/li&gt;
&lt;li&gt;Backend: TimescaleDB, InfluxDB, Kafka, REST API&lt;/li&gt;
&lt;li&gt;통신: OPC-UA, MQTT 기반 실시간 스트림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;대시보드는 &amp;lsquo;디지털 운영의 창&amp;rsquo;이다&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트팩토리 성공의 핵심은 &amp;lsquo;데이터 &amp;rarr; 인사이트 &amp;rarr; 행동&amp;rsquo;의 루프를 만드는 것입니다. 그 중심에 대시보드가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;공정 흐름 기반으로 구성된 대시보드는 단순 모니터링을 넘어 &lt;/span&gt;&lt;b&gt;문제의 위치와 원인을 빠르게 인식하고 행동하게 만드는 실시간 운영 도구&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 대시보드에는 전략이 필요합니다. KPI가 있고, 사용자 맥락이 있고, 흐름의 구조가 있어야 합니다. 그럴 때만이 제조 데이터는 &lt;span&gt;&lt;b&gt;성과로 이어지는 실행력&lt;/b&gt;&lt;/span&gt;을 갖게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기술과 산업/도메인</category>
      <category>KPI시각화</category>
      <category>mes연동</category>
      <category>공정흐름시각화</category>
      <category>스마트제조UX</category>
      <category>스마트팩토리UI</category>
      <category>실시간운영</category>
      <category>예측기반운영</category>
      <category>이벤트기반대시보드</category>
      <category>제조kpi</category>
      <category>제조대시보드</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/502</guid>
      <comments>https://bcuts.tistory.com/502#entry502comment</comments>
      <pubDate>Wed, 30 Jul 2025 10:07:13 +0900</pubDate>
    </item>
    <item>
      <title>Spring AI 시리즈 10화 &amp;ndash; OpenSearch Vector Search 연동 전략</title>
      <link>https://bcuts.tistory.com/501</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;기존 Elasticsearch/OpenSearch 인프라를 기반으로 RAG 시스템을 구축하려면 벡터 검색 기능과 LLM 연동 전략이 필요합니다. 본 글에서는 Spring AI 환경에서 OpenSearch를 활용한 Vector Search 통합 방법과 설계 전략을 정리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 OpenSearch 벡터 검색인가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 기업에서 이미 Elasticsearch 또는 OpenSearch를 &lt;span&gt;&lt;b&gt;로그, 검색, 운영 데이터 저장소&lt;/b&gt;&lt;/span&gt;로 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 환경에 새로 LLM 기반 RAG 시스템을 도입할 때 가장 이상적인 방법은 기존 인프라를 그대로 활용하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearch는 최근 버전부터 &lt;span&gt;&lt;b&gt;Dense Vector Field와 k-NN 검색 기능&lt;/b&gt;&lt;/span&gt;을 공식 지원하고 있으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring 애플리케이션에서 바로 연동할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring AI는 공식적으로 OpenSearch VectorStore를 아직 제공하지 않지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearch의 벡터 검색 API를 직접 연동하는 전략으로 충분히 실전 적용이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OpenSearch에서 벡터 검색을 가능하게 하는 구성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Dense Vector Field 정의&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearch의 인덱스 스키마(mapping)에서 &lt;span&gt;dense_vector&lt;/span&gt; 타입을 정의합니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;mappings&quot;: {
    &quot;properties&quot;: {
      &quot;text&quot;: { &quot;type&quot;: &quot;text&quot; },
      &quot;embedding&quot;: {
        &quot;type&quot;: &quot;dense_vector&quot;,
        &quot;dims&quot;: 1536,
        &quot;index&quot;: true,
        &quot;similarity&quot;: &quot;cosine&quot;
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;dims&lt;/span&gt;: 사용 중인 임베딩 모델 차원 수 (예: OpenAI는 1536)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;similarity&lt;/span&gt;: cosine, l2_norm 등 설정 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 데이터 삽입 (벡터 포함)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring 애플리케이션에서 문서 내용을 임베딩한 뒤, OpenSearch에 벡터와 함께 저장합니다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;Map&amp;lt;String, Object&amp;gt; json = new HashMap&amp;lt;&amp;gt;();
json.put(&quot;text&quot;, &quot;문서 내용...&quot;);
json.put(&quot;embedding&quot;, embeddingClient.embed(&quot;문서 내용...&quot;));

IndexRequest request = new IndexRequest(&quot;my-docs&quot;)
        .id(UUID.randomUUID().toString())
        .source(json);
client.index(request, RequestOptions.DEFAULT);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;embeddingClient&lt;/span&gt;는 Spring AI에서 제공하는 임베딩 추상화&lt;/li&gt;
&lt;li&gt;OpenAI, HuggingFace, Cohere 등으로 교체 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 벡터 기반 유사도 검색 쿼리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearch는 &lt;span&gt;knn_vector&lt;/span&gt; 검색 API를 제공합니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;size&quot;: 3,
  &quot;query&quot;: {
    &quot;knn&quot;: {
      &quot;embedding&quot;: {
        &quot;vector&quot;: [/* 쿼리 임베딩 */],
        &quot;k&quot;: 3
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서 호출 시:&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders
    .knnQuery(&quot;embedding&quot;, queryEmbedding)
    .k(3));

SearchRequest searchRequest = new SearchRequest(&quot;my-docs&quot;);
searchRequest.source(builder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Spring AI 기반 RAG 구조와 OpenSearch 통합&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 OpenSearch를 VectorStore로 활용할 때의 전체 흐름입니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;문서 등록 시&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;텍스트 &amp;rarr; 임베딩 &amp;rarr; OpenSearch 인덱싱 (&lt;span&gt;text&lt;/span&gt; + &lt;span&gt;embedding&lt;/span&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용자 질문 처리 시&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;질문 &amp;rarr; 임베딩&lt;/li&gt;
&lt;li&gt;OpenSearch에서 유사 문서 검색 (&lt;span&gt;knnQuery&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;&lt;span&gt;검색 결과 &amp;rarr; Prompt 구성 &amp;rarr; &lt;/span&gt;ChatClient.call(prompt)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 Spring AI가 제공하는 &lt;span&gt;EmbeddingClient&lt;/span&gt;, &lt;span&gt;ChatClient&lt;/span&gt;는 그대로 사용하면서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VectorStore만 OpenSearch로 커스텀 구성하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 이 전략이 유리한가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;기존 인프라 활용&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Elastic/OpenSearch를 이미 사용 중이라면 별도 벡터 DB 도입 없이 통합 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;대규모 문서 처리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Shard/Replica 구조로 수십만~수백만 문서까지 확장 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;메타 쿼리 통합&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;벡터 유사도 + 속성 기반 필터 쿼리 혼합 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;운영 용이성&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;모니터링, 보안, 백업 등 기존 툴 그대로 활용 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 시 고려할 전략&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전략&lt;/b&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;hybrid score 구성&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;벡터 유사도 점수 + keyword 점수 혼합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;chunk 단위 저장&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;문서를 청크로 분할해 개별 벡터 저장 후 검색 시 병합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;필터 쿼리와 결합&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;예: 특정 날짜, 카테고리 필터 후 벡터 검색 적용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;multi-index 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;컬렉션/도메인별 인덱스를 분리하여 다중 조회 구현&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;확장 방향&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Kibana와 통합하여 벡터 검색 시각화&lt;/li&gt;
&lt;li&gt;vector field별 boosting 설정&lt;/li&gt;
&lt;li&gt;검색 결과에 출처 메타데이터 삽입 (&amp;rarr; 사용자 신뢰도 증가)&lt;/li&gt;
&lt;li&gt;Spring Data Elasticsearch와 연동하여 도메인 엔티티 기반 접근&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요약&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;b&gt;Spring AI + OpenSearch 역할&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;EmbeddingClient&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;텍스트 &amp;rarr; 벡터 변환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;OpenSearch&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;벡터 저장 + 유사도 검색&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;ChatClient&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;검색 문서를 프롬프트에 삽입 후 응답 생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;이점&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;기존 인프라 유지, 유연한 필터링, 높은 운영 안정성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기술과 산업/언어 및 프레임워크</category>
      <category>ai-search</category>
      <category>dense-vector</category>
      <category>ElasticSearch</category>
      <category>Embedding</category>
      <category>java</category>
      <category>LLM</category>
      <category>OpenSearch</category>
      <category>rag</category>
      <category>spring-ai</category>
      <category>vectorsearch</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/501</guid>
      <comments>https://bcuts.tistory.com/501#entry501comment</comments>
      <pubDate>Tue, 29 Jul 2025 09:57:04 +0900</pubDate>
    </item>
    <item>
      <title>소프트웨어 아키텍처 시리즈 14화 &amp;ndash; 이벤트 기반 시스템의 데이터 일관성 문제와 해결 전략</title>
      <link>https://bcuts.tistory.com/500</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 기반 시스템은 유연성과 확장성은 높지만, 데이터 일관성 문제를 내포하고 있습니다. 이 글에서는 이벤트 처리에서 발생하는 일관성 이슈의 원인과, 그것을 해결하기 위한 실전 설계 전략을 집중 분석합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 이벤트 기반 시스템은 &amp;lsquo;일관성 문제&amp;rsquo;를 안고 있는가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 기반 시스템은 다음과 같은 장점을 가지고 있습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;서비스 간 &lt;/span&gt;&lt;b&gt;강한 결합 제거&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;비동기 메시지 전달&lt;/b&gt;&lt;/span&gt;을 통한 확장성과 탄력성 확보&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;CQRS + 이벤트 소싱&lt;/b&gt;&lt;/span&gt; 기반의 독립적인 읽기/쓰기 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이 구조는 근본적으로 **즉시 일관성(Strong Consistency)**이 아닌,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**최종적 일관성(Eventual Consistency)**를 전제로 하기 때문에, 데이터 간 불일치가 필연적으로 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대표적인 일관성 문제 사례&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 이벤트 중복 처리&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동일한 이벤트가 두 번 처리되어 데이터가 중복 갱신됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 이벤트 순서 불일치&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;OrderShipped&lt;/span&gt; 이벤트가 &lt;span&gt;OrderPlaced&lt;/span&gt;보다 먼저 도착 &amp;rarr; Projection 오류&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 이벤트 손실&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브로커 장애 또는 구독 서비스 장애로 이벤트 누락 &amp;rarr; 데이터 일관성 훼손&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 트랜잭션 경계 문제&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트 발행은 완료되었지만, DB 커밋이 실패 &amp;rarr; 외부 시스템은 상태 변경됐다고 믿음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;메시지 일관성 보장의 난이도&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 기반 구조는 보통 다음 두 계층으로 나뉩니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;도메인 계층&lt;/b&gt;&lt;/span&gt;: 명령 수행 &amp;rarr; 이벤트 생성&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;인프라 계층&lt;/b&gt;&lt;/span&gt;: 메시지 브로커 발행&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘이 &lt;span&gt;&lt;b&gt;동시에 실패하거나, 동시에 성공하지 않는 문제&lt;/b&gt;&lt;/span&gt;는 &amp;ldquo;데이터-이벤트 일관성 문제(Data-Messaging Inconsistency)&amp;ldquo;라고 불리며, 이는 실무에서 가장 자주 발생하는 장애 유형입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 해결 전략 1 &amp;ndash; 트랜잭셔널 아웃박스 패턴(Transactional Outbox)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 방식은 &lt;/span&gt;&lt;b&gt;도메인 이벤트를 데이터베이스 테이블에 먼저 저장한 뒤&lt;/b&gt;&lt;span&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기적으로 메시지 브로커에 전달하는 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;흐름&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;도메인 로직 수행 &amp;rarr; 이벤트 저장 (Outbox 테이블)&lt;/li&gt;
&lt;li&gt;트랜잭션 커밋&lt;/li&gt;
&lt;li&gt;별도의 Polling 프로세스 또는 CDC가 Outbox 테이블의 이벤트를 브로커로 전송&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 데이터베이스의 트랜잭션 경계 내에서 처리되기 때문에 &lt;span&gt;&lt;b&gt;DB 상태와 이벤트 메시지 간의 원자성을 확보&lt;/b&gt;&lt;/span&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메시지 누락, 중복 방지&lt;/li&gt;
&lt;li&gt;이벤트 저장 시점과 데이터 저장 시점의 일관성 보장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Poller 개발 필요&lt;/li&gt;
&lt;li&gt;DB 테이블 증가&lt;/li&gt;
&lt;li&gt;지연(latency) 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 해결 전략 2 &amp;ndash; 이벤트 재처리/멱등성 보장&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불가피하게 이벤트가 중복되거나 순서가 뒤바뀔 수 있으므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**이벤트 핸들러는 반드시 멱등성(idempotency)**을 보장해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;OrderPlaced&lt;/span&gt; 이벤트는 이미 동일한 주문 ID가 처리됐는지 확인한 후 저장&lt;/li&gt;
&lt;li&gt;Redis, DB에 이벤트 ID 기반 중복 처리 여부 캐시&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 전략은 마이크로서비스 간 통신이나 Kafka 기반 이벤트 설계에서 필수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 해결 전략 3 &amp;ndash; 이벤트 순서 보장&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kafka의 &lt;span&gt;&lt;b&gt;파티션과 키 기반 순서 보장&lt;/b&gt;&lt;/span&gt; 기능을 활용하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;동일한 키(예: &lt;/span&gt;&lt;span&gt;orderId&lt;/span&gt;&lt;span&gt;)에 대해서는 &lt;/span&gt;&lt;b&gt;이벤트 순서를 강제할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;설계 팁&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주문 ID, 사용자 ID 등을 Partition Key로 활용&lt;/li&gt;
&lt;li&gt;Consumer 그룹은 파티션 기반 처리 구조로 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실전 해결 전략 4 &amp;ndash; Snapshot과 보정 시나리오 도입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 Projection은 이벤트 누락이나 순서 꼬임에 취약합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 일정 간격으로 도메인 상태를 Snapshot 형태로 저장하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 발생 시 Projection을 &lt;span&gt;&lt;b&gt;재생하거나 재빌드&lt;/b&gt;&lt;/span&gt;할 수 있도록 설계합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구성&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스냅샷 DB 테이블 (정기 백업)&lt;/li&gt;
&lt;li&gt;Projection 초기화/리플레이 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추가 전략 &amp;ndash; 사가(Saga) 패턴으로 분산 트랜잭션 정렬&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일련의 이벤트 체인에서 트랜잭션 경계를 나누되,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 단계에서 보상 로직을 포함하여 시스템 전체의 &lt;span&gt;&lt;b&gt;논리적 일관성&lt;/b&gt;&lt;/span&gt;을 유지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;예: 주문 생성 &amp;rarr; 결제 승인 &amp;rarr; 재고 차감 &amp;rarr; 배송 요청&lt;/blockquote&gt;
&lt;blockquote style=&quot;color: #0e0e0e;&quot; data-ke-style=&quot;style1&quot;&gt;중간 실패 시, 이전 단계 보상(결제 취소 등) 로직 실행&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;도입 판단 기준&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고려사항&lt;/b&gt;&lt;b&gt;권장 전략&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;데이터-이벤트 일관성&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;트랜잭셔널 아웃박스&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;중복/누락 가능성 높음&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;멱등성 + 재처리 설계&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;순서 중요&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;파티션 키 기반 메시지 설계&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;복잡한 상태 전이&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Saga 또는 State Machine&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;일관성은 트레이드오프의 문제다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 기반 아키텍처는 확장성과 유연성을 주지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 대가로 우리는 &lt;/span&gt;&lt;b&gt;데이터 일관성에 대한 설계 책임을 직접 져야&lt;/b&gt;&lt;span&gt; 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, &lt;/span&gt;&lt;b&gt;CAP 이론의 현실을 받아들이고&lt;/b&gt;&lt;span&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 목적과 복잡도에 맞는 일관성 전략을 구조적으로 설계해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 그 전략은 단순한 기술 선택이 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아키텍트의 판단과 균형 감각이 필요한 영역&lt;/b&gt;&lt;span&gt;입니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>기술과 산업/아키텍처</category>
      <category>CQRS</category>
      <category>데이터일관성</category>
      <category>메시지순서</category>
      <category>멱등성처리</category>
      <category>사가패턴</category>
      <category>실무아키텍처전략</category>
      <category>이벤트기반아키텍처</category>
      <category>이벤트소싱</category>
      <category>트랜잭셔널아웃박스</category>
      <category>헥사고날아키텍처</category>
      <author>B컷개발자</author>
      <guid isPermaLink="true">https://bcuts.tistory.com/500</guid>
      <comments>https://bcuts.tistory.com/500#entry500comment</comments>
      <pubDate>Tue, 29 Jul 2025 09:44:01 +0900</pubDate>
    </item>
  </channel>
</rss>