제조 및 공급망을 위한 LLM 솔루션 엔지니어링
요약
재고 및 수요 데이터를 분석하여 구매 주문을 권장하는 공급망 리스크 에이전트 구축 가이드를 제공합니다. Oxlo.ai를 활용하여 OpenAI SDK 호환성을 유지하면서도 복잡한 BOM 분석 시 추론 비용을 효율적으로 관리하는 방법을 다룹니다.
핵심 포인트
- Oxlo.ai를 활용한 비용 효율적인 공급망 에이전트 구현
- OpenAI SDK 호환성을 통한 손쉬운 클라이언트 설정
- 엄격한 JSON 스키마 강제를 통한 ERP 시스템 연동 최적화
- 복잡한 제조 데이터를 위한 데이터 정규화 및 배치 처리 전략
우리는 원시 재고 및 수요 데이터를 입력받아 부족분을 식별하고, 구조화된 구매 주문(Purchase Order) 권장 사항을 출력하는 공급망 리스크 에이전트(Supply Chain Risk Agent)를 구축하고 있습니다. 이 에이전트는 기존 ERP 파이프라인에 바로 적용되며, Oxlo.ai의 요청당 고정 가격제(flat per-request pricing)로 실행되므로, 복잡한 자재 명세서(Bill of Materials, BOM)를 분석하더라도 추론 비용(Inference bill)이 급증하지 않습니다. 저는 지난 분기에 하드웨어 팀을 위해 이 솔루션의 버전을 출시했으며, 이것이 제가 시작할 때 사용했던 정확한 스캐폴드(Scaffold)입니다.
필요한 사항
- Python 3.10 이상
- OpenAI SDK:
pip install openai - https://portal.oxlo.ai에서 발급받은 Oxlo.ai API 키
1단계: Oxlo.ai 클라이언트 부트스트랩(Bootstrap)
비즈니스 로직을 건드리지 않고 나중에 모델을 교체할 수 있도록 클라이언트 설정을 단일 모듈로 유지합니다. Oxlo.ai는 OpenAI SDK와 완전히 호환되므로, base_url만 변경하면 됩니다.
import os
import json
from datetime import datetime, timedelta
...
2단계: 시스템 프롬프트(System Prompt) 고정
시스템 프롬프트는 모델과의 계약입니다. 저는 다운스트림(Downstream) ERP 스크립트가 정규 표현식(Regex) 없이 결과를 파싱할 수 있도록 엄격한 JSON 스키마(Schema)를 강제하며, 모델이 일관되게 추론할 수 있도록 재고 계산 규칙을 내장합니다.
SYSTEM_PROMPT = """당신은 제조 공급망 분석가입니다. 제공된 SKU 기록을 분석하고 정확히 하나의 유효한 JSON 객체로 응답하십시오. JSON을 마크다운(Markdown)으로 감싸지 마십시오.
Schema:
...
3단계: 공급망 페이로드(Payload) 모델링
제조 데이터는 매우 복잡합니다. 저는 각 SKU를 모델에 보내기 전에 평탄한 딕셔너리(Flat dictionary)로 정규화합니다. 이를 통해 프롬프트 구조를 예측 가능하게 유지하고, 결과 반환 시 중첩 파싱(Nested parsing) 오류를 방지합니다.
def build_user_message(sku_record: dict, reference_date: str) -> str:
payload = {
"task": "analyze_inventory",
...
4단계: JSON 모드로 모델 호출
유효한 출력을 보장하기 위해 Oxlo.ai의 JSON 모드를 사용합니다. 재고 계산은 창의적인 글쓰기가 아니므로 온도를(Temperature) 낮게 유지합니다. 또한 추적 가능성을 위해 입력된 SKU를 결과에 그대로 반영합니다.
def analyze_sku(sku_record: dict) -> dict:
reference = datetime.now().strftime("%Y-%m-%d")
user_msg = build_user_message(sku_record, reference)
...
단계 5: 전체 자재 명세서 (Bill of Materials, BOM) 배치 처리
실제 BOM에는 수십 개의 품목(line items)이 포함되어 있습니다. 저는 리스트를 루프(loop)로 돌며 결과를 수집합니다. Oxlo.ai는 콜드 스타트 (cold starts) 없이 인기 있는 모델들을 제공하므로, 루프는 네트워크 속도로 빠르게 진행됩니다.
BOM = [
{
"sku": "PCB-CTRL-001",
...
단계 6: 플래너 요약 (planner summary) 생성
가공되지 않은 JSON은 ERP에 입력되지만, 사람은 문단 형태의 설명이 필요합니다. 저는 배치(batch) 결과를 모델로 다시 보내 짧은 경영진 요약 (executive summary)을 생성합니다. 이를 별도의 호출 (call)로 유지함으로써, 구조화된 스키마 (structured schema)를 건드리지 않고도 말투(voice)를 조정할 수 있습니다.
def planner_summary(bom: list[dict], analyses: list[dict]) -> str:
enriched = []
for item, analysis in zip(bom, analyses):
...
실행하기
저는 매일 아침 스탠드업 (standup) 미팅 전에 이것을 실행합니다. 그러면 구조화된 기록과 사람이 읽을 수 있는 요약이 모두 출력됩니다.
if __name__ == "__main__":
analyses = analyze_bom(BOM)
...
출력 예시:
=== STRUCTURED RESULTS ===
{
"sku": "PCB-CTRL-001",
"stock_status": "critical",
"projected_stockout_date": "2025-01-25",
"recommended_order_quantity": 800,
"recommended_supplier": "Shenzen PCB Ltd",
"risk_factors": ["single_source", "lead_time_exceeds_14_days"],
"confidence": "high",
"input_sku": "PCB-CTRL-001"
}
{
"sku": "CAP-10UF-0603",
"stock_status": "low",
"projected_stockout_date": "2025-03-02",
"recommended_order_quantity": 1000,
"recommended_supplier": "Yageo",
"risk_factors": ["lead_time_exceeds_14_days"],
"confidence": "high",
"input_sku": "CAP-10UF-0603"
}
{
"sku": "CONN-USBC-01",
"stock_status": "adequate",
"projected_stockout_date": "2025-05-01",
"recommended_order_quantity": 0,
"recommended_supplier": "Amphenol",
"risk_factors": [],
"confidence": "high",
"input_sku": "CONN-USBC-01"
}
=== 플래너 요약 (PLANNER SUMMARY) ===
두 가지 항목에 주의가 필요합니다. PCB-CTRL-001은 매우 중요하며 1월 25일에 재고가 소진될 예정입니다. 즉시 800개를 주문해야 하며 예상 지출액은 $10,000입니다. CAP-10UF-0603은 3월 2일에 재고가 소진될 예정으로 위험도가 낮으며, 약 $20의 비용으로 1,000개를 주문하십시오. CONN-USBC-01은 2분기(Q2)까지 충분합니다. 총 핵심 노출 비용은 $10,000입니다.
다음 단계 (Next steps)
이를 FastAPI 엔드포인트(endpoint)에 연결하여, 귀사의 ERP가 BOM 스냅샷을 POST하고 JSON 배열을 실시간으로 수신할 수 있도록 하십시오. 상관관계가 있는 고장 모드(failure modes)를 가진 다계층 공급업체 네트워크(multi-tier supplier networks) 전반에 걸쳐 추론이 필요한 경우, 더 깊은 사고 사슬 (chain-of-thought) 분석을 위해 Oxlo.ai에서 llama-3.3-70b를 kimi-k2.6 또는 deepseek-v3.2로 교체하십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기