<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>김신건의 로그 - 위키 / ai</title><description>&apos;ai&apos; 카테고리 위키 페이지 최신 업데이트</description><link>https://shinkeonkim.com/</link><language>ko-KR</language><item><title>[LLM Eval] BIG-Bench (Beyond the Imitation Game)</title><link>https://shinkeonkim.com/wiki/ai/big-bench/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/big-bench/</guid><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;BIG-Bench (Beyond the Imitation Game Benchmark)&lt;/strong&gt; 는 2022년 Google + 132개 기관 442명의 공저로 발표된 &lt;strong&gt;대형 언어 모델 종합 평가 벤치마크&lt;/strong&gt; 입니다. &lt;strong&gt;204 개의 다양한 태스크&lt;/strong&gt; 를 담고 있어, 하나의 스킬이 아닌 언어 모델의 &lt;strong&gt;광폭 능력 지도&lt;/strong&gt; 를 그리는 것이 목표입니다.&lt;/p&gt;
&lt;p&gt;이름은 튜링 테스트 (Imitation Game) 를 넘어서겠다는 뜻으로, 단일 태스크 벤치마크가 놓치는 능력들을 포괄합니다.&lt;/p&gt;
&lt;h2 id=&quot;구성&quot;&gt;구성&lt;/h2&gt;
&lt;h3 id=&quot;태스크-유형&quot;&gt;태스크 유형&lt;/h3&gt;
&lt;p&gt;BIG-Bench 태스크는 크게 두 형태로 정의됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JSON tasks&lt;/strong&gt;: 입력, 정답 (multiple-choice 또는 free-form generation) 이 JSON 으로 명시된 태스크. 자동 채점 가능.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Programmatic tasks&lt;/strong&gt;: 파이썬 함수가 상호작용 (다중 턴, 조건부 프롬프트 생성) 을 정의. 훨씬 유연하지만 상대적으로 소수.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;태스크-카테고리&quot;&gt;태스크 카테고리&lt;/h3&gt;
&lt;p&gt;204 개는 다음과 같은 keyword tag 로 분류됩니다 (한 태스크에 여러 태그).&lt;/p&gt;

















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;태그&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;대표 태스크&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;논리 (logic)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;logical deduction, formal fallacies, sports understanding&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;수학 (mathematics)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;arithmetic, tracking shuffled objects, multi-step arithmetic&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;상식 (commonsense)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;causal judgment, hyperbaton, disambiguation QA&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;다국어 (multilingual)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;international phonetic alphabet transliterate, 다국어 QA&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;사회 편향 (bias)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BBQ (Bias Benchmark for QA), gender inclusive sentences&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;자기인식 (self-awareness)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;self-evaluation tutoring, know unknowns&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;거짓 정보 (misinformation)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;TruthfulQA (별도 벤치이지만 통합)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;coding&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;date understanding, formal logic&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;소설 태스크&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;novel concepts, ruin names, understanding fables&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;긴 컨텍스트&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;disambiguation, tracking shuffled objects&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;채점&quot;&gt;채점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiple-choice&lt;/strong&gt;: brier score, log-likelihood 정답 확률&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation&lt;/strong&gt;: exact match, BLEU, ROUGE, 태스크별 custom scorer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 태스크는 &lt;strong&gt;인간 baseline (평균/최고)&lt;/strong&gt; 도 함께 포함하여, 모델이 사람 수준에 도달했는지 판단합니다.&lt;/p&gt;
&lt;h2 id=&quot;평가-파이프라인&quot;&gt;평가 파이프라인&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Model[&quot;LLM 모델&quot;] --&gt; Harness[&quot;lm-evaluation-harness&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Harness --&gt; BBH[&quot;BBH 태스크들&amp;#x3C;br/&gt;(23개)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    BBH --&gt; Prompt[&quot;Few-shot prompt&amp;#x3C;br/&gt;(3-shot CoT)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Prompt --&gt; Gen[&quot;모델 생성&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Gen --&gt; Score[&quot;자동 채점&amp;#x3C;br/&gt;(exact match / custom)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Score --&gt; Report[&quot;정확도 리포트&amp;#x3C;br/&gt;(태스크별 + 평균)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Human[&quot;인간 baseline&quot;] --&gt; Report&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    BBH_Raw[&quot;BBH (23 태스크)&quot;] --&gt;|&quot;GPT-4 급에서 포화&quot;| BBEH[&quot;BBEH (23 대응)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    BBEH --&gt; HardTask[&quot;추론 홉 증가&amp;#x3C;br/&gt;오도 정보 삽입&amp;#x3C;br/&gt;문제 길이 확장&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    HardTask --&gt; Result[&quot;최신 프론티어 모델&amp;#x3C;br/&gt;평균 정확도 30% 미만&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;big-bench-hard-bbh&quot;&gt;BIG-Bench Hard (BBH)&lt;/h2&gt;
&lt;p&gt;Suzgun et al. (2022) 은 204 개 태스크 중 &lt;strong&gt;당시 (GPT-3 급) 최선 모델이 사람 평균에도 못 미친 23 개 태스크&lt;/strong&gt; 를 골라 &lt;strong&gt;BIG-Bench Hard (BBH)&lt;/strong&gt; 를 만들었습니다.&lt;/p&gt;
&lt;p&gt;대표 BBH 태스크 (일부):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Boolean Expressions&lt;/strong&gt;: 논리식 truth value 계산&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Causal Judgment&lt;/strong&gt;: 인과관계 판단 (도덕적 시나리오 포함)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Date Understanding&lt;/strong&gt;: 상대 날짜 계산 (“last Friday” 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disambiguation QA&lt;/strong&gt;: 대명사 지칭 애매성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Formal Fallacies&lt;/strong&gt;: 형식논리 오류 식별&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Geometric Shapes&lt;/strong&gt;: SVG path -&gt; 도형 이름&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hyperbaton&lt;/strong&gt;: 형용사 순서 문법&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Logical Deduction (three/five/seven objects)&lt;/strong&gt;: 순서 추론&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Movie Recommendation&lt;/strong&gt;: 최근접 유사 영화 찾기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-Step Arithmetic&lt;/strong&gt;: 다단계 계산&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Navigate&lt;/strong&gt;: 이동 후 시작점 여부&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Object Counting&lt;/strong&gt;: 물체 개수 세기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Penguins in a Table&lt;/strong&gt;: 표에서 조건 필터링&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reasoning about Colored Objects&lt;/strong&gt;: 색깔 물체 추론&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruin Names&lt;/strong&gt;: 이름의 한 글자 바꾸기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Salient Translation Error Detection&lt;/strong&gt;: 번역 오류 탐지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snarks&lt;/strong&gt;: 풍자 이해&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sports Understanding&lt;/strong&gt;: 스포츠 상식&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Temporal Sequences&lt;/strong&gt;: 일정 짜기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracking Shuffled Objects (three/five/seven)&lt;/strong&gt;: 물체 위치 추적&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web of Lies&lt;/strong&gt;: 진실/거짓 진술 체인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Word Sorting&lt;/strong&gt;: 단어 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 23개는 [[chain-of-thought|CoT]] 프롬프팅 효과를 검증하는 대표 벤치마크로 자리잡았습니다. Suzgun 논문 자체가 “CoT 로 몇 태스크는 사람 수준을 초과” 했다는 결과입니다.&lt;/p&gt;
&lt;h2 id=&quot;bbeh-big-bench-extra-hard&quot;&gt;BBEH (BIG-Bench Extra Hard)&lt;/h2&gt;
&lt;p&gt;Kazemi et al. (2025) 은 BBH 가 최신 프론티어 모델 (GPT-4o, Claude 3.5, Gemini 1.5) 에게 이미 포화 (&gt; 85% 정확도) 되었다는 문제를 지적하며, 각 BBH 태스크의 &lt;strong&gt;더 어려운 변종&lt;/strong&gt; 으로 대체한 &lt;strong&gt;BBEH&lt;/strong&gt; 를 발표했습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BBH 와 같은 23 개 카테고리 대응&lt;/li&gt;
&lt;li&gt;문제 길이 확장, 추론 홉 (hop) 증가, 오도 정보 삽입&lt;/li&gt;
&lt;li&gt;최신 모델도 평균 정확도 30% 미만 (초기 리포트 기준)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;주요-모델-성능-추이&quot;&gt;주요 모델 성능 추이&lt;/h2&gt;
&lt;p&gt;BIG-Bench / BBH 에서의 정확도 변화 (대략적 추이):&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;모델 세대&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;BBH 정확도 (대략)&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특이점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;GPT-3 (2020)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;30-40%&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사람 평균 이하 태스크 다수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;GPT-4 (2023)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;70-85%&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대부분 태스크 사람 수준 근접&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Claude 3.5 / GPT-4o (2024)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&gt; 85%&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;포화 시작, BBH 변별력 감소&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;o1 / Gemini 2.0 (2024-25)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&gt; 90%&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BBH 실질적 의미 소멸, BBEH 필요성 대두&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
이 수치들은 대략적인 경향입니다. 실제 벤치마크 결과는 few-shot 설정, 프롬프트 형식, 평가 도구 버전에 따라 달라집니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;리더보드&quot;&gt;리더보드&lt;/h2&gt;
&lt;p&gt;원 BIG-Bench 는 &lt;strong&gt;GitHub 기반 커뮤니티 벤치마크&lt;/strong&gt; 로 시작했지만, 이후 다음 플랫폼들이 리더보드를 제공합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HELM Classic&lt;/strong&gt;: BIG-Bench 태스크 일부 통합, [[helm-llm-benchmark|HELM]] 축으로 리포트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EleutherAI lm-evaluation-harness&lt;/strong&gt;: BBH 자동 실행 지원 (&lt;code&gt;--tasks bbh_*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Papers With Code&lt;/strong&gt;: BBH 별 순위표&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;한계&quot;&gt;한계&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;태스크 품질 편차가 큽니다.&lt;/strong&gt; 442명 공저 방식이라 태스크마다 명세 완성도가 다르고, 일부는 정답 라벨이 애매합니다. 이 문제 때문에 실전에서는 BBH 로 축약해 쓰는 경우가 많습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;데이터 오염 (contamination)&lt;/strong&gt;. 초기 발표 후 태스크가 공개되어 학습 데이터에 유입될 위험. GPT-4 이후 모델의 BBH 정확도가 갑자기 뛴 이유 중 하나로 지목됩니다. BBEH 는 이 문제를 부분 완화.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;BIG-Bench 는 “언어 이해” 편중&lt;/strong&gt; 입니다. 코드 실행, 멀티모달, agent 사용, 툴 호출은 초기 스코프에서 벗어나 있어, 오늘날 LLM 평가에는 다른 벤치마크와 병행이 필요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;다른-벤치마크와-관계&quot;&gt;다른 벤치마크와 관계&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;벤치마크&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;초점&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;BIG-Bench 와 차이&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;**[[helm-llm-benchmark&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;HELM]]**&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다면적 (accuracy + fairness + robustness …)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MMLU&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지식 QA 57 과목&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BIG-Bench 는 더 넓고 소설 태스크 포함, MMLU 는 학과 시험&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MMLU-Pro&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MMLU 강화&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;여전히 지식 QA 편중&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;GSM8K / MATH&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;수학&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BIG-Bench 에 수학 태스크가 있지만 소규모&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;HumanEval / MBPP&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;코드 생성&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BIG-Bench 는 코드 편중 아님&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Chatbot Arena&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사람 선호도&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;태스크 세분화 없음, BIG-Bench 는 세분&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;실전-사용&quot;&gt;실전 사용&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# EleutherAI lm-evaluation-harness 기준&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; lm-eval&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;lm_eval&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --model&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; hf&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --model_args&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; pretrained=meta-llama/Llama-3.3-70B&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --tasks&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; bbh_boolean_expressions,bbh_navigate,bbh_causal_judgment&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --num_fewshot&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --device&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; cuda:0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;bbh_*&lt;/code&gt; 태스크는 CoT 를 기본으로 활용하도록 few-shot 예시가 이미 구성되어 있습니다. Zero-shot 실험이라면 &lt;code&gt;bbh_zero_shot_*&lt;/code&gt; 변종 사용.&lt;/p&gt;
&lt;h3 id=&quot;재현-시-주의사항&quot;&gt;재현 시 주의사항&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;few-shot 수 (0, 1, 3) 에 따라 결과가 크게 달라짐&lt;/li&gt;
&lt;li&gt;프롬프트 템플릿 (CoT 유무, 언어) 명시&lt;/li&gt;
&lt;li&gt;모델 버전 (체크포인트) 고정&lt;/li&gt;
&lt;li&gt;평가 라이브러리 버전 고정 (lm-eval 버전별 결과 차이 존재)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;인간-baseline-해석&quot;&gt;인간 baseline 해석&lt;/h2&gt;
&lt;p&gt;BIG-Bench 는 태스크별로 &lt;em&gt;인간 평균&lt;/em&gt; 과 &lt;em&gt;인간 최고&lt;/em&gt; 두 baseline 을 제공합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;인간 평균&lt;/strong&gt;: 일반 사람 (crowdsource) 의 평균 성능. 많은 태스크에서 50-75% 수준.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인간 최고&lt;/strong&gt;: 전문가 또는 best worker. 대부분 태스크에서 85-99%.&lt;/li&gt;
&lt;li&gt;모델 점수가 &lt;em&gt;인간 평균을 초과하면&lt;/em&gt; “superhuman” 이라 부르지만, 태스크 특성에 따라 다름.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BBH 의 23개 태스크는 &lt;em&gt;원 BIG-Bench 에서 GPT-3 이 인간 평균에 못 미친 것들&lt;/em&gt;. 즉 BBH 의 human baseline 은 최소 GPT-3 보다 높다는 의미.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
인간 baseline 은 crowdwork 설정에 따라 달라집니다. 태스크 지시문의 명확도, 평가자의 도메인 지식에 따라 동일 태스크라도 baseline 이 크게 다를 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;어떤-상황에-사용하나&quot;&gt;어떤 상황에 사용하나&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;상황&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;사용 여부&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;이유&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;새 모델의 일반 언어 능력 측정&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BBH 사용&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;검증된 23개, 해석하기 쉬움&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;최신 프론티어 모델 변별&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BBEH 사용&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BBH 는 포화 상태&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;코드 생성 능력 평가&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다른 벤치 (HumanEval, MBPP)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BIG-Bench 는 코드 편중 아님&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;다국어 능력&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;FLORES, mMMLU 병행&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BIG-Bench 다국어 태스크는 소수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;에이전트/툴 사용 능력&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GAIA, SWE-bench&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BIG-Bench 스코프 밖&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;연구 논문에서 표준 비교&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;BBH 선택&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;인용 수와 재현성 보장&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
BBH 를 단독으로 리포트하면 “어떤 few-shot 설정인지”, “어떤 평가 라이브러리 버전인지” 반드시 명시. 설정에 따라 결과가 5-15% 포인트 달라질 수 있음.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;공개-기여-방법&quot;&gt;공개 기여 방법&lt;/h2&gt;
&lt;p&gt;BIG-Bench 는 GitHub PR 기반 공개 기여 모델로 운영됩니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 새 태스크 기여 흐름&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; clone&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; https://github.com/google/BIG-bench&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; BIG-bench/bigbench/benchmark_tasks/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 새 폴더 생성 (kebab-case)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;mkdir&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; my_new_task&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# task.json 또는 task.py 작성&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# README.md: 태스크 설명, 인간 baseline, 동기 기술&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 테스트: python -m pytest bigbench/tests/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;태스크는 &lt;strong&gt;JSON&lt;/strong&gt; (간단한 QA) 또는 &lt;strong&gt;Python&lt;/strong&gt; (복잡한 상호작용) 중 선택. 공식 GitHub 의 &lt;code&gt;bigbench/benchmark_tasks/&lt;/code&gt; 아래 기존 태스크를 참고.&lt;/p&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] - 다면 평가 프레임워크 (BIG-Bench 태스크 통합)&lt;/li&gt;
&lt;li&gt;[[chain-of-thought|Chain-of-Thought]] - BBH 는 CoT 효과 실증의 표준 벤치&lt;/li&gt;
&lt;li&gt;[[zero-shot-prompting|Zero-Shot Prompting]] - BBH 도 zero-shot 변종 존재&lt;/li&gt;
&lt;li&gt;[[few-shot-prompting|Few-Shot Prompting]] - BBH 표준은 3-shot CoT&lt;/li&gt;
&lt;li&gt;[[classification-metrics|분류 모델 지표]] - 태스크별 스코어 계산 근간&lt;/li&gt;
&lt;li&gt;[[transfer-learning|Transfer Learning]] - BIG-Bench 는 파운데이션 모델 일반화 능력 평가&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>benchmark</category><category>evaluation</category><author>koa (김신건)</author></item><item><title>[Prompting] Few-Shot Prompting</title><link>https://shinkeonkim.com/wiki/ai/few-shot-prompting/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/few-shot-prompting/</guid><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Few-shot prompting&lt;/strong&gt; 은 프롬프트 안에 &lt;strong&gt;작업의 입력-출력 예시 K개 (보통 K = 2~16)&lt;/strong&gt; 를 함께 제공해 모델이 그 형식과 규칙을 유추해 새 입력에 답하도록 하는 기법입니다. 예시로부터의 학습이지만 &lt;strong&gt;가중치 갱신이 없기 때문에 (no gradient update)&lt;/strong&gt; 이를 &lt;strong&gt;in-context learning (ICL)&lt;/strong&gt; 이라 부릅니다.&lt;/p&gt;
&lt;p&gt;Brown et al. (2020) 의 GPT-3 논문이 “규모가 커지면 파인튜닝 없이도 예시 몇 개만으로 태스크를 수행한다” 는 관찰을 대중화했습니다.&lt;/p&gt;
&lt;h2 id=&quot;언제-쓰이나&quot;&gt;언제 쓰이나&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;엄격한 출력 형식 강제&lt;/strong&gt;: JSON 스키마, 특정 XML, 사내 보고서 양식&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도메인 특화 어휘&lt;/strong&gt;: 의료, 법률, 사내 용어의 특수 컨벤션&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비표준 분류 라벨&lt;/strong&gt;: 기존 상식과 다른 라벨 체계&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;zero-shot 오류가 반복될 때&lt;/strong&gt;: 예시가 지시문보다 훨씬 빠르게 문제를 해결&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;입력이 짧고 반복 패턴이 강한 태스크&lt;/strong&gt;: 구조적 예시의 효과가 극대화&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;기본-흐름&quot;&gt;기본 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Prompt[&quot;Few-Shot 프롬프트&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E1[&quot;예시 1: Input - Output&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        E2[&quot;예시 2: Input - Output&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        EK[&quot;예시 K: Input - Output&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Q[&quot;본 질의: Input - ?&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Prompt --&gt; ICL[&quot;LLM\nIn-Context Learning&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ICL --&gt; Ans[&quot;예측 Output&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예시는 &lt;strong&gt;가중치를 바꾸지 않는다&lt;/strong&gt;. 모델이 컨텍스트에서 패턴을 추출해 즉시 적용.&lt;/p&gt;
&lt;h2 id=&quot;기본-구조&quot;&gt;기본 구조&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[선택] 시스템/지시문&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[선택] 형식 스펙&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[예시 1]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Input: ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Output: ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[예시 2]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Input: ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Output: ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[본 질의]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Input: {query}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Output:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Chat API 에서는 이를 &lt;strong&gt;role-alternating messages&lt;/strong&gt; 로 옮기기도 합니다:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;감정을 positive/negative 로 분류&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;이 식당은 정말 좋았어요&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;positive&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;다시는 가고 싶지 않네요&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;negative&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{query}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;k-값의-선택&quot;&gt;K 값의 선택&lt;/h2&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;center&quot;&gt;K&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특성&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;언제&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;0&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Zero-shot&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지시문이 명확하고 모델이 태스크를 잘 알 때&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;1&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;One-shot&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;형식만 맞추면 되는 단순 태스크&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;3-8&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;표준 few-shot&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대부분의 실전 태스크&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;16-32&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Many-shot&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Complex reasoning, 다양한 클래스 커버&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;100+&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Many-shot (Gemini/Claude long context)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컨텍스트 확장 후 등장한 실험적 영역&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Diminishing return&lt;/strong&gt; 이 K = 8 근처부터 관찰되는 경우가 많지만, Gemini 1.5 / Claude 3 이후의 초장문 컨텍스트에서는 K = 500 many-shot 이 여전히 유효하다는 결과 (Agarwal et al. 2024) 도 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;무엇이-성능을-결정하는가&quot;&gt;무엇이 성능을 결정하는가&lt;/h2&gt;
&lt;p&gt;Min et al. (2022) 의 “Rethinking the Role of Demonstrations” 이 반직관적 결과를 보였습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;라벨을 랜덤으로 섞어도&lt;/strong&gt; 정확도가 크게 안 떨어짐 (in-context 예시는 형식/도메인 시그널이 더 중요)&lt;/li&gt;
&lt;li&gt;하지만 &lt;strong&gt;입력 분포&lt;/strong&gt; 와 &lt;strong&gt;라벨 분포&lt;/strong&gt; (어떤 클래스가 나올 수 있는지) 는 매우 중요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;형식 (delimiter, template)&lt;/strong&gt; 이 라벨보다 더 중요할 때가 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;즉 few-shot 예시가 하는 일은 &lt;strong&gt;모델에게 “이 태스크의 표면 형식”&lt;/strong&gt; 을 상기시키는 것이지, 실제로 “라벨 규칙을 학습” 하는 것은 아닐 수 있습니다 (완전한 결론은 아니지만 강력한 경향성).&lt;/p&gt;
&lt;h2 id=&quot;예시-선택-전략&quot;&gt;예시 선택 전략&lt;/h2&gt;
&lt;p&gt;Liu et al. (2021) 는 &lt;strong&gt;kNN 유사도 기반 선택&lt;/strong&gt; 이 유리함을 보임. 프로덕션에서는:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Pool[&quot;예시 풀\n(수백~수천개)&quot;] --&gt; Embed[&quot;예시 임베딩 변환&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Query[&quot;현재 질의&quot;] --&gt; QEmbed[&quot;질의 임베딩 변환&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Embed --&gt; KNN[&quot;kNN 유사도 검색&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    QEmbed --&gt; KNN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    KNN --&gt; TopK[&quot;Top-K 유사 예시 선택&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TopK --&gt; Bal[&quot;라벨 균형 조정\n(Majority bias 방지)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Bal --&gt; Prompt[&quot;Few-shot 프롬프트 조합&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Query --&gt; Prompt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Prompt --&gt; LLM[&quot;LLM 추론&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAG 스타일&lt;/strong&gt;: 질의를 임베딩 후 pool 에서 top-k 유사 예시 선택&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diverse selection&lt;/strong&gt;: 클러스터에서 골고루 뽑아 커버리지 확보&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hard example prioritization&lt;/strong&gt;: 어려운 케이스 (edge case) 를 예시로 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;함정과-편향&quot;&gt;함정과 편향&lt;/h2&gt;
&lt;h3 id=&quot;1-recency-bias&quot;&gt;1. Recency bias&lt;/h3&gt;
&lt;p&gt;마지막 예시의 라벨이 답에 강하게 영향. &lt;strong&gt;다양한 클래스를 골고루 섞고 마지막에 특정 편향된 라벨을 두지 않도록&lt;/strong&gt; 주의.&lt;/p&gt;
&lt;h3 id=&quot;2-majority-label-bias&quot;&gt;2. Majority label bias&lt;/h3&gt;
&lt;p&gt;예시에 특정 클래스가 많으면 그쪽으로 편향. 균형된 분포로 샘플링.&lt;/p&gt;
&lt;h3 id=&quot;3-common-token-bias&quot;&gt;3. Common token bias&lt;/h3&gt;
&lt;p&gt;빈도 높은 토큰 (예: “yes”) 을 답으로 선호. &lt;strong&gt;Calibrate Before Use&lt;/strong&gt; (Zhao et al., 2021) 는 이를 완화하는 후처리:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;p_calibrated(y | x) = p(y | x) / p(y | &quot;&quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;빈 입력에 대한 확률로 나누어 편향을 정규화.&lt;/p&gt;
&lt;h3 id=&quot;4-order-sensitivity&quot;&gt;4. Order sensitivity&lt;/h3&gt;
&lt;p&gt;Lu et al. (2022) 는 같은 예시라도 순서만 바꿔도 정확도가 큰 폭으로 흔들림을 보였습니다. &lt;strong&gt;여러 순서로 앙상블&lt;/strong&gt; 하거나 &lt;strong&gt;정보이론적 지표로 좋은 순서 선택&lt;/strong&gt; 을 시도.&lt;/p&gt;
&lt;h3 id=&quot;5-example-selection&quot;&gt;5. Example selection&lt;/h3&gt;
&lt;p&gt;Liu et al. (2021) 는 &lt;strong&gt;kNN 유사도 기반 선택&lt;/strong&gt; 이 유리함을 보임. 프로덕션에서는:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAG 스타일&lt;/strong&gt;: 질의를 임베딩 -&gt; pool 에서 top-k 유사 예시 선택&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diverse selection&lt;/strong&gt;: 클러스터에서 골고루 뽑아 커버리지 확보&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hard example prioritization&lt;/strong&gt;: 어려운 케이스 (edge case) 를 예시로 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;chain-of-thought-와-결합&quot;&gt;Chain-of-Thought 와 결합&lt;/h2&gt;
&lt;p&gt;Few-shot + [[chain-of-thought|CoT]] 는 CoT 원 논문의 정확한 방식. 예시 자체에 &lt;strong&gt;추론 사슬&lt;/strong&gt; 을 포함:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: If John has 3 apples and gives 1 to Mary, how many left?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: John started with 3. He gave away 1. 3 - 1 = 2. The answer is 2.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: {question}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;실전-예시&quot;&gt;실전 예시&lt;/h2&gt;
&lt;h3 id=&quot;python-으로-few-shot-분류-openai&quot;&gt;Python 으로 few-shot 분류 (OpenAI)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; openai &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; few_shot_classify&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(text: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, examples: list[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    examples: [{&quot;input&quot;: &quot;...&quot;, &quot;output&quot;: &quot;positive/negative&quot;}]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    messages &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;고객 리뷰를 positive 또는 negative 로 분류합니다.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # few-shot 예시를 role-alternating 으로 추가&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ex &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; examples:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        messages.append({&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: ex[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        messages.append({&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: ex[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # 본 질의&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    messages.append({&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: text})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        temperature&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.choices[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].message.content.strip()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;examples &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;정말 만족스럽습니다!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;positive&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;다시는 구매 안 합니다.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;negative&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;무난하고 가성비 좋네요.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;positive&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;포장이 너무 엉망이었어요.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;negative&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; few_shot_classify(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;배송이 생각보다 늦었지만 제품은 좋아요.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, examples)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result)  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# &quot;positive&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;json-스키마-강제-추출&quot;&gt;JSON 스키마 강제 추출&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;SYSTEM&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;다음 양식에 맞게 JSON 만 출력하시오. 추가 텍스트 없이.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;EXAMPLES&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;홍길동, 010-1234-5678, hong@example.com&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;{&quot;name&quot;:&quot;홍길동&quot;,&quot;phone&quot;:&quot;010-1234-5678&quot;,&quot;email&quot;:&quot;hong@example.com&quot;}&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;김철수, 010-9999-0000, chul@corp.co.kr&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;{&quot;name&quot;:&quot;김철수&quot;,&quot;phone&quot;:&quot;010-9999-0000&quot;,&quot;email&quot;:&quot;chul@corp.co.kr&quot;}&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;SYSTEM&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ex &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; EXAMPLES&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    messages &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: ex[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: ex[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;output&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages.append({&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;이영희, 010-7777-8888, lee@startup.io&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;instruction-tuned-모델에서의-위상-변화&quot;&gt;Instruction-tuned 모델에서의 위상 변화&lt;/h2&gt;
&lt;p&gt;GPT-4, Claude, Gemini 등 instruction-tuned 계열은 &lt;strong&gt;zero-shot 성능이 이미 높아&lt;/strong&gt; 대부분 태스크에서 few-shot 이득이 작아졌습니다. Few-shot 이 여전히 강한 곳은:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;엄격한 출력 형식&lt;/strong&gt; (예: 특정 JSON 스키마)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도메인 특화 어휘&lt;/strong&gt; (의료, 법률의 특정 용어 컨벤션)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분류 태스크의 라벨 세트가 이상함&lt;/strong&gt; (기존 상식과 다른 라벨링)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;입력이 짧고 반복 패턴이 강함&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실전-팁&quot;&gt;실전 팁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;가장 정보량 높은 예시&lt;/strong&gt; 를 선택 (경계 케이스, 오답이 자주 나오는 케이스).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;예시 순서 다양화 후 앙상블&lt;/strong&gt; (n=3~5 순서).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;라벨 균형 유지&lt;/strong&gt;: K=8 이면 각 라벨이 최대 2-3개.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;명시적 구분자&lt;/strong&gt; (&lt;code&gt;###&lt;/code&gt;, &lt;code&gt;---&lt;/code&gt;, &lt;code&gt;Q:/A:&lt;/code&gt;) 로 예시 경계를 확실히.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;형식만 배우는 것 같으면&lt;/strong&gt; temperature 를 낮추고 (0-0.2) 결정적 출력.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용 관리&lt;/strong&gt;: K 를 늘리면 입력 토큰이 선형 증가. K=8 → K=32 는 API 요금 4배.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Recency / Majority bias 로 인해 예상과 다른 라벨을 선호합니다.&lt;/strong&gt; 마지막 예시나 빈번한 라벨로 치우치는 경향이 있습니다. 예시 순서를 무작위로 섞거나 여러 순서의 앙상블을 고려하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;비용이 선형으로 증가합니다.&lt;/strong&gt; K = 16 예시를 모든 요청에 붙이면 입력 토큰이 크게 늘어납니다. RAG 스타일 동적 선택으로 관련 예시만 붙이는 방식이 비용 효율적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;예시 품질이 결과 품질을 결정합니다.&lt;/strong&gt; 잘못된 예시 하나가 전체 성능을 끌어내릴 수 있습니다. 예시 pool 은 사람이 검증한 고품질 샘플로 구성하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[zero-shot-prompting|Zero-Shot Prompting]] - K=0, 지시문만&lt;/li&gt;
&lt;li&gt;[[one-shot-prompting|One-Shot Prompting]] - K=1, 형식 정렬&lt;/li&gt;
&lt;li&gt;[[chain-of-thought|Chain-of-Thought]] - 예시에 추론 사슬 포함&lt;/li&gt;
&lt;li&gt;[[llm-rag|LLM RAG]] - 예시를 벡터 유사도로 검색&lt;/li&gt;
&lt;li&gt;[[function-calling|Function Calling]] - 함수 스키마를 few-shot 대체로&lt;/li&gt;
&lt;li&gt;[[transfer-learning|Transfer Learning]] - 파인튜닝의 대안으로서 ICL&lt;/li&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] - few-shot 평가 표준화 벤치마크&lt;/li&gt;
&lt;li&gt;[[big-bench|BIG-Bench]] - few-shot 성능 다양성 테스트&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>prompting</category><category>in-context-learning</category><author>koa (김신건)</author></item><item><title>[Prompting] Zero-Shot Prompting</title><link>https://shinkeonkim.com/wiki/ai/zero-shot-prompting/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/zero-shot-prompting/</guid><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Zero-shot prompting&lt;/strong&gt; 은 프롬프트에 &lt;strong&gt;예시 없이 태스크 지시문만&lt;/strong&gt; 제공해 모델이 태스크를 수행하도록 하는 기법입니다. K=0 few-shot 이지만 &lt;strong&gt;의미가 다르며&lt;/strong&gt;, 모델이 &lt;strong&gt;사전학습 + instruction tuning&lt;/strong&gt; 으로 얻은 일반화 능력에 의존합니다.&lt;/p&gt;
&lt;p&gt;Radford et al. (2019) 의 GPT-2 논문에서 “unsupervised multitask learners” 라는 표현으로 처음 대중화되었고, InstructGPT (2022) 이후 실용화되었습니다.&lt;/p&gt;
&lt;h2 id=&quot;언제-쓰이나&quot;&gt;언제 쓰이나&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;표준 태스크&lt;/strong&gt;: 요약, 번역, 감정 분석, 텍스트 분류&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자연어 인터페이스 (챗봇)&lt;/strong&gt;: 사용자 발화가 매번 달라 few-shot 이 비실용적&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용 최소화&lt;/strong&gt;: 대량 배치 처리에서 입력 토큰 절감&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;탐색적 실험 초기&lt;/strong&gt;: 새 태스크를 설계할 때 반복 실험 시작점&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프로덕션 간단 태스크&lt;/strong&gt;: 모델이 이미 잘 아는 태스크에서 예시 없이도 충분&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;기본-흐름&quot;&gt;기본 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Inst[&quot;지시문\n(태스크 설명)&quot;] --&gt; Model[&quot;Instruction-tuned LLM&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Input[&quot;입력 텍스트&quot;] --&gt; Model&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Model --&gt; Output[&quot;예측 출력&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예시가 없다. 지시문 + 입력만으로 추론. 모델의 instruction tuning 품질이 곧 zero-shot 성능.&lt;/p&gt;
&lt;h2 id=&quot;기본-구조&quot;&gt;기본 구조&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{지시문}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{입력}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;다음 문장의 감정을 positive 또는 negative 중 하나로만 답하시오.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;문장: 이 식당은 서비스도 좋고 음식도 맛있었습니다.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;답:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;왜-zero-shot-이-가능한가&quot;&gt;왜 zero-shot 이 가능한가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;사전학습 데이터에 이미 태스크가 섞여 있음&lt;/strong&gt;: 인터넷 코퍼스에는 “번역: … -&gt; …”, “요약: …”, “질문: … 답: …” 형태가 자연스럽게 포함되어, 모델이 pattern 을 학습.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instruction tuning&lt;/strong&gt; (FLAN, T0, InstructGPT): 다양한 태스크의 &lt;strong&gt;지시문 + 정답 쌍&lt;/strong&gt; 으로 파인튜닝. 미지의 지시문에도 일반화.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RLHF&lt;/strong&gt;: 사람 선호도 기반 강화학습으로 지시 준수 능력 강화.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    PT[&quot;사전학습\n(웹 텍스트 수조 토큰)&quot;] --&gt; IT[&quot;Instruction Tuning\n(FLAN, T0, SFT)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    IT --&gt; RLHF[&quot;RLHF / DPO\n(사람 선호도 학습)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RLHF --&gt; ZS[&quot;Zero-shot 능력\n(미학습 태스크도 수행)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;few-shot-대비-장단점&quot;&gt;Few-shot 대비 장단점&lt;/h2&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;기준&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Zero-shot&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Few-shot&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;입력 토큰&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 짧음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;K 배 증가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;비용&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;예시 개수만큼 증가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;형식 준수&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지시문에만 의존&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;예시가 강력한 앵커&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;엣지 케이스&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지시문에 안 쓰면 놓침&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;예시로 커버 가능&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;성능 (단순 태스크)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Instruction-tuned 모델이면 대등&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소폭 우위&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;성능 (복잡/특이 태스크)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지시문만으론 부족&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;예시로 disambiguate&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;zero-shot-cot&quot;&gt;Zero-shot CoT&lt;/h2&gt;
&lt;p&gt;Kojima et al. (2022) 는 프롬프트 끝에 &lt;strong&gt;“Let’s think step by step”&lt;/strong&gt; 을 붙이는 것만으로 CoT 를 유도할 수 있음을 보였습니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: {question}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: Let&apos;s think step by step.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multi-Arith 정확도 17.7% → 78.7% (InstructGPT-003). 자세한 내용은 [[chain-of-thought|Chain-of-Thought]] 참조.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant U as 사용자&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant L as LLM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    U-&gt;&gt;L: 문제 + &quot;단계별로 풀이하시오&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L--&gt;&gt;L: 내부 추론 단계 생성&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L--&gt;&gt;U: 1단계 풀이 ... 최종 답&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;한국어에서는:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“차근차근 생각해 봅시다.”&lt;/li&gt;
&lt;li&gt;“단계별로 풀이해 봅시다.”&lt;/li&gt;
&lt;li&gt;“먼저 문제를 정리하고, 단계별로 계산합니다.”&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;instruction-tuning-의-영향&quot;&gt;Instruction tuning 의 영향&lt;/h2&gt;
&lt;p&gt;Zero-shot 성능은 모델의 instruction tuning 품질에 강하게 의존합니다.&lt;/p&gt;
&lt;h3 id=&quot;flan-wei-et-al-2021&quot;&gt;FLAN (Wei et al., 2021)&lt;/h3&gt;
&lt;p&gt;Google 의 137B LaMDA-PT 를 62개 NLP 태스크의 지시문으로 파인튜닝. 미학습 태스크에서 zero-shot 성능이 raw LM 대비 큰 폭 개선.&lt;/p&gt;
&lt;h3 id=&quot;t0-sanh-et-al-2022&quot;&gt;T0 (Sanh et al., 2022)&lt;/h3&gt;
&lt;p&gt;Multitask prompted training. 다양한 프롬프트 템플릿을 학습하여 새 지시문 형태에도 robust.&lt;/p&gt;
&lt;h3 id=&quot;instructgpt--rlhf&quot;&gt;InstructGPT / RLHF&lt;/h3&gt;
&lt;p&gt;Ouyang et al. (2022) 는 사람 라벨러의 지시문 예시로 SFT + PPO. ChatGPT 계보의 시작. Zero-shot 이 사실상 표준이 된 계기.&lt;/p&gt;
&lt;h3 id=&quot;오늘의-instruction-tuned-모델&quot;&gt;오늘의 instruction-tuned 모델&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI GPT-4o, GPT-5, o1/o3&lt;/li&gt;
&lt;li&gt;Anthropic Claude 3.5/3.7/4/Opus 4&lt;/li&gt;
&lt;li&gt;Google Gemini 2.5 Pro/Flash&lt;/li&gt;
&lt;li&gt;Meta Llama 3.3, Llama 4&lt;/li&gt;
&lt;li&gt;DeepSeek V3, R1&lt;/li&gt;
&lt;li&gt;Mistral Large 2, Ministral&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;모두 zero-shot 시나리오를 기본으로 튜닝되어 있고, 실전 사용의 90%+ 는 zero-shot 형태입니다.&lt;/p&gt;
&lt;h2 id=&quot;잘-쓰는-지시문의-원칙&quot;&gt;잘 쓰는 지시문의 원칙&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;구체적 태스크 정의&lt;/strong&gt;: “이 텍스트를 요약하시오” 보다 “다음 뉴스 기사를 3문장 이하 한국어로 요약하시오”.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;출력 형식 명시&lt;/strong&gt;: JSON 객체로 답하되 &lt;code&gt;{&quot;summary&quot;: ..., &quot;keywords&quot;: [...]}&lt;/code&gt; 형태.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;제약 명시&lt;/strong&gt;: “고유명사를 그대로 유지”. “300자 이내”.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;역할 부여 (선택)&lt;/strong&gt;: “당신은 시니어 백엔드 엔지니어입니다”. 스타일 조정에는 유효, 정확도에는 미미.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분리자 사용&lt;/strong&gt;: &lt;code&gt;&amp;#x3C;입력&gt;...&amp;#x3C;/입력&gt;&lt;/code&gt;, &lt;code&gt;###&lt;/code&gt;, &lt;code&gt;---&lt;/code&gt; 로 지시문과 데이터 경계 명확화.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;부정보다 긍정 지시&lt;/strong&gt;: “하지 마세요” 보다 “이렇게 하세요”. 부정문은 놓치기 쉬움.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Claude 계열에는 XML 구분자가 특히 효과적입니다:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;instruction&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;다음 고객 이메일의 의도를 분류하시오.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;분류 결과: INQUIRY, COMPLAINT, REFUND_REQUEST, OTHER 중 하나&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/instruction&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;email&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{email_body}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/email&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;분류:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;실전-예시&quot;&gt;실전 예시&lt;/h2&gt;
&lt;h3 id=&quot;감정-분석&quot;&gt;감정 분석&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;당신은 한국어 고객 리뷰 분석기입니다.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;아래 리뷰의 감정을 POSITIVE, NEGATIVE, NEUTRAL 중 하나로만 답하시오.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;리뷰: &quot;배송은 빠른데 포장이 엉망이었어요. 제품 자체는 괜찮습니다.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;감정:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예상 출력: &lt;code&gt;NEUTRAL&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;구조화-json-추출&quot;&gt;구조화 JSON 추출&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;다음 채용 공고에서 정보를 추출해 JSON 으로 반환하시오.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;형식: {&quot;role&quot;: &quot;...&quot;, &quot;company&quot;: &quot;...&quot;, &quot;skills&quot;: [...], &quot;location&quot;: &quot;...&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;텍스트: (주)테크스타트에서 시니어 백엔드 엔지니어를 채용합니다.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;주요 기술: Java, Spring Boot, Kubernetes. 서울 강남 근무.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;JSON:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;zero-shot-cot-수학-문제&quot;&gt;Zero-shot CoT: 수학 문제&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;다음 문제를 단계별로 풀이하시오.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;문제: 사과가 32개 있다. 4명이 균등하게 나누면 각자 몇 개씩 받는가?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;단계별 풀이:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;python-에서-zero-shot-호출&quot;&gt;Python 에서 zero-shot 호출&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; openai &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; zero_shot&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(instruction: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, input_text: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        temperature&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: instruction},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: input_text},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.choices[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].message.content.strip()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 감정 분석&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; zero_shot(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    instruction&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;고객 리뷰를 POSITIVE, NEGATIVE, NEUTRAL 중 하나로 분류하시오.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    input_text&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;배송이 빠르고 포장도 깔끔해서 아주 만족합니다.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result)  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# &quot;POSITIVE&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;성능-한계&quot;&gt;성능 한계&lt;/h2&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;한계 상황&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;원인&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;대안&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;사내 고유 분류 체계&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지시문으로 표현 어려움&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;few-shot 예시 추가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;10개 이상 라벨 분류&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;라벨 집합이 너무 큼&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;few-shot 또는 파인튜닝&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;엄격한 구조 출력&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;형식 오류율 높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;[[function-calling&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;도메인 특화 어휘&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사전학습에 희소&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;few-shot + [[llm-rag&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;수치 추론 및 계산&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;직접 계산 실수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;zero-shot CoT 또는 code interpreter&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;모호한 태스크에서 오답률이 급등합니다.&lt;/strong&gt; 라벨 후보가 표준적이지 않거나 (예: 5단계 감정, 자체 스키마), 도메인 특수 어휘가 나오면 예시 없이 정확히 맞추기 어렵습니다. 이럴 때는 최소한 one-shot 이라도 붙여야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;잘못된 지시문에 순응합니다.&lt;/strong&gt; 지시문에 모순이 있어도 모델은 대개 뭐라도 답하려 합니다. 이상한 라벨 조합, 존재하지 않는 태스크 이름에도 그럴싸한 답을 내니, 지시문 자체의 검증이 필요합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Zero-shot 은 재현성이 낮을 수 있습니다.&lt;/strong&gt; temperature=0 이어도 시스템 프롬프트, 컨텍스트 캐시, provider 백엔드 상태에 따라 결과가 흔들립니다. 여러 시드로 평균 내는 편이 안전.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;모델별로 최적 지시문 스타일이 다릅니다.&lt;/strong&gt; GPT 는 markdown 을 잘 따르고, Claude 는 XML 구분자에 강하고, Gemini 는 구조화된 프롬프트에 반응이 좋습니다. 이식성이 필요하면 공통 최소분모 형식으로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;언제-zero-shot-을-쓰나&quot;&gt;언제 zero-shot 을 쓰나&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;간단한 요약, 번역, 감정 분석&lt;/strong&gt; (표준 태스크)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자연어 인터페이스 (챗봇)&lt;/strong&gt;: 사용자 발화가 매번 달라 few-shot 이 무의미&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용 최소화&lt;/strong&gt;: 대량 배치 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;탐색적 태스크 정의&lt;/strong&gt;: 프롬프트 반복 실험 초기 단계&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;언제-zero-shot-대신-few-shot-이-낫나&quot;&gt;언제 zero-shot 대신 few-shot 이 낫나&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;출력 스키마가 매우 엄격 (JSON 스펙, 특정 XML)&lt;/li&gt;
&lt;li&gt;도메인 특화 (법률, 의료, 사내 용어)&lt;/li&gt;
&lt;li&gt;분류 라벨이 비표준&lt;/li&gt;
&lt;li&gt;예시가 지시문보다 훨씬 짧고 명확할 때&lt;/li&gt;
&lt;li&gt;모델이 instruction tuning 이 약한 (base model) 계열일 때&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[one-shot-prompting|One-Shot Prompting]] - K=1, zero-shot 과 few-shot 의 경계&lt;/li&gt;
&lt;li&gt;[[few-shot-prompting|Few-Shot Prompting]] - K&gt;=2, 예시 기반&lt;/li&gt;
&lt;li&gt;[[chain-of-thought|Chain-of-Thought]] - Zero-shot CoT 는 “step by step” 확장&lt;/li&gt;
&lt;li&gt;[[function-calling|Function Calling]] - 함수 스키마로 zero-shot 강화&lt;/li&gt;
&lt;li&gt;[[llm-rag|LLM RAG]] - 지시문에 검색 결과 삽입&lt;/li&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] - zero-shot 벤치마크 축&lt;/li&gt;
&lt;li&gt;[[big-bench|BIG-Bench]] - zero-shot 일반화 평가&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>prompting</category><category>instruction-tuning</category><author>koa (김신건)</author></item><item><title>[Voice AI] Voice RAG: 지연 병목 + 예측적 프리페치</title><link>https://shinkeonkim.com/wiki/ai/voice-rag/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/voice-rag/</guid><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Voice RAG&lt;/strong&gt; = 음성 에이전트에 &lt;em&gt;RAG (Retrieval-Augmented Generation)&lt;/em&gt; 결합. &lt;em&gt;벡터 DB 조회&lt;/em&gt; 가 &lt;em&gt;지연 누적&lt;/em&gt; 의 큰 원인이 되므로 &lt;em&gt;예측적 프리페치&lt;/em&gt; 같은 패턴 필수.&lt;/p&gt;
&lt;p&gt;음성 응답 허용 지연(Time to First Audio)은 일반적으로 1.5-2초 이하를 목표로 하는데, 기존 RAG 파이프라인의 직렬 구조는 이 예산을 쉽게 초과합니다.&lt;/p&gt;
&lt;h2 id=&quot;언제-쓰이나&quot;&gt;언제 쓰이나&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;도메인 지식 필요 음성 에이전트&lt;/strong&gt;: 콜센터, 의료 Q&amp;#x26;A, 사내 챗봇&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;실시간 대화 + 사실 근거&lt;/strong&gt;: 환각을 줄이고 정확한 출처 기반 답변 필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;다회차 음성 대화&lt;/strong&gt;: 이전 발화 컨텍스트 + 외부 지식 결합&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;전체-파이프라인&quot;&gt;전체 파이프라인&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant User as 사용자&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant VAD as VAD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant STT as STT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant RAG as RAG&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant LLM as LLM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant TTS as TTS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;VAD: 음성 스트림&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    VAD--&gt;&gt;STT: End-of-Speech 감지&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    STT--&gt;&gt;RAG: 전사 텍스트&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over STT,RAG: partial 수신 시 미리 prefetch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RAG--&gt;&gt;LLM: 질문 + 관련 청크&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM--&gt;&gt;TTS: 응답 토큰 (streaming)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TTS--&gt;&gt;User: 음성 청크 (streaming)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;각 단계가 직렬&lt;/em&gt;. RAG 추가 &lt;em&gt;200-1000ms&lt;/em&gt; → 종단 지연 &lt;em&gt;2초+&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;지연-분해&quot;&gt;지연 분해&lt;/h2&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;단계&lt;/th&gt;&lt;th&gt;일반&lt;/th&gt;&lt;th&gt;최적&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;STT (Whisper 등)&lt;/td&gt;&lt;td&gt;200-500ms&lt;/td&gt;&lt;td&gt;50ms (streaming + local)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Embedding&lt;/td&gt;&lt;td&gt;50-200ms&lt;/td&gt;&lt;td&gt;30ms (로컬 small 모델)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Vector DB query&lt;/td&gt;&lt;td&gt;30-200ms&lt;/td&gt;&lt;td&gt;10ms (Redis vector, ES kNN)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Re-ranking&lt;/td&gt;&lt;td&gt;100-500ms&lt;/td&gt;&lt;td&gt;50ms (cross-encoder small)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LLM prompt assembly&lt;/td&gt;&lt;td&gt;5-20ms&lt;/td&gt;&lt;td&gt;5ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LLM TTFT (first token)&lt;/td&gt;&lt;td&gt;200-800ms&lt;/td&gt;&lt;td&gt;100ms (cached prefix)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TTS (first audio)&lt;/td&gt;&lt;td&gt;100-300ms&lt;/td&gt;&lt;td&gt;50ms (streaming)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;RAG overhead&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;200-1000ms&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;&amp;#x3C; 100ms&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;지연-예산-할당&quot;&gt;지연 예산 할당&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Budget[&quot;총 예산\n1500ms&quot;] --&gt; STT_b[&quot;STT\n100ms&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Budget --&gt; RAG_b[&quot;RAG\n100ms&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Budget --&gt; LLM_b[&quot;LLM TTFT\n200ms&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Budget --&gt; TTS_b[&quot;TTS first audio\n100ms&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Budget --&gt; Margin[&quot;마진\n1000ms&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;vad-voice-activity-detection&quot;&gt;VAD (Voice Activity Detection)&lt;/h2&gt;
&lt;p&gt;발화 시작/종료를 감지하는 첫 단계. End-of-Speech 감지 정확도가 UX 를 결정합니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; webrtcvad&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; VADHandler&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, aggressiveness: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, sample_rate: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.vad &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; webrtcvad.Vad(aggressiveness)  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 0~3, 3 = 가장 민감&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.sample_rate &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sample_rate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.frame_ms &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 30&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  # 10, 20, 30ms 중 하나&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.speech_frames: list[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.silence_count &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;SILENCE_THRESHOLD&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 20&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  # 연속 silence frame 수&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; process_frame&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, frame: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; None&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;&quot;&quot;Return &apos;START&apos;, &apos;CONTINUE&apos;, &apos;END&apos;, or None&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        is_speech &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.vad.is_speech(frame, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.sample_rate)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; is_speech:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.silence_count &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.speech_frames.append(frame)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;CONTINUE&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.silence_count &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.silence_count &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;SILENCE_THRESHOLD&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; and&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.speech_frames:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                audio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.join(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.speech_frames)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;                self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.speech_frames &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;END&quot;&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  # 발화 종료&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; None&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;예측적-프리페치-speculative-retrieval&quot;&gt;예측적 프리페치 (Speculative Retrieval)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Partial[&quot;Partial transcript&quot;] --&gt; Predict[&quot;가능 의도 예측&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Predict --&gt; Pre[&quot;미리 fetch (병렬)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Final[&quot;Final transcript&quot;] --&gt; Match{예측 매칭?}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Match --&gt;|예| UsePre[&quot;프리페치 결과 사용&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Match --&gt;|아니오| Re[&quot;다시 fetch&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SpeculativeRAG&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.prefetched: Dict[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, Future] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; on_partial&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, partial: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;&quot;&quot;partial 받자마자 예측 fetch 시작&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(partial.split()) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;   # 너무 짧으면 skip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        # 이미 fetch 중인 것이 있고 유사하면 재사용&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; any&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;._similar(partial, k) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; k &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.prefetched):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        # 미리 fetch (병렬)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        fut &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; asyncio.create_task(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;._retrieve(partial))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.prefetched[partial] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fut&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; on_final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, final: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; List[Chunk]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;&quot;&quot;final 시 prefetched 결과 활용 또는 새로 fetch&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        # 가장 유사한 prefetched 찾기&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        best &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.prefetched.keys(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;                   key&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=lambda&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; k: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;._similarity(k, final),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;                   default&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; best &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;._similarity(best, final) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0.85&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.prefetched[best]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;._retrieve(final)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;partial 받자마자 추측 fetch&lt;/em&gt; → final 시 &lt;em&gt;대부분 즉시 사용 가능&lt;/em&gt;. RAG overhead → 0 에 가깝게.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;캐시-계층&quot;&gt;캐시 계층&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q[Query] --&gt; L1[&quot;L1: in-memory recent (LRU)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L1 -.miss.-&gt; L2[&quot;L2: Redis semantic cache&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L2 -.miss.-&gt; L3[&quot;L3: Vector DB&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L3 --&gt; Pop[&quot;populate L2 + L1&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;semantic-cache&quot;&gt;Semantic Cache&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SemanticCache&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;&quot;&quot;비슷한 질문의 결과 재사용&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, similarity_threshold&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.92&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.cache &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {}   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# embedding → result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.threshold &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; similarity_threshold&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, query: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        emb &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; embed(query)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cached_emb, result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.cache.items():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            sim &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cosine_similarity(emb, cached_emb)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sim &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.threshold:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; None&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자세한 건 [[Redis Vector Search]] 의 semantic cache.&lt;/p&gt;
&lt;h2 id=&quot;streaming-tts-패턴&quot;&gt;Streaming TTS 패턴&lt;/h2&gt;
&lt;p&gt;LLM 응답을 기다렸다가 한번에 TTS 에 넘기면 추가 지연이 발생합니다. 토큰 단위로 스트리밍해 첫 문장이 완성되는 즉시 TTS 를 시작합니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stream_response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(llm_stream, tts_client):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;&quot;&quot;LLM 토큰을 문장 단위로 누적, 문장 완성 즉시 TTS 로 전달&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    buffer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    SENTENCE_END&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;?&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;。&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;！&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;？&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; token &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm_stream:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        buffer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; token&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        # 문장 끝 감지&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; buffer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; buffer[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; SENTENCE_END&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            sentence &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; buffer.strip()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                # 문장 완성 즉시 TTS 트리거 (비동기)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                asyncio.create_task(tts_client.speak(sentence))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            buffer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # 남은 텍스트 처리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; buffer.strip():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tts_client.speak(buffer.strip())&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;rag-인덱스-선택-음성-환경&quot;&gt;RAG 인덱스 선택 (음성 환경)&lt;/h2&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Pinecone&lt;/th&gt;&lt;th&gt;Redis Vector&lt;/th&gt;&lt;th&gt;ES kNN&lt;/th&gt;&lt;th&gt;Qdrant&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Latency (kNN)&lt;/td&gt;&lt;td&gt;30-100ms&lt;/td&gt;&lt;td&gt;5-20ms&lt;/td&gt;&lt;td&gt;20-50ms&lt;/td&gt;&lt;td&gt;10-30ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;운영&lt;/td&gt;&lt;td&gt;managed&lt;/td&gt;&lt;td&gt;익숙&lt;/td&gt;&lt;td&gt;익숙&lt;/td&gt;&lt;td&gt;중간&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Hybrid (BM25 + vector)&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;별도&lt;/td&gt;&lt;td&gt;&lt;em&gt;우수 (RRF)&lt;/em&gt;&lt;/td&gt;&lt;td&gt;가능&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;음성 에이전트 + 한국어 hybrid search = &lt;em&gt;ElasticSearch kNN + nori&lt;/em&gt; 가 강력.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;청크-전략-음성-친화&quot;&gt;청크 전략 (음성 친화)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 일반 RAG: 큰 청크 (500-1000 tokens)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 음성 RAG: *짧은 청크* (100-300 tokens) → LLM 응답 짧게 유도&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; chunk_for_voice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(doc: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; list[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;&quot;&quot;문장 단위 + 의미 단위 분할&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    sentences &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; nltk.sent_tokenize(doc, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;language&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;korean&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    chunks &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    cur &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; s &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentences:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(cur) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(s) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 300&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            chunks.append(cur)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            cur &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            cur &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cur:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chunks.append(cur)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chunks&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;짧은 청크는 검색 정밀도를 높이고 LLM 이 짧고 자연스러운 음성 응답을 생성하도록 유도합니다.&lt;/p&gt;
&lt;h2 id=&quot;re-ranking-의-trade-off&quot;&gt;Re-ranking 의 trade-off&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    VS[&quot;Vector Search top 50&quot;] --&gt; Re[&quot;Re-ranker&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Re --&gt; Top5[&quot;top 5&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Re --&gt; Cost[&quot;+100-500ms&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;정확도 ↑ vs 지연 ↑&lt;/em&gt;. 음성 에이전트는 &lt;em&gt;작은 cross-encoder&lt;/em&gt; (Cohere rerank-v3 light, BAAI bge-reranker-base) 권장.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RAG 매 turn 동기 fetch&lt;/strong&gt; = 매 응답 200-1000ms 증가. &lt;em&gt;예측적 프리페치&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;거대 청크&lt;/strong&gt; = LLM 응답이 길어짐. 짧은 청크 (100-300 tokens).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-encoder rerank 무조건&lt;/strong&gt; = 500ms+ 부담. &lt;em&gt;trade-off&lt;/em&gt; 결정.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결과 그대로 prompt&lt;/strong&gt; = 토큰 폭증. 요약 또는 selection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VAD 미사용&lt;/strong&gt; = 발화 종료 감지가 느려 STT 에 불필요한 silence 포함. 지연 증가.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Semantic cache 유사도 임계값을 낮추면 오답 반환 위험이 생깁니다.&lt;/strong&gt; 0.92 이하에서는 의미가 다른 질의의 캐시 결과를 반환할 수 있습니다. 도메인 특성에 맞게 검증 후 설정하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[voice-agent-architecture]]&lt;/li&gt;
&lt;li&gt;[[voice-first-prompt]]&lt;/li&gt;
&lt;li&gt;[[elasticsearch-vector-search]]&lt;/li&gt;
&lt;li&gt;[[Redis Vector Search]]&lt;/li&gt;
&lt;li&gt;[[latency-percentiles]]&lt;/li&gt;
&lt;li&gt;[[llm-rag|LLM RAG]] - 일반 RAG 파이프라인&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>voice-rag</category><category>rag</category><category>vector-db</category><category>latency</category><category>prefetch</category><author>koa (김신건)</author></item><item><title>[Prompting] One-Shot Prompting</title><link>https://shinkeonkim.com/wiki/ai/one-shot-prompting/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/one-shot-prompting/</guid><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;One-shot prompting&lt;/strong&gt; 은 프롬프트에 &lt;strong&gt;정확히 1개의 입력-출력 예시&lt;/strong&gt; 를 함께 제공하는 프롬프팅입니다. K=1 인 [[few-shot-prompting|few-shot]] 의 특수 케이스이자 [[zero-shot-prompting|zero-shot]] 과 few-shot 사이의 경계입니다.&lt;/p&gt;
&lt;p&gt;GPT-3 논문 (Brown et al., 2020) 이 zero-shot / one-shot / few-shot 세 축으로 실험 테이블을 구성하면서 명확한 용어로 자리잡았습니다.&lt;/p&gt;
&lt;h2 id=&quot;in-context-learning-스펙트럼&quot;&gt;In-Context Learning 스펙트럼&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ZS[&quot;Zero-Shot\nK=0\n예시 없음\n지시문만&quot;] --&gt; OS[&quot;One-Shot\nK=1\n예시 1개&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    OS --&gt; FS[&quot;Few-Shot\nK=2+\n예시 2개 이상&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    FS --&gt; FT[&quot;Fine-Tuning\n가중치 업데이트\n별도 학습&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    style OS fill:#f0f4ff,stroke:#4466cc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;방법&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;예시 수&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;형식 강제력&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;비용&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Zero-Shot&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;0&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최소&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;One-Shot&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&lt;strong&gt;중간&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;소폭 증가&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Few-Shot&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2+&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;K 배 증가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Fine-Tuning&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;수천&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;매우 높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;학습 비용&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;언제-쓰나&quot;&gt;언제 쓰나&lt;/h2&gt;
&lt;p&gt;One-shot 이 유용한 지점은 좁습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;출력 형식만 강제&lt;/strong&gt; 하고 싶을 때 (JSON 스키마, 특정 어투)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;예시 하나로 충분한 단순 매핑&lt;/strong&gt; (레이블 몇 개 안 되는 분류, 도메인 없는 정렬 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컨텍스트 예산이 빡빡&lt;/strong&gt; 해서 예시를 더 많이 못 넣을 때&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일럿 실험&lt;/strong&gt;: few-shot 으로 확장하기 전에 K=1 로 형식만 맞춰 보기&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;기본-구조&quot;&gt;기본 구조&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{지시문}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Input: {예시 입력}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Output: {예시 출력}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Input: {실제 질의}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Output:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Chat API 에서는 user/assistant 각 1회 왕복 예시:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;다음 문장을 formal 한국어로 다시 써 주세요.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;야 이거 어떻게 해?&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;이것을 어떻게 처리하면 좋을까요?&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{실제 입력}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;zero-shot--few-shot-과-비교&quot;&gt;Zero-Shot / Few-Shot 과 비교&lt;/h2&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Zero-shot&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;One-shot&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Few-shot&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;예시 수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;0&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;2 이상&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;형식 강제력&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음 (지시문만)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;도메인 규칙 학습&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;안 됨&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;어렵&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;가능&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;입력 비용&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최소&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소폭 증가&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;K 배 증가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Recency bias&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;유일한 예시 = 강한 앵커&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;마지막 예시 편중&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;핵심&lt;/strong&gt;: One-shot 예시는 유일하므로 그 자체가 &lt;strong&gt;강한 앵커&lt;/strong&gt; 로 작용합니다. Recency bias 를 다양화로 완화할 방법이 없어, 예시가 대표성을 잃으면 &lt;strong&gt;오히려 zero-shot 보다 성능이 나빠질 수 있습니다&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;min-et-al-재조명&quot;&gt;Min et al. 재조명&lt;/h2&gt;
&lt;p&gt;Min et al. (2022) “Rethinking the Role of Demonstrations” 결과가 one-shot 에도 적용됩니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;예시의 &lt;strong&gt;입력 도메인&lt;/strong&gt; 이 실제 질의와 다르면 큰 손해&lt;/li&gt;
&lt;li&gt;예시의 &lt;strong&gt;라벨&lt;/strong&gt; 을 랜덤으로 바꿔도 성능이 크게 안 떨어지는 경우 (형식 시그널이 지배)&lt;/li&gt;
&lt;li&gt;예시가 &lt;strong&gt;형식 스펙만 알려주고&lt;/strong&gt; 실제 규칙은 지시문이 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이는 one-shot 에서 특히 강하게 나타납니다: 한 예시가 모든 신호를 담당하기 때문.&lt;/p&gt;
&lt;h2 id=&quot;chain-of-thought-와-결합&quot;&gt;Chain-of-Thought 와 결합&lt;/h2&gt;
&lt;p&gt;One-shot + [[chain-of-thought|CoT]] 는 흔한 조합. 사슬 예시 1개를 넣어 형식과 추론 스타일 모두 유도:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: If a train leaves at 3pm and travels 60 mph for 2 hours, where is it?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: The train travels 60 miles per hour. After 2 hours it has gone 60 * 2 = 120 miles.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   The answer is 120 miles from the start.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: {question}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 방식이 zero-shot CoT (“Let’s think step by step”) 보다 정확도가 높을 때가 많습니다. 형식과 사슬 스타일을 모두 명시하기 때문.&lt;/p&gt;
&lt;h2 id=&quot;예시-선택-기준&quot;&gt;예시 선택 기준&lt;/h2&gt;
&lt;p&gt;One-shot 은 예시 하나가 결과를 좌우하므로 &lt;strong&gt;선택이 매우 중요&lt;/strong&gt;합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;대표성&lt;/strong&gt;: 실제 질의 분포의 중앙에 있는 예시&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정보량&lt;/strong&gt;: 지시문에서 놓친 규칙을 예시가 채워줌&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;간결성&lt;/strong&gt;: 너무 긴 예시는 컨텍스트 낭비 + 모델 주의 분산&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;명확한 라벨&lt;/strong&gt;: 애매한 경계 케이스는 오히려 혼선&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;프로덕션에서는 &lt;strong&gt;입력을 임베딩해 유사도 top-1 예시&lt;/strong&gt; 를 동적으로 선택하는 retrieval-based one-shot 이 실전에서 강합니다.&lt;/p&gt;
&lt;h2 id=&quot;실전-예시&quot;&gt;실전 예시&lt;/h2&gt;
&lt;h3 id=&quot;감성-분류&quot;&gt;감성 분류&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;prompt &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&quot;Classify the sentiment of the review as Positive or Negative.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Review: &quot;The food was absolutely amazing and the staff was super friendly!&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Sentiment: Positive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Review: &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{review}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Sentiment:&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;구조화-출력-json-스키마-강제&quot;&gt;구조화 출력 (JSON 스키마 강제)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;prompt &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&quot;Extract the key information from the meeting note as JSON.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Note: &quot;Team sync on Jan 5. Attendees: Alice, Bob. Action items: Alice to send report by Jan 10.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;JSON: {&quot;date&quot;: &quot;Jan 5&quot;, &quot;attendees&quot;: [&quot;Alice&quot;, &quot;Bob&quot;], &quot;action_items&quot;: [{&quot;owner&quot;: &quot;Alice&quot;, &quot;task&quot;: &quot;send report&quot;, &quot;due&quot;: &quot;Jan 10&quot;}]}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Note: &quot;{meeting_note}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;JSON:&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;코드-변환-python-to-typescript&quot;&gt;코드 변환 (Python to TypeScript)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;prompt &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&quot;Convert the Python function to TypeScript.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Python:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;def add(a: int, b: int) -&gt; int:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    return a + b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TypeScript:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;function add(a: number, b: number): number {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    return a + b;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Python:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{python_code}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TypeScript:&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;retrieval-based-one-shot-동적-예시-선택&quot;&gt;Retrieval-Based One-Shot (동적 예시 선택)&lt;/h2&gt;
&lt;p&gt;정적으로 예시를 고르지 않고, 입력과 가장 유사한 예시를 예시 풀에서 검색해 삽입. [[llm-rag|RAG]] 와 결합한 패턴이다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence_transformers &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SentenceTransformer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numpy &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; np&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SentenceTransformer(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;all-MiniLM-L6-v2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 예시 풀 (질의, 정답) 쌍&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;example_pool &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;What is the capital of France?&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;The capital of France is Paris.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    (&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;How do I sort a list in Python?&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Use list.sort() or sorted(list).&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # ... 수백~수천 개&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 오프라인: 예시 임베딩&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;example_embeddings &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model.encode([ex[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ex &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; example_pool])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; select_one_shot_example&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(query: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; tuple[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    q_emb &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; model.encode([query])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    scores &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; np.dot(example_embeddings, q_emb.T).squeeze()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    best_idx &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; scores.argmax()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; example_pool[best_idx]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;query &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;What is the tallest mountain in the world?&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ex_input, ex_output &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; select_one_shot_example(query)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;prompt &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;Answer the geography question.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Q: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ex_input&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;A: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ex_output&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Q: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;A:&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;one-shot-결정-플로우&quot;&gt;One-Shot 결정 플로우&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Start[&quot;새 프롬프트 설계&quot;] --&gt; Q1{&quot;출력 형식만\n강제하면 되나?&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|Yes| Q2{&quot;structured output\nAPI 지원?&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q2 --&gt;|Yes| SO[&quot;response_format / JSON schema\n(One-shot 불필요)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q2 --&gt;|No| OS[&quot;One-Shot 사용&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|No| Q3{&quot;도메인 규칙\n학습 필요?&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q3 --&gt;|No| OS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q3 --&gt;|Yes| Q4{&quot;컨텍스트 예산?&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q4 --&gt;|&quot;빡빡&quot;| OS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q4 --&gt;|&quot;여유 있음&quot;| FS[&quot;Few-Shot (K&gt;=3)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;언제-one-shot-이-최적인가&quot;&gt;언제 One-shot 이 최적인가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;예시가 실제 질의와 매우 유사할 때 (retrieval-augmented one-shot)&lt;/li&gt;
&lt;li&gt;지시문 + 예시 조합이 API 응답 스키마를 명확히 고정할 때&lt;/li&gt;
&lt;li&gt;CoT 스타일을 정확히 지정하고 싶을 때 (사슬 예시 1개)&lt;/li&gt;
&lt;li&gt;컨텍스트 예산이 매우 제한적 (모바일 온디바이스 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;잘못된 예시는 zero-shot 보다 나쁩니다.&lt;/strong&gt; 지시문에는 없는 이상한 형식/스타일을 예시가 강제하면 모델이 그것을 따라갑니다. One-shot 은 그 예시가 유일한 신호이므로 잘못된 예시의 영향이 특히 큽니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;엣지 케이스를 커버 못 합니다.&lt;/strong&gt; 한 예시로 모든 케이스를 담을 수 없어, 예상 밖 입력에는 모델이 형식만 따르고 규칙은 놓치는 경우가 자주 발생합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Instruction-tuned 최신 모델 (GPT-4o, Claude 3.5+, Gemini 2.0+) 에서는 zero-shot 만으로 충분한 경우가 많아졌습니다.&lt;/strong&gt; 형식 강제가 목표라면 one-shot 대신 structured output (&lt;code&gt;response_format&lt;/code&gt;, JSON schema) 을 쓰는 편이 안정적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[zero-shot-prompting|Zero-Shot Prompting]] - K=0&lt;/li&gt;
&lt;li&gt;[[few-shot-prompting|Few-Shot Prompting]] - K&gt;=2&lt;/li&gt;
&lt;li&gt;[[chain-of-thought|Chain-of-Thought]] - one-shot CoT 조합&lt;/li&gt;
&lt;li&gt;[[function-calling|Function Calling]] - 형식 강제의 대안&lt;/li&gt;
&lt;li&gt;[[llm-rag|LLM RAG]] - 유사도 기반 예시 검색&lt;/li&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] - 다양한 shot 조건에서의 평가&lt;/li&gt;
&lt;li&gt;[[big-bench|BIG-Bench]] - one-shot 성능 다양성 실험&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>prompting</category><category>in-context-learning</category><author>koa (김신건)</author></item><item><title>Function Calling / Tool Use: LLM 도구 사용</title><link>https://shinkeonkim.com/wiki/ai/function-calling/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/function-calling/</guid><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Function Calling&lt;/strong&gt; (또는 &lt;strong&gt;Tool Use&lt;/strong&gt;) 은 LLM 이 사전 정의된 함수/도구를 &lt;strong&gt;호출하기 위한 인자를 JSON 으로 생성&lt;/strong&gt; 하는 기능. JSON Schema 로 함수 시그니처를 알려주면, LLM 이 사용자 질의에 맞는 함수와 인자를 선택해 반환한다.&lt;/p&gt;
&lt;p&gt;실제 함수 실행은 LLM 이 아닌 &lt;strong&gt;애플리케이션 코드&lt;/strong&gt;가 담당. LLM 은 오직 “어떤 함수를, 어떤 인자로 호출할지” 만 결정한다.&lt;/p&gt;
&lt;h2 id=&quot;언제-쓰이나&quot;&gt;언제 쓰이나&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;외부 API 연동 (날씨, 주식, 검색)&lt;/li&gt;
&lt;li&gt;데이터베이스 쿼리 자동화&lt;/li&gt;
&lt;li&gt;LLM 이 직접 수행 불가능한 작업 (계산, 코드 실행, 파일 읽기)&lt;/li&gt;
&lt;li&gt;[[agent-patterns|AI 에이전트]] 구현 (ReAct, Plan-and-Execute)&lt;/li&gt;
&lt;li&gt;구조화된 데이터 추출&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;전체-흐름&quot;&gt;전체 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant User as 사용자&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant App as 애플리케이션&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant LLM as LLM API&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    participant Tool as 실제 도구&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;App: &quot;서울 날씨 알려줘&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    App-&gt;&gt;LLM: 메시지 + tool 정의 전송&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM--&gt;&gt;App: tool_call (get_weather, city=Seoul)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    App-&gt;&gt;Tool: get_weather(&quot;Seoul&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Tool--&gt;&gt;App: {temp: 22, condition: &quot;sunny&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    App-&gt;&gt;LLM: tool 결과 재주입&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM--&gt;&gt;App: &quot;서울은 현재 22도로 맑습니다&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    App--&gt;&gt;User: 최종 답변&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;json-schema-로-도구-정의&quot;&gt;JSON Schema 로 도구 정의&lt;/h2&gt;
&lt;h3 id=&quot;openai-형식&quot;&gt;OpenAI 형식&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;특정 도시의 현재 날씨 조회. 도시명은 영어로.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;parameters&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;도시 이름 (예: Seoul, Tokyo)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;unit&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;enum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;F&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;온도 단위&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;default&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;additionalProperties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;strict&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;anthropic-claude-형식&quot;&gt;Anthropic (Claude) 형식&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;특정 도시의 현재 날씨 조회&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;input_schema&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;unit&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;enum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;F&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;code&gt;description&lt;/code&gt; 이 가장 중요하다. LLM 은 description 을 읽고 어떤 도구를 언제 호출할지 결정. 명확하고 구체적인 설명이 할루시네이션을 줄인다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;openai-vs-anthropic-vs-gemini-비교&quot;&gt;OpenAI vs Anthropic vs Gemini 비교&lt;/h2&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;항목&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;OpenAI&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Anthropic Claude&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Google Gemini&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;필드명&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tools&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tools&lt;/code&gt;, &lt;code&gt;input_schema&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tools&lt;/code&gt;, &lt;code&gt;function_declarations&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;결과 전달&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tool_call_id&lt;/code&gt; + &lt;code&gt;role: tool&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tool_use_id&lt;/code&gt; + &lt;code&gt;role: user&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;function_response&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;병렬 호출&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tool_calls[]&lt;/code&gt; (배열)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;응답에 여러 &lt;code&gt;tool_use&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;function_calls[]&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;strict mode&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;&quot;strict&quot;: true&lt;/code&gt; (JSON 강제)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;멀티턴&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tool_call_id&lt;/code&gt; 로 매칭&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;tool_use_id&lt;/code&gt; 로 매칭&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;id&lt;/code&gt; 로 매칭&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;실전-코드&quot;&gt;실전 코드&lt;/h2&gt;
&lt;h3 id=&quot;openai-python-sdk&quot;&gt;OpenAI Python SDK&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; openai &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;현재 날씨 조회&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;parameters&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;unit&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;enum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;F&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get_weather&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(city: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, unit: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;C&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # 실제 날씨 API 호출&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;condition&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;sunny&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: city}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 1단계: LLM 호출&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;서울 날씨 알려줘&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tools&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tool_choice&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;auto&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.choices[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 2단계: tool_calls 처리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; message.tool_calls:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    messages &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;서울 날씨 알려줘&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        message,  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# assistant 의 tool_call 메시지&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; message.tool_calls:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        args &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; json.loads(tc.function.arguments)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; get_weather(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;args)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        messages.append({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tool&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;tool_call_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: tc.id,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: json.dumps(result, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;ensure_ascii&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;False&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # 3단계: 결과 재주입 후 최종 답변&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    final &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(final.choices[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].message.content)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;anthropic-python-sdk&quot;&gt;Anthropic Python SDK&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; anthropic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; anthropic.Anthropic()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;현재 날씨 조회&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;input_schema&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.messages.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;claude-opus-4-5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    max_tokens&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tools&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;서울 날씨 알려줘&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# stop_reason == &quot;tool_use&quot; 인 경우 처리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.stop_reason &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;tool_use&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    tool_use &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(b &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.content &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b.type &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;tool_use&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; get_weather(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tool_use.input)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    final &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.messages.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;claude-opus-4-5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        max_tokens&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        tools&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;서울 날씨 알려줘&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assistant&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: response.content},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tool_result&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;tool_use_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: tool_use.id,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: json.dumps(result, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;ensure_ascii&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;False&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                }]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;병렬-tool-call&quot;&gt;병렬 Tool Call&lt;/h2&gt;
&lt;p&gt;LLM 이 여러 도구를 동시에 호출해야 할 때 배열로 반환:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;tool_calls&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;call_1&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;arguments&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;city&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Seoul&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;call_2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;arguments&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;city&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Tokyo&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;call_3&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_stock&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,  &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;arguments&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;symbol&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;AAPL&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;병렬로 실행 후 결과를 한꺼번에 재주입:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; asyncio&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; handle_parallel_tools&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tool_calls):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    tasks &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tool_calls:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        args &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; json.loads(tc.function.arguments)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tc.function.name &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            tasks.append(get_weather_async(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;args))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        elif&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tc.function.name &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;get_stock&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            tasks.append(get_stock_async(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;args))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; asyncio.gather(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tasks)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;mcp-model-context-protocol&quot;&gt;MCP (Model Context Protocol)&lt;/h2&gt;
&lt;p&gt;Anthropic 이 2024년 발표한 &lt;strong&gt;표준화 프로토콜&lt;/strong&gt;. Function calling 의 생태계 문제(각 공급사마다 다른 형식)를 해결.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM[&quot;Claude / GPT / Gemini&quot;] &amp;#x3C;--&gt;|&quot;MCP 프로토콜&quot;| Server[&quot;MCP Server&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Server --&gt; FS[&quot;파일 시스템&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Server --&gt; DB[&quot;데이터베이스&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Server --&gt; API[&quot;외부 API&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Server --&gt; Git[&quot;Git / GitHub&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MCP 의 특징:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;표준 클라이언트-서버&lt;/strong&gt;: LLM 이 MCP client, 도구 공급자가 MCP server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stdio / HTTP 전송&lt;/strong&gt;: 로컬 프로세스 또는 원격 서버&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;세 가지 원시(primitive)&lt;/strong&gt;: &lt;code&gt;tools&lt;/code&gt; (함수), &lt;code&gt;resources&lt;/code&gt; (파일/데이터), &lt;code&gt;prompts&lt;/code&gt; (프롬프트 템플릿)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인증&lt;/strong&gt;: OAuth 2.0 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;mcp-서버-예시-python&quot;&gt;MCP 서버 예시 (Python)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mcp.server &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mcp.server.stdio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; stdio_server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mcp &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; types&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;server &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Server(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;weather-server&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@server.list_tools&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; list_tools&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() -&gt; list[types.Tool]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        types.Tool(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            description&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;현재 날씨 조회&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            inputSchema&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@server.call_tool&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; call_tool&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(name: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, arguments: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; list[types.Content]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; name &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        city &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; arguments[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        weather &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fetch_weather(city)  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 실제 API&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [types.TextContent(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(weather))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; stdio_server() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (read, write):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; server.run(read, write, server.create_initialization_options())&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;agent-루프-패턴&quot;&gt;Agent 루프 패턴&lt;/h2&gt;
&lt;p&gt;Function Calling 을 반복 사용하는 [[agent-patterns|에이전트 패턴]]:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Start[&quot;사용자 요청&quot;] --&gt; Think[&quot;LLM: 생각 (Thought)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Think --&gt; Decide{도구 필요?}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Decide --&gt;|&quot;Yes&quot;| Call[&quot;도구 호출&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Call --&gt; Observe[&quot;결과 관찰 (Observation)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Observe --&gt; Think&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Decide --&gt;|&quot;No&quot;| Answer[&quot;최종 답변&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 패턴이 &lt;strong&gt;ReAct (Reasoning + Acting)&lt;/strong&gt;. LangChain, LlamaIndex, Claude Code 등이 내부적으로 사용.&lt;/p&gt;
&lt;h2 id=&quot;json-schema-베스트-프랙티스&quot;&gt;JSON Schema 베스트 프랙티스&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;search_products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;상품 검색. 반드시 카테고리를 지정해야 정확한 결과 반환.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;parameters&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;query&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;검색어 (한국어 가능)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;category&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;enum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;electronics&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;clothing&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;food&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;books&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;상품 카테고리. 모르면 &apos;electronics&apos; 기본값 사용.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;max_price&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;최대 가격 (원화). 제한 없으면 null.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;page&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;integer&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;minimum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        &quot;default&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;query&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;category&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;주요 원칙:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;description 이 핵심&lt;/strong&gt;: LLM 은 description 으로 판단. 누락 시 오호출 급증&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;enum 활용&lt;/strong&gt;: 자유 텍스트 대신 enum 으로 범위 제한&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;required 최소화&lt;/strong&gt;: 선택 필드는 LLM 이 생략 가능 (default 활용)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;additionalProperties: false&lt;/strong&gt;: 정의 안 된 필드 차단 (strict mode)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;오호출 (Hallucinated call)&lt;/strong&gt;: LLM 이 없는 함수 호출 시도. 반드시 &lt;code&gt;name&lt;/code&gt; 검증 후 실행.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인자 할루시네이션&lt;/strong&gt;: 필수 필드 누락, enum 외 값 반환. JSON Schema 검증 레이어 필수 (&lt;code&gt;jsonschema&lt;/code&gt; 라이브러리).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;무한 루프&lt;/strong&gt;: 도구 결과 → 다음 도구 호출 반복. 최대 반복 횟수 제한 설정.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도구 스펙이 너무 큼&lt;/strong&gt;: 도구 정의만으로 수천 토큰 소비. 도구 수 최소화 (7-10개 이하 권장).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;결과 미검증&lt;/strong&gt;: 도구가 반환한 데이터를 그대로 LLM 에 재주입. XSS/injection 위험. 결과 sanitize 필수.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tool_choice=“required” 오남용&lt;/strong&gt;: LLM 이 항상 도구를 호출하도록 강제 → 필요 없는 상황에서도 호출.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[agent-patterns]] - Function Calling 을 활용한 에이전트 패턴&lt;/li&gt;
&lt;li&gt;[[llm-rag]] - RAG 에서의 검색 도구 활용&lt;/li&gt;
&lt;li&gt;[[llm-serving-vllm]] - vLLM 에서의 function calling 서빙&lt;/li&gt;
&lt;li&gt;[[chain-of-thought]] - LLM 추론 능력 향상 (도구 선택 품질에 영향)&lt;/li&gt;
&lt;li&gt;[[few-shot-prompting]] - few-shot 으로 도구 사용 패턴 학습&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>function-calling</category><category>agent</category><category>mcp</category><category>json-schema</category><author>koa (김신건)</author></item><item><title>LLM RAG: Retrieval-Augmented Generation</title><link>https://shinkeonkim.com/wiki/ai/llm-rag/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/llm-rag/</guid><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt; 는 LLM 생성 전에 &lt;strong&gt;외부 지식 베이스에서 관련 문서를 검색&lt;/strong&gt; 하여 프롬프트에 삽입하는 패턴. 최신 정보, 도메인 지식, 사설 데이터 접근이 필요할 때 사용한다.&lt;/p&gt;
&lt;p&gt;LLM 파인튜닝 대신 검색으로 외부 지식을 주입하므로 &lt;strong&gt;추가 학습 비용 없이&lt;/strong&gt; 최신 정보를 반영할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;최신 정보&lt;/strong&gt;: LLM 학습 컷오프 이후 지식 (뉴스, 법령 개정 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도메인 데이터&lt;/strong&gt;: 회사 내부 문서, 개인 지식 베이스&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;hallucination 감소&lt;/strong&gt;: 검색된 “출처” 를 명시해 사실성 검증 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용 절감&lt;/strong&gt;: 파인튜닝 대비 데이터 갱신이 쉬움 (벡터 DB 업서트만 하면 됨)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;파이프라인-전체-흐름&quot;&gt;파이프라인 전체 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q[&quot;사용자 질의&quot;] --&gt; E[&quot;쿼리 임베딩\n(Embedding Model)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    E --&gt; V[&quot;벡터 DB 검색\n(ANN 인덱스)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    V --&gt; R[&quot;상위 K 문서 검색\n(Dense / Sparse / Hybrid)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R --&gt; RR[&quot;Reranker\n(Cross-encoder)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RR --&gt; P[&quot;프롬프트 조합\nContext + Question&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P --&gt; L[&quot;LLM\n(GPT-4o, Claude, Gemini)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    L --&gt; A[&quot;최종 답변&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;인덱싱-파이프라인-오프라인&quot;&gt;인덱싱 파이프라인 (오프라인)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    D[&quot;원본 문서\n(PDF, HTML, DB)&quot;] --&gt; C[&quot;Chunking\n500-1000 tokens&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    C --&gt; EM[&quot;Embedding 모델\nbge-large, text-embedding-3&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    EM --&gt; VS[&quot;Vector Store\n(Pinecone, pgvector, Qdrant)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;핵심-구성-요소&quot;&gt;핵심 구성 요소&lt;/h2&gt;
&lt;h3 id=&quot;1-문서-chunking-전략&quot;&gt;1. 문서 Chunking 전략&lt;/h3&gt;
&lt;p&gt;문서를 청크 단위로 분할. 청크 크기와 전략이 검색 품질에 직결된다.&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;전략&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;크기&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;장점&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;단점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;고정 크기&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;500 tokens&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단순&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;문맥 경계에서 끊김&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;슬라이딩 윈도우&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;500 + 50 overlap&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;문맥 손실 최소화&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중복 저장&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;문단/섹션 기반&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;가변&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;의미 단위 유지&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;크기 불균일&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;계층적 chunking&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;문단 + 섹션&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;요약 + 상세 동시&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;복잡한 인덱싱&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; langchain.text_splitter &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; RecursiveCharacterTextSplitter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;splitter &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; RecursiveCharacterTextSplitter(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    chunk_size&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    chunk_overlap&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    separators&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;chunks &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; splitter.split_text(document)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-embedding-모델&quot;&gt;2. Embedding 모델&lt;/h3&gt;
&lt;p&gt;각 청크를 고밀도 벡터 (dense vector) 로 변환. 의미적으로 유사한 텍스트는 벡터 공간에서 가깝게 위치한다.&lt;/p&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;모델&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;차원&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;언어&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;text-embedding-3-small&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;1536&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다국어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;OpenAI, 저비용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;text-embedding-3-large&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;3072&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다국어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;OpenAI, 고성능&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;bge-large-en-v1.5&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;1024&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;영어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스, MTEB 상위&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;bge-m3&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;1024&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다국어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스, 한국어 우수&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;code&gt;nomic-embed-text&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;768&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;영어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스, 로컬 실행 가능&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; openai &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAI()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; embed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(text: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; list[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.embeddings.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;text-embedding-3-small&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        input&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;text,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.data[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].embedding&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3-vector-store&quot;&gt;3. Vector Store&lt;/h3&gt;
&lt;p&gt;임베딩 벡터를 저장하고 ANN (Approximate Nearest Neighbor) 검색을 제공하는 데이터베이스.&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;솔루션&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;유형&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Pinecone&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;관리형&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;완전 관리, 서버리스 플랜&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Qdrant&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Rust, 고성능, 페이로드 필터&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Weaviate&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;멀티벡터, GraphQL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Milvus&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;오픈소스&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대규모, CNCF 프로젝트&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;pgvector&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;PostgreSQL 확장&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;기존 PG 통합, HNSW 지원&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;**[[redis-vector-search&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Redis Vector Search]]**&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Redis 모듈&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# pgvector 예시&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; psycopg2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pgvector.psycopg2 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; register_vector&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;conn &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; psycopg2.connect(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;postgresql://...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;register_vector(conn)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;cursor &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; conn.cursor()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;cursor.execute(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    SELECT content, embedding &amp;#x3C;=&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;%s&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; AS distance&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    FROM documents&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    ORDER BY distance&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    LIMIT 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, (query_embedding,))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;results &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cursor.fetchall()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;4-retrieval-방법&quot;&gt;4. Retrieval 방법&lt;/h3&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;방법&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;설명&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;장점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Dense (벡터)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;코사인 유사도, HNSW&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;의미적 유사성&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Sparse (BM25)&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단어 빈도 기반&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정확한 키워드 매칭&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Hybrid&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Dense + Sparse 결합 (RRF)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;양쪽 장점&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Reranker&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Cross-encoder 재순위&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정확도 향상&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;RRF (Reciprocal Rank Fusion)&lt;/strong&gt;: Dense 와 Sparse 검색 결과 순위를 합산해 최종 순위 산출. 별도 학습 없이 Hybrid 효과.&lt;/p&gt;
&lt;h3 id=&quot;5-reranker&quot;&gt;5. Reranker&lt;/h3&gt;
&lt;p&gt;Dense 검색으로 상위 20-50개를 뽑은 뒤, Cross-encoder 모델로 질의-문서 쌍을 직접 스코어링해 재순위한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cross-encoder/ms-marco-MiniLM-L-12-v2&lt;/code&gt; (오픈소스)&lt;/li&gt;
&lt;li&gt;Cohere Rerank API (관리형)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence_transformers &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CrossEncoder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reranker &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CrossEncoder(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cross-encoder/ms-marco-MiniLM-L-12-v2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pairs &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [(query, doc) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; doc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; candidate_docs]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;scores &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; reranker.predict(pairs)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ranked_docs &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [doc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _, doc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; sorted&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;zip&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(scores, candidate_docs), &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;top_k &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ranked_docs[:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;6-prompt-composition&quot;&gt;6. Prompt Composition&lt;/h3&gt;
&lt;p&gt;검색된 문서를 LLM 프롬프트에 조합.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;You are a helpful assistant. Answer the question based ONLY on the provided context.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;If the answer is not in the context, say &quot;I don&apos;t know.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Context:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Document 1]: {chunk_1}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Document 2]: {chunk_2}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Document 3]: {chunk_3}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Question: {user_query}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Answer:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;고급-rag-패턴&quot;&gt;고급 RAG 패턴&lt;/h2&gt;
&lt;h3 id=&quot;hyde-hypothetical-document-embeddings&quot;&gt;HyDE (Hypothetical Document Embeddings)&lt;/h3&gt;
&lt;p&gt;질의를 임베딩하는 대신, LLM 이 “가상의 답변” 을 먼저 생성한 뒤 그 답변을 임베딩해 검색. 질의와 문서 간 임베딩 공간 불일치 문제를 완화한다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;hypothesis &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm.generate(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Write a hypothetical answer to: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;hypothesis_embedding &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; embed(hypothesis)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;results &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; vector_store.search(hypothesis_embedding, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;multi-query-rewriting&quot;&gt;Multi-Query Rewriting&lt;/h3&gt;
&lt;p&gt;질의를 여러 관점으로 재작성해 다수의 검색 결과를 합산.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;queries &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm.generate(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Rewrite the following query from 3 different perspectives:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;all_results &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [vector_store.search(q) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; q &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; queries]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# RRF 로 합산&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;query-routing&quot;&gt;Query Routing&lt;/h3&gt;
&lt;p&gt;질의 종류에 따라 다른 인덱스나 도구로 라우팅.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q[&quot;사용자 질의&quot;] --&gt; R[&quot;Router LLM&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R --&gt;|&quot;최신 뉴스&quot;| WS[&quot;웹 검색 도구&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R --&gt;|&quot;내부 문서&quot;| VS[&quot;내부 Vector DB&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R --&gt;|&quot;계산 필요&quot;| CALC[&quot;계산기 도구&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    R --&gt;|&quot;일반 질의&quot;| LLM2[&quot;LLM 직접 답변&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;평가-지표&quot;&gt;평가 지표&lt;/h2&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;지표&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;측정 대상&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Recall@K&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;K 개 검색 결과에 정답 포함 비율&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MRR&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Mean Reciprocal Rank, 정답 순위&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Faithfulness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;답변이 컨텍스트에 근거한 정도&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Answer Relevance&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;답변이 질의에 적절한 정도&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Context Precision&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;검색된 문서 중 관련 비율&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ragas &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; evaluate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ragas.metrics &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; faithfulness, answer_relevancy, context_recall&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; evaluate(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    dataset&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;test_dataset,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    metrics&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[faithfulness, answer_relevancy, context_recall],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;청크 경계에서 문맥이 잘린다.&lt;/strong&gt; 고정 크기 chunking 은 문장 중간이나 표 안에서 잘릴 수 있다. 슬라이딩 윈도우 (overlap) 나 문단 기반 chunking 으로 보완해야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Reranker 후보군이 부족하면 역효과.&lt;/strong&gt; Dense 검색 1차 후보를 top-5 만 뽑으면, 실제 정답이 애초에 후보에 없을 수 있다. 1차 검색은 top-20 이상, Reranker 로 top-5 압축하는 패턴이 일반적이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;RAG 는 hallucination 을 줄이지 무조건 없애지 않는다.&lt;/strong&gt; LLM 이 컨텍스트를 무시하고 학습 지식을 사용하는 경우가 있다. “컨텍스트에만 근거해 답하라” 지시 + Faithfulness 평가로 지속 모니터링이 필요하다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[redis-vector-search|Redis Vector Search]] - 인메모리 벡터 검색&lt;/li&gt;
&lt;li&gt;[[function-calling|Function Calling]] - 도구 호출 기반 에이전트 (RAG 의 대안/보완)&lt;/li&gt;
&lt;li&gt;[[one-shot-prompting|One-Shot Prompting]] - 예시 기반 프롬프팅&lt;/li&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] - LLM 평가 벤치마크&lt;/li&gt;
&lt;li&gt;[[voice-rag|Voice RAG]] - 음성 인터페이스 RAG&lt;/li&gt;
&lt;li&gt;[[agent-patterns|Agent Patterns]] - RAG 를 포함한 에이전트 패턴&lt;/li&gt;
&lt;li&gt;[[llm-serving-vllm|vLLM]] - RAG 백엔드 LLM 서빙&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>rag</category><category>retrieval</category><category>vector-db</category><category>embedding</category><author>koa (김신건)</author></item><item><title>[Prompting] Chain-of-Thought (CoT)</title><link>https://shinkeonkim.com/wiki/ai/chain-of-thought/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/chain-of-thought/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Chain-of-Thought (CoT) prompting&lt;/strong&gt; 은 대형 언어 모델이 최종 답을 내기 전에 &lt;strong&gt;중간 추론 단계를 자연어로 생성하도록 유도&lt;/strong&gt; 하는 프롬프팅 기법입니다. 산술, 상식, 논리, 다단계 질문 응답 등 &lt;strong&gt;다단계 추론이 필요한 태스크에서 정확도를 크게 향상&lt;/strong&gt; 시킵니다.&lt;/p&gt;
&lt;p&gt;Wei et al. (Google Brain) 이 2022년 1월 논문에서 처음 체계화했고, GSM8K (초등 산술 문장 문제) 에서 PaLM 540B 의 정확도를 17.9% → 58.1% 로 끌어올린 결과가 인상적이었습니다.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;p&gt;기존 few-shot prompting 은 &lt;strong&gt;입력 → 답&lt;/strong&gt; 을 그대로 요구했는데, 다단계 계산이 필요한 문제에서는 모델이 중간 사고를 생략한 채 답만 뱉으며 자주 틀렸습니다. CoT 는 모델이 사람이 문제를 푸는 순서 (읽고, 정리하고, 계산하고, 결론) 를 언어로 &lt;strong&gt;명시적으로 서술&lt;/strong&gt; 하게 만들어, 이 서술 자체가 다음 토큰 예측의 문맥이 되어 정확도가 오른다는 발견입니다.&lt;/p&gt;
&lt;h2 id=&quot;기본-예시-few-shot-cot&quot;&gt;기본 예시 (Few-shot CoT)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;표준 few-shot&lt;/strong&gt; (틀림):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: Roger has 5 tennis balls. He buys 2 more cans of tennis balls.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Each can has 3 tennis balls. How many tennis balls does he have now?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: 11.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: The cafeteria had 23 apples. If they used 20 to make lunch and bought 6 more,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   how many apples do they have?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: 27.   ← 오답 (정답 9)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Chain-of-Thought&lt;/strong&gt; (정답):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: Roger has 5 tennis balls. He buys 2 more cans of tennis balls.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Each can has 3 tennis balls. How many tennis balls does he have now?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: Roger started with 5 balls. 2 cans of 3 tennis balls each is 6 balls.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   5 + 6 = 11. The answer is 11.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: The cafeteria had 23 apples. If they used 20 to make lunch and bought 6 more,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   how many apples do they have?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: The cafeteria started with 23 apples. They used 20, so 23 - 20 = 3.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Then they bought 6 more, so 3 + 6 = 9. The answer is 9.   ← 정답&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;같은 예시 개수, 같은 모델, 형식만 바꿨는데 정답률이 오릅니다.&lt;/p&gt;
&lt;h2 id=&quot;zero-shot-cot&quot;&gt;Zero-shot CoT&lt;/h2&gt;
&lt;p&gt;Kojima et al. (2022) 는 &lt;strong&gt;예시 없이 지시문만&lt;/strong&gt; 으로도 CoT 를 유도할 수 있음을 보였습니다.&lt;/p&gt;
&lt;p&gt;프롬프트 끝에 다음 마법 문장을 붙입니다:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q: {question}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;A: Let&apos;s think step by step.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 한 줄이 InstructGPT-003 의 MultiArith 정확도를 17.7% → 78.7% 로 끌어올렸습니다. 한국어에서는 “차근차근 생각해 봅시다” 또는 “단계별로 풀이해 봅시다” 등으로 옮깁니다.&lt;/p&gt;
&lt;p&gt;두 단계 프롬프트 (two-stage) 로 쓰기도 합니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reasoning extraction&lt;/strong&gt;: “Let’s think step by step” 으로 추론 생성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Answer extraction&lt;/strong&gt;: 위 추론을 이어 붙이고 “Therefore, the answer is” 로 답만 추출&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;창발성-emergent-ability&quot;&gt;창발성 (emergent ability)&lt;/h2&gt;
&lt;p&gt;Wei et al. 논문의 핵심 관찰: CoT 는 &lt;strong&gt;일정 규모 이상&lt;/strong&gt; 에서만 효과가 나타납니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;~62B 이하 모델: CoT 가 오히려 성능을 떨어뜨림 (틀린 추론을 확신 있게 씀)&lt;/li&gt;
&lt;li&gt;~62B 이상: CoT 로 정확도 급상승 (특히 100B+ 에서 gap 이 커짐)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이것이 “emergent abilities” 논쟁의 대표 사례입니다 (Schaeffer et al. 2023 이 metric artifact 라고 반박한 논문도 있음). 실제로 오늘날 소형 모델도 instruction tuning + CoT-style SFT 를 거치면 CoT 를 어느 정도 흉내낼 수 있어, “임계 규모” 는 절대적이지 않습니다.&lt;/p&gt;
&lt;h2 id=&quot;주요-확장&quot;&gt;주요 확장&lt;/h2&gt;
&lt;h3 id=&quot;self-consistency-wang-et-al-2022&quot;&gt;Self-Consistency (Wang et al., 2022)&lt;/h3&gt;
&lt;p&gt;CoT 한 번만 샘플링하지 말고, &lt;strong&gt;temperature &gt; 0 으로 여러 개 (예: 40 개) 샘플링&lt;/strong&gt; 후 최종 답을 &lt;strong&gt;다수결&lt;/strong&gt; 로 뽑습니다.&lt;/p&gt;
&lt;p&gt;$$
\hat{y} = \arg\max_y \sum_{i=1}^{N} \mathbb{1}[\text{answer}(z_i) = y]
$$&lt;/p&gt;
&lt;p&gt;여기서 $z_i$ 는 $i$ 번째 chain-of-thought, $\text{answer}(z_i)$ 는 그 chain 의 최종 답. GSM8K 에서 PaLM 의 성능이 SC 로 74.4% → 스코어링 대폭 개선.&lt;/p&gt;
&lt;h3 id=&quot;least-to-most-zhou-et-al-2022&quot;&gt;Least-to-Most (Zhou et al., 2022)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;문제 분해 후 순차 해결&lt;/strong&gt;. 프롬프트 두 개:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Decomposition&lt;/strong&gt;: “이 문제를 더 쉬운 하위 문제로 나눠 봐”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Solving&lt;/strong&gt;: 하위 문제를 순서대로 풀고 답을 다음 하위 문제에 참조&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Compositional generalization (긴 조합 문제) 에서 CoT 를 크게 상회.&lt;/p&gt;
&lt;h3 id=&quot;tree-of-thoughts-yao-et-al-2023&quot;&gt;Tree of Thoughts (Yao et al., 2023)&lt;/h3&gt;
&lt;p&gt;CoT 는 선형 사슬. &lt;strong&gt;ToT&lt;/strong&gt; 는 &lt;strong&gt;여러 추론 분기&lt;/strong&gt; 를 탐색합니다. 각 노드에서 여러 다음 스텝을 생성하고 self-evaluation 으로 점수를 매긴 뒤 BFS/DFS 로 탐색. Game of 24, Creative Writing 등에서 강함.&lt;/p&gt;
&lt;h3 id=&quot;program-aided-pal-pot&quot;&gt;Program-Aided (PAL, PoT)&lt;/h3&gt;
&lt;p&gt;자연어 대신 &lt;strong&gt;Python 코드&lt;/strong&gt; 로 중간 추론을 씁니다. 계산은 언어 모델이 아니라 인터프리터가 실행 -&gt; 산술 오류가 원천 차단.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# Q: A juggler can juggle 16 balls. Half of them are golf balls,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;#    and half of the golf balls are blue. How many blue golf balls?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;total_balls &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;golf_balls &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; total_balls &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;blue_golf_balls &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; golf_balls &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;answer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blue_golf_balls   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;auto-cot-zhang-et-al-2022&quot;&gt;Auto-CoT (Zhang et al., 2022)&lt;/h3&gt;
&lt;p&gt;예시를 사람이 손으로 만들지 않고, &lt;strong&gt;클러스터링 + Zero-shot CoT&lt;/strong&gt; 로 자동 생성한 예시를 few-shot 에 삽입. 사람 수작업 비용 절감.&lt;/p&gt;
&lt;h3 id=&quot;react-yao-et-al-2022&quot;&gt;ReAct (Yao et al., 2022)&lt;/h3&gt;
&lt;p&gt;Reasoning + Acting. CoT 사이에 &lt;strong&gt;도구 호출 (검색, 계산기, API)&lt;/strong&gt; 을 끼워 넣습니다. 오늘날 [[function-calling|Function Calling]] 기반 agent 의 원류.&lt;/p&gt;
&lt;h2 id=&quot;2024-2025-진화-reasoning-models&quot;&gt;2024-2025 진화: Reasoning models&lt;/h2&gt;
&lt;p&gt;CoT 를 &lt;strong&gt;사후 학습 (RL)&lt;/strong&gt; 으로 내재화하고, 추론 시 훨씬 길고 정교한 사슬을 생성하도록 훈련한 계열이 등장했습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenAI o1 / o3 / o4-mini&lt;/strong&gt; (2024-2025): 강화학습으로 CoT 능력 향상, hidden reasoning tokens 로 답 이전에 광범위한 내부 사슬 소비&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DeepSeek-R1&lt;/strong&gt; (2025): 오픈웨이트 reasoning model, PPO/GRPO 로 CoT 학습&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude 3.7 / 4 Extended Thinking&lt;/strong&gt;: 사용자에게 노출 가능한 thinking tokens&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gemini 2.5 Thinking&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 계열에서는 프롬프트에 “step by step” 을 굳이 붙일 필요가 없습니다. 모델이 이미 알아서 확장 추론합니다. 오히려 지시가 이중이 되면 사슬이 산만해질 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;CoT 는 정확도를 항상 올리지 않습니다.&lt;/strong&gt; 태스크가 사실 조회 (facts), 스타일 변환, 짧은 감정 분류 등 &lt;strong&gt;단발성 답변에 가까운 태스크&lt;/strong&gt; 라면 CoT 가 오히려 노이즈를 늘려 정확도가 떨어질 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;CoT 는 사후 정당화 (post-hoc rationalization) 를 할 수 있습니다.&lt;/strong&gt; 모델이 먼저 답을 내리고, 그럴듯한 사슬을 만들어 맞춰 쓰는 경우가 관측됩니다. 사슬이 논리적으로 완결돼 보인다고 실제 그렇게 추론했다고 신뢰하면 안 됩니다 (Turpin et al. 2023 “Language Models Don’t Always Say What They Think”).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;비용 팽창.&lt;/strong&gt; 다단계 사슬은 출력 토큰이 늘어 API 요금이 몇 배 커집니다. Self-Consistency 는 여기에 샘플 수 배수를 더 곱합니다. 프로덕션에서는 답만 필요한 경우 사슬을 max_tokens 로 잘라내는 것이 아니라, 요약된 최종 답을 뽑는 &lt;strong&gt;answer extraction&lt;/strong&gt; 을 별도로 두는 편이 안전합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;작은 모델에는 역효과&lt;/strong&gt; 였다는 초기 관찰 (Wei 2022) 이 여전히 부분적으로 유효합니다. SLM (&amp;#x3C; 10B) 에는 CoT 를 유도하는 대신 instruction-tuned SFT 데이터에 이미 CoT-style 응답이 포함되어 있는지가 관건입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;실전-팁&quot;&gt;실전 팁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;예시 개수&lt;/strong&gt;: 4-8 shot 이 대개 최적. 그 이상은 return diminishing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;예시 순서&lt;/strong&gt;: 최근 예시가 답에 큰 영향 (recency bias). 다양한 라벨을 섞습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분리 구분자&lt;/strong&gt;: &lt;code&gt;Q:&lt;/code&gt; / &lt;code&gt;A:&lt;/code&gt; 형식 또는 messages array 로 role 분리.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;답 추출&lt;/strong&gt;: 정규식으로 최종 숫자만 뽑기 (&lt;code&gt; ... The answer is (\d+)&lt;/code&gt; 등).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;temperature&lt;/strong&gt;: 단답 CoT 는 0-0.3, Self-Consistency 는 0.5-0.8.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;평가는 sample 여러 개 평균&lt;/strong&gt;: CoT 는 분산이 큽니다. n=3~5 로 여러 번 돌린 평균이 신뢰할 만합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cot-변형-계보&quot;&gt;CoT 변형 계보&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Std[Standard Few-shot]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CoT[&quot;Few-shot CoT (Wei 2022)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ZSCoT[&quot;Zero-shot CoT (Kojima 2022)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    SC[&quot;Self-Consistency (Wang 2022)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LtM[&quot;Least-to-Most (Zhou 2022)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ToT[&quot;Tree of Thoughts (Yao 2023)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    PAL[&quot;PAL / PoT (Gao 2022)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ReAct[&quot;ReAct (Yao 2022)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RM[&quot;Reasoning Models (o1/R1/Claude)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Std --&gt; CoT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Std --&gt; ZSCoT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CoT --&gt; SC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CoT --&gt; LtM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CoT --&gt; ToT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CoT --&gt; PAL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CoT --&gt; ReAct&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    SC --&gt; RM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ToT --&gt; RM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ReAct --&gt; RM&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 계보는 논문 발표 순서를 대략 반영합니다. 하위로 내려갈수록 추론 구조가 복잡해지며, “Reasoning Models” 계열에서는 이 기법들이 강화학습으로 내재화됩니다.&lt;/p&gt;
&lt;h2 id=&quot;벤치마크별-cot-효과&quot;&gt;벤치마크별 CoT 효과&lt;/h2&gt;
&lt;p&gt;CoT 가 특히 효과적인 태스크와 그렇지 않은 태스크:&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;벤치마크&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;태스크 성격&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;CoT 효과&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;GSM8K&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;초등 산술 문장 문제&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 큼: PaLM 540B 17.9% → 58.1%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MATH&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;고등 수학 경시 문제&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;큼: 다단계 증명에 적합&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;ARC-Challenge&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;4지선다 과학&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간: Self-Consistency 병행 시 효과적&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;StrategyQA&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;암묵적 다단계 추론&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;CommonsenseQA&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;상식 추론&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;HotpotQA&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다단계 Wikipedia 추론&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;TriviaQA&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단순 사실 조회&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;거의 없음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;NaturalQuestions&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단순 사실 조회&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;없음 또는 음수&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;단순 사실 조회에서 CoT 가 오히려 노이즈를 늘려 정확도가 낮아지는 케이스도 관측됩니다.&lt;/p&gt;
&lt;h2 id=&quot;프롬프트-구성-흐름&quot;&gt;프롬프트 구성 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    U[사용자 질문] --&gt; PB[프롬프트 빌더]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    PB --&gt; E1[&quot;예시 1: Q + 추론 + A&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    PB --&gt; E2[&quot;예시 2: Q + 추론 + A&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    PB --&gt; TQ[대상 질문]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TQ --&gt; LLM[LLM 생성]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM --&gt; CH[중간 추론 사슬]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CH --&gt; AE[답 추출]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    AE --&gt; OUT[최종 답]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;two-stage&lt;/code&gt; 방식에서는 1단계에서 사슬만 생성하고, 2단계에서 사슬을 붙여 “따라서 답은” 형태로 답만 추출합니다. 이렇게 하면 답 파싱이 안정적이고 출력 길이를 제어하기 쉽습니다.&lt;/p&gt;
&lt;h2 id=&quot;self-consistency-샘플링-전략&quot;&gt;Self-Consistency 샘플링 전략&lt;/h2&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;샘플 수&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;temperature&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;권장 상황&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;5&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;0.5&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠른 검증, 비용 절감 우선&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;20&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;0.7&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간 신뢰도, 프로덕션 일반&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;40&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;0.7-0.8&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;논문 수준 평가, 비용 큼&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;다수결 집계는 numeric answer 에만 정규식으로 추출합니다. 자유 형식 답변에는 LLM-as-judge 로 별도 합의를 구합니다.&lt;/p&gt;
&lt;h2 id=&quot;프로덕션-구현-체크리스트&quot;&gt;프로덕션 구현 체크리스트&lt;/h2&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;answer extraction&lt;/strong&gt;: 최종 답만 파싱 (정규식 또는 extraction prompt 분리)&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;max_tokens 설정&lt;/strong&gt;: 사슬이 너무 길면 잘림 방지를 위해 여유분 확보&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;fallback&lt;/strong&gt;: CoT 사슬이 비어 오면 zero-shot 재시도&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;응답 캐시&lt;/strong&gt;: 동일 질문 반복이면 CoT 결과 캐시로 비용 절감&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;eval 로그&lt;/strong&gt;: temperature &gt; 0 이므로 n=5 결과 평균으로 정확도 측정&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; &lt;strong&gt;streaming&lt;/strong&gt;: 긴 사슬은 streaming 응답으로 사용자 경험 개선&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;다른-프롬프팅-기법과-관계&quot;&gt;다른 프롬프팅 기법과 관계&lt;/h2&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;기법&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;관계&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;[[zero-shot-prompting&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Zero-Shot Prompting]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;[[one-shot-prompting&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;One-Shot Prompting]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;[[few-shot-prompting&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Few-Shot Prompting]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;[[function-calling&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Function Calling]]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;[[llm-rag&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LLM RAG]]&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[few-shot-prompting|Few-Shot Prompting]] - CoT 의 예시 구조 기반&lt;/li&gt;
&lt;li&gt;[[zero-shot-prompting|Zero-Shot Prompting]] - “Let’s think step by step” 계열&lt;/li&gt;
&lt;li&gt;[[one-shot-prompting|One-Shot Prompting]] - 예시 1개 CoT&lt;/li&gt;
&lt;li&gt;[[helm-llm-benchmark|HELM]] - CoT reasoning 벤치마크 (GSM8K, MATH)&lt;/li&gt;
&lt;li&gt;[[big-bench|BIG-Bench]] - CoT 초기 검증에 자주 쓰인 태스크 셋&lt;/li&gt;
&lt;li&gt;[[function-calling|Function Calling]] - ReAct 계열 tool-augmented reasoning&lt;/li&gt;
&lt;li&gt;[[llm-rag|LLM RAG]] - 검색 결과 위에 CoT&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>prompting</category><category>reasoning</category><category>inference</category><author>koa (김신건)</author></item><item><title>[LLM Eval] HELM: Holistic Evaluation of Language Models</title><link>https://shinkeonkim.com/wiki/ai/helm-llm-benchmark/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/helm-llm-benchmark/</guid><pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;HELM (Holistic Evaluation of Language Models)&lt;/strong&gt; 는 Stanford CRFM (Center for Research on Foundation Models) 이 2022년 발표한 LLM 종합 평가 프레임워크입니다. 기존 벤치마크가 정확도 단일 지표에 편중되는 문제를 지적하며, &lt;strong&gt;여러 시나리오 × 여러 메트릭의 행렬&lt;/strong&gt; 로 모델을 평가하는 것을 특징으로 합니다.&lt;/p&gt;
&lt;p&gt;원 논문 제목이 곧 방법론입니다. Holistic (전체적): 정확도만이 아니라 공정성, 편향, 견고성, 효율성까지 함께 보겠다는 선언.&lt;/p&gt;
&lt;h2 id=&quot;왜-등장했는가&quot;&gt;왜 등장했는가&lt;/h2&gt;
&lt;p&gt;2022 년 시점 LLM 평가의 문제:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;단일 태스크 평가&lt;/strong&gt; (MMLU, HellaSwag 등) 는 특정 능력만 봄&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정확도 지표만 리포트&lt;/strong&gt; (calibration, robustness, bias 등은 무시)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모델 비교가 임의적&lt;/strong&gt; (논문마다 다른 태스크 조합, 다른 세팅)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;재현성 부족&lt;/strong&gt; (프롬프트, 파라미터, few-shot 개수가 논문마다 다름)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HELM 은 이를 &lt;strong&gt;표준화된 시나리오 세트 + 표준화된 메트릭 세트 + 표준화된 프롬프트/실행 방식&lt;/strong&gt; 으로 해결하려 했습니다.&lt;/p&gt;
&lt;h2 id=&quot;7-가지-핵심-메트릭-축&quot;&gt;7 가지 핵심 메트릭 축&lt;/h2&gt;
&lt;p&gt;원 논문의 7 축입니다. 각 시나리오에 대해 이 7 가지를 모두 측정하려 시도합니다.&lt;/p&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;의미&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;예시&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Accuracy&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정답 맞추는 능력&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정확도, F1, exact match&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Calibration&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;확신도 vs 실제 정확도 일치&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ECE (Expected Calibration Error)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Robustness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;입력 변형에도 안정적인가&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Typo, paraphrase, adversarial 변형 아래 성능&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Fairness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;인구통계 집단별 성능 균등한가&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;이름/방언에 따른 성능 편차&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Bias&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;스테레오타입 재생산 여부&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;성별/인종 등에 대한 연관성 통계&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Toxicity&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;유해 텍스트 생성 여부&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Perspective API 등으로 측정&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Efficiency&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;추론 비용, 학습 비용&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;초당 토큰, 학습에 든 FLOPs&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;이 7 가지는 &lt;strong&gt;완전한 목록이 아니라 출발점&lt;/strong&gt; 이라고 논문 스스로 명시했습니다. 이후 버전에서 확장되었습니다.&lt;/p&gt;
&lt;h2 id=&quot;시나리오-scenario&quot;&gt;시나리오 (Scenario)&lt;/h2&gt;
&lt;p&gt;HELM 이 커버하는 태스크 유형입니다. 각 시나리오는 데이터셋 + 태스크 정의 + 평가 방식으로 구성됩니다. 초기 버전 42 개 시나리오를 대략 6 개 카테고리로 나눌 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Question Answering&lt;/strong&gt;: NaturalQuestions, NarrativeQA, TruthfulQA, QuAC 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Information Retrieval&lt;/strong&gt;: MS MARCO 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Summarization&lt;/strong&gt;: CNN/DailyMail, XSum&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sentiment Analysis / Classification&lt;/strong&gt;: IMDB, RAFT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Toxicity Detection&lt;/strong&gt;: CivilComments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reasoning&lt;/strong&gt;: MMLU, GSM8K, MATH, BBQ (bias)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이후 버전에서 코드 (HumanEval, MBPP), 롱-컨텍스트 (LongBench 계열), 멀티모달 등이 추가되었습니다.&lt;/p&gt;
&lt;h2 id=&quot;helm-variants-2023&quot;&gt;HELM Variants (2023~)&lt;/h2&gt;
&lt;p&gt;원 HELM (이하 &lt;strong&gt;HELM Classic&lt;/strong&gt;) 은 모든 시나리오 × 모든 메트릭을 시도했기 때문에 &lt;strong&gt;매우 비쌉니다&lt;/strong&gt; (수천~수만 달러 규모의 API 비용). 이를 축소한 파생 버전들이 나왔습니다.&lt;/p&gt;
&lt;h3 id=&quot;helm-lite-2023-말&quot;&gt;HELM Lite (2023 말~)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;실전에서 자주 쓰이는 시나리오만 &lt;strong&gt;10 개 내외&lt;/strong&gt; 로 축소&lt;/li&gt;
&lt;li&gt;MMLU (multiple-choice), GSM8K, MATH, NaturalQuestions, WMT, LegalBench 등&lt;/li&gt;
&lt;li&gt;하루~며칠 단위로 리더보드 업데이트&lt;/li&gt;
&lt;li&gt;빠른 반복 평가에 적합&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://crfm.stanford.edu/helm/lite/&quot;&gt;https://crfm.stanford.edu/helm/lite/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;helm-instruct&quot;&gt;HELM Instruct&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;지시 따르기 (instruction following)&lt;/strong&gt; 평가에 초점&lt;/li&gt;
&lt;li&gt;Open-ended generation 을 사람 또는 LLM-as-judge 로 평가&lt;/li&gt;
&lt;li&gt;MT-Bench, AlpacaEval 등과 유사한 접근&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://crfm.stanford.edu/helm/instruct/&quot;&gt;https://crfm.stanford.edu/helm/instruct/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;helm-safety&quot;&gt;HELM Safety&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;안전성 (harmful content, jailbreak 저항성) 중심&lt;/li&gt;
&lt;li&gt;유해 요청에 대한 거부, jailbreak 프롬프트 아래 견고성 등&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;도메인-특화-helm&quot;&gt;도메인 특화 HELM&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MedHELM&lt;/strong&gt;: 의료 도메인 (2024)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LegalBench&lt;/strong&gt; 통합&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIR-Bench&lt;/strong&gt;: 리스크 카테고리별&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;리더보드는 &lt;a href=&quot;https://crfm.stanford.edu/helm/&quot;&gt;https://crfm.stanford.edu/helm/&lt;/a&gt; 최상단에서 여러 트랙을 선택할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;시나리오--메트릭-매트릭스&quot;&gt;시나리오 × 메트릭 매트릭스&lt;/h2&gt;
&lt;p&gt;핵심 아이디어를 도식으로 표현하면:&lt;/p&gt;





































































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;MMLU&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;HellaSwag&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;TruthfulQA&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;HumanEval&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;…&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Accuracy&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;pass@1&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Calibration&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Robustness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓ (typo)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Fairness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓ (이름 치환)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Bias&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✓ (BBQ)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Toxicity&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Efficiency&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;tok/s, FLOPs&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;…&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;모든 셀이 다 채워지진 않습니다 (해당 메트릭이 그 시나리오에 적용 불가한 경우 존재). HELM 은 &lt;strong&gt;어떤 셀이 비어 있는지도 명시적으로 보여주어&lt;/strong&gt; 평가의 불완전성을 드러냅니다.&lt;/p&gt;
&lt;h2 id=&quot;리더보드-2026-기준&quot;&gt;리더보드 (2026 기준)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://crfm.stanford.edu/helm/lite/&quot;&gt;https://crfm.stanford.edu/helm/lite/&lt;/a&gt; 최신 리더보드에서 확인 가능합니다. 상위권에는 GPT-5, Claude Opus 4, Gemini 2.5 계열 등이 위치하며, 오픈 웨이트 (Llama, Qwen, DeepSeek) 도 근접해 있습니다. 정확한 순위는 시점마다 바뀌므로 링크 참조가 정답입니다.&lt;/p&gt;
&lt;h2 id=&quot;실행-방법-helm-run&quot;&gt;실행 방법 (helm-run)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; crfm-helm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 실행할 conf 파일 정의&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;cat&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run-specs.conf&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; EOF&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  {description: &quot;mmlu:subject=philosophy,model=openai/gpt-4o&quot;, priority: 1},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  {description: &quot;narrativeqa:model=openai/gpt-4o&quot;, priority: 1},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 실행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;helm-run&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --conf-paths&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run-specs.conf&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --suite&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; my-eval&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --max-eval-instances&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --num-threads&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 결과 요약 통합&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;helm-summarize&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --suite&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; my-eval&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 웹 UI 로 결과 확인&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;helm-server&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --suite&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; my-eval&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# http://localhost:8000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;지원 모델 provider: &lt;strong&gt;OpenAI, Anthropic, Google, Meta, Microsoft, Cohere, HuggingFace Hub, vLLM, Together, DeepSeek, Mistral&lt;/strong&gt; 등. 자체 서빙 모델도 &lt;code&gt;LocalModel&lt;/code&gt; 로 붙일 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;다른-벤치마크와-비교&quot;&gt;다른 벤치마크와 비교&lt;/h2&gt;



























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;벤치마크&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;초점&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;장점&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;단점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;HELM&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Holistic (다면적)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;여러 축 동시 측정, 표준화&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실행 비용 큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MMLU / MMLU-Pro&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지식 QA&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;간단, 널리 인용됨&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단일 정답 편중, 오염 우려&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;BIG-Bench&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다양성 극대화&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;200+ 태스크&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;태스크 품질 편차 큼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Chatbot Arena&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사람 선호도&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실사용자 판단, 편향 적음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;태스크 세분화 없음, 오랜 축적 필요&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;AlpacaEval&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Instruction following&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LLM-as-judge 로 빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Judge 편향&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;MT-Bench&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대화 품질&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;짧고 실용적&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소규모 (80 문항)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;LM Eval Harness&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;프레임워크&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;EleutherAI, 매우 널리 쓰임&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;표준 축이 아니라 도구&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;AGIEval&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;인간 시험 (SAT, LSAT)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실제 인간 기준&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;지역/언어 편중&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;HELM 은 벤치마크 그 자체이자 프레임워크&lt;/strong&gt;입니다. 다른 벤치마크의 결과를 HELM 구조 안에서 재실행할 수 있게 통합해 왔습니다.&lt;/p&gt;
&lt;h2 id=&quot;한계와-비판&quot;&gt;한계와 비판&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;오염 (contamination)&lt;/strong&gt;: MMLU 등 공개 벤치마크가 학습 데이터에 유출되어 점수가 부풀려질 수 있습니다. HELM 자체는 이를 감지하지 못합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비용&lt;/strong&gt;: 원 HELM Classic 은 GPT-4 급 모델을 완전 실행하려면 수만 달러가 필요합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7 축의 임의성&lt;/strong&gt;: 안전성/agentic 능력/멀티모달은 원 논문에 없었고 이후 추가되었지만 여전히 커버리지 논쟁.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단일 시드 실행&lt;/strong&gt;: 확률적 생성이므로 결과가 흔들리며, 여러 시드로 여러 번 실행하는 것이 이상적이지만 비용 문제로 어려움.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동 평가의 한계&lt;/strong&gt;: LLM-as-judge 는 편향 (자기 편애, 길이 선호) 이 알려져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;평가-파이프라인&quot;&gt;평가 파이프라인&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Def[&quot;시나리오 정의&quot;] --&gt; Conf[&quot;run-specs.conf 작성&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Conf --&gt; Run[&quot;helm-run (API 호출)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Run --&gt; Cache[&quot;결과 캐시&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Cache --&gt; Sum[&quot;helm-summarize (집계)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sum --&gt; Dash[&quot;helm-server 대시보드&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Dash --&gt; Cmp[&quot;모델 비교 (7축)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;시나리오별-추천-벤치마크&quot;&gt;시나리오별 추천 벤치마크&lt;/h2&gt;
&lt;p&gt;목적에 따라 집중할 시나리오가 다름.&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;목적&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;추천 시나리오&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;이유&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;지식 QA / 상식&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MMLU, TruthfulQA&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;광범위한 도메인 지식&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;수학 / 추론&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;GSM8K, MATH&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;다단계 논리 추론&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;코드 생성&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;HumanEval, MBPP&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실행 가능 코드&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;긴 문맥 처리&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LongBench, SCROLLS&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;컨텍스트 창 활용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;안전성&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;ToxiGen, BBQ&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;편향, 독성&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;지시 따르기&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MT-Bench, AlpacaEval&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;대화형 assistant 품질&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;의료&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;MedQA, MedHELM&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;임상 추론&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;법률&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LegalBench&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;법률 문서 이해&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;helm-결과-해석&quot;&gt;HELM 결과 해석&lt;/h2&gt;
&lt;h3 id=&quot;단일-점수-vs-프로파일&quot;&gt;단일 점수 vs 프로파일&lt;/h3&gt;
&lt;p&gt;HELM 은 &lt;em&gt;단일 평균 순위보다 시나리오별 프로파일&lt;/em&gt;을 중시. 모델 A 가 MMLU 에서 높아도 TruthfulQA 에서 낮으면 실사용 신뢰성에 문제가 됨.&lt;/p&gt;
&lt;h3 id=&quot;신뢰-구간&quot;&gt;신뢰 구간&lt;/h3&gt;
&lt;p&gt;단일 시드 실행 특성상 결과에 통계적 불확실성이 존재. 1-2% 차이는 의미 없을 수 있음. Elo 기반 Chatbot Arena 는 더 많은 샘플에서 통계적 신뢰도 제공.&lt;/p&gt;
&lt;h3 id=&quot;오염-탐지-방법&quot;&gt;오염 탐지 방법&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# n-gram overlap 기반 간이 탐지 (13-gram 기준)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; nltk.util &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ngrams &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; make_ngrams&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ngram_overlap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(train_text: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, test_text: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, n: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 13&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    train_set &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(make_ngrams(train_text.split(), n))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    test_set &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(make_ngrams(test_text.split(), n))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; test_set:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(train_set &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; test_set) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(test_set)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 5% 이상이면 오염 의심&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;대규모 스캔에는 Min-Hash 또는 Bloom filter 활용. HELM 자체는 오염 탐지 기능 없음.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;참고&quot;&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;관련 [[transfer-learning|Transfer Learning]] 은 HELM 이 평가하는 파운데이션 모델의 근본 기법입니다&lt;/li&gt;
&lt;li&gt;관련 [[classification-metrics|분류 모델 지표]] 는 accuracy 축 세부 지표&lt;/li&gt;
&lt;li&gt;관련 [[sagemaker-model-monitor|SageMaker Model Monitor]] 는 프로덕션 모니터링, HELM 은 모델 선정 단계&lt;/li&gt;
&lt;li&gt;리더보드: &lt;a href=&quot;https://crfm.stanford.edu/helm/&quot;&gt;https://crfm.stanford.edu/helm/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Paper: &lt;a href=&quot;https://arxiv.org/abs/2211.09110&quot;&gt;Liang et al. 2022, HELM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href=&quot;https://github.com/stanford-crfm/helm&quot;&gt;https://github.com/stanford-crfm/helm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;관련 커뮤니티: &lt;a href=&quot;https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard&quot;&gt;Open LLM Leaderboard&lt;/a&gt;, &lt;a href=&quot;https://github.com/EleutherAI/lm-evaluation-harness&quot;&gt;LM Eval Harness&lt;/a&gt;, &lt;a href=&quot;https://chat.lmsys.org/&quot;&gt;Chatbot Arena&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>ai</category><category>llm</category><category>evaluation</category><category>benchmark</category><author>koa (김신건)</author></item><item><title>[Voice AI] Agent 패턴: Supervisor, Handoff, ReAct, HITL</title><link>https://shinkeonkim.com/wiki/ai/agent-patterns/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/agent-patterns/</guid><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;복잡한 음성 에이전트 = &lt;em&gt;여러 sub-agent + 조정 패턴&lt;/em&gt;. 단일 LLM 으로 처리하기 어려운 흐름.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
각 sub-agent 내부는 &lt;em&gt;VAD → STT → LLM → TTS 순차 파이프라인&lt;/em&gt; 위에서 동작. 본 페이지의 패턴은 &lt;em&gt;상위 조정 (orchestration)&lt;/em&gt; 레이어.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;4가지-핵심-패턴&quot;&gt;4가지 핵심 패턴&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q[Agent Patterns]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt; S[Supervisor]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt; H[Handoff]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt; R[ReAct]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt; HITL[Human-in-the-Loop]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;1-supervisor&quot;&gt;1. Supervisor&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User --&gt; Sup[Supervisor Agent]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sup --&gt; Choose{어느 sub-agent?}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Choose --&gt;|결제 문의| Pay[Payment Agent]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Choose --&gt;|환불| Ref[Refund Agent]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Choose --&gt;|기술 지원| Tech[Tech Agent]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Pay --&gt; Sup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Ref --&gt; Sup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Tech --&gt; Sup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sup --&gt; User&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SupervisorAgent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;&quot;&quot;질의 → 적절 sub-agent 라우팅&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    sub_agents &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;payment&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: PaymentAgent(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;refund&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: RefundAgent(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;tech_support&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: TechAgent(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; handle&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, user_input: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        # LLM 으로 의도 분류&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        intent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;._classify_intent(user_input)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        agent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.sub_agents[intent]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; agent.handle(user_input)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; _classify_intent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(self, text: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm.structured_output(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            schema&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;IntentSchema,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: text}],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; result.intent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;작은 분류 모델 (gpt-4o-mini, Haiku) 가 &lt;em&gt;intent classifier&lt;/em&gt;, &lt;em&gt;세부 agent 가 더 큰 모델&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;2-handoff&quot;&gt;2. Handoff&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;Booking: 예약 문의&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Booking-&gt;&gt;Booking: 예약 처리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over Booking: 결제 단계&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Booking-&gt;&gt;Payment: HANDOFF (context 전달)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Payment-&gt;&gt;User: &quot;결제 진행하겠습니다&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;Payment: 카드 정보&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Payment-&gt;&gt;Payment: 결제 처리&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Payment--&gt;&gt;Booking: HANDOFF BACK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Booking-&gt;&gt;User: &quot;예약 + 결제 완료&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OpenAI Swarm 의 &lt;em&gt;handoff&lt;/em&gt; 패턴:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; swarm &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Swarm, Agent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;booking_agent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Agent(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Booking&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    instructions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;식당 예약을 도와줍니다.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    functions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[lookup_restaurant, check_availability, transfer_to_payment],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;payment_agent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Agent(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Payment&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    instructions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;결제를 처리합니다.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    functions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[charge_card, transfer_to_booking],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transfer_to_payment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; payment_agent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transfer_to_booking&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; booking_agent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Swarm()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.run(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;agent&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;booking_agent, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Function return 으로 agent 교체&lt;/em&gt;. 깔끔.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;3-react-reason--act&quot;&gt;3. ReAct (Reason + Act)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thought: 사용자가 &quot;내일 오후 회의 잡아줘&quot; 라고 했다.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Action: search_calendar(date=&quot;내일&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Observation: 14:00-15:00 비어있음&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thought: 14시에 잡으면 되겠다. 참석자는 누구?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Action: ask_user(&quot;참석자는 누구신가요?&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Observation: &quot;민수씨와 영희씨요&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thought: 그들의 가용성 확인 필요&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Action: check_availability([&quot;민수&quot;, &quot;영희&quot;], &quot;내일 14:00&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Observation: 모두 OK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thought: 회의 생성&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Action: create_meeting(...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Observation: 회의 생성됨, ID=m_42&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thought: 사용자에게 알림&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Action: respond(&quot;내일 오후 2시에 민수씨, 영희씨와 회의 잡았습니다.&quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; react_loop&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(user_input, max_steps&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    messages &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: user_input}]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; step &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(max_steps):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm.chat(messages, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.finish_reason &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;stop&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.content   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 최종 답변&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.tool_calls:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tc &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.tool_calls:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                result &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; execute_tool(tc)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                messages.append({&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tool&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tool_call_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: tc.id, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: result})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    raise&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ReActLoopExceededError()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;음성에서는 &lt;em&gt;너무 많은 step&lt;/em&gt; = 지연 폭증. &lt;em&gt;max_steps 3-5&lt;/em&gt; 권장.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;4-human-in-the-loop-hitl&quot;&gt;4. Human-in-the-Loop (HITL)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;Agent: &quot;1억 송금&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent-&gt;&gt;HITL: critical action approval request&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    HITL-&gt;&gt;Human[운영자]: 알림 (&quot;승인 필요&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Human--&gt;&gt;HITL: approve / reject&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    HITL--&gt;&gt;Agent: result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent-&gt;&gt;User: &quot;송금 완료&quot; 또는 &quot;보안 확인 필요&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@agent.tool&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transfer_money&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(amount: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, to: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; amount &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10_000_000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        approval &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; request_human_approval(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            action&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;송금 &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;amount&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;원 → &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;            timeout&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; approval:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;송금이 보류되었습니다. 보안팀 확인 후 처리됩니다.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; bank_api.transfer(amount, to)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;amount&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;원이 송금되었습니다.&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;고위험 작업&lt;/em&gt; (금액 큰 송금, 데이터 삭제, 외부 noti) 에 인간 승인.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;패턴-조합&quot;&gt;패턴 조합&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User --&gt; Sup[Supervisor]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sup --&gt;|일반| Single[Single Agent + ReAct]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Sup --&gt;|복잡 → 전문| Hand[Handoff Chain]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Hand --&gt; Risk{고위험?}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Risk --&gt;|예| HITL[HITL Approval]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    HITL --&gt; Exec[실행]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;langgraph-예시-다중-agent--state-machine&quot;&gt;LangGraph 예시 (다중 agent + state machine)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; langgraph.graph &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; StateGraph, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;END&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; State&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;TypedDict&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    user_input: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    intent: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    result: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; classify&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(state):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    state[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;intent&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; classify_intent(state[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user_input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; state&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; payment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(state):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    state[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; handle_payment(state[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user_input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; state&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; refund&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(state):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    state[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; handle_refund(state[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user_input&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; state&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; StateGraph(State)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.add_node(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;classify&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, classify)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.add_node(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;payment&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, payment)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.add_node(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;refund&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, refund)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.set_entry_point(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;classify&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.add_conditional_edges(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;classify&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    lambda&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; s: s[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;intent&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;payment&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;payment&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;refund&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;refund&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;other&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;END&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.add_edge(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;payment&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;END&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;graph.add_edge(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;refund&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;END&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;app &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; graph.compile()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;모든 query 에 ReAct&lt;/strong&gt; = 단순 FAQ 도 3-step. 의도 분류 후 &lt;em&gt;복잡한 것만&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handoff 후 &lt;em&gt;context 손실&lt;/em&gt;&lt;/strong&gt; = 사용자가 같은 정보 반복. handoff 시 &lt;em&gt;summary&lt;/em&gt; 전달.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;너무 많은 sub-agent&lt;/strong&gt; = supervisor 가 &lt;em&gt;분류 어려움&lt;/em&gt;. 5-7개 이내.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HITL 없이 critical action&lt;/strong&gt; = 사고. 임계 정의 + 자동 승인 vs 인간.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[voice-agent-architecture]]&lt;/li&gt;
&lt;li&gt;[[voice-first-prompt]]&lt;/li&gt;
&lt;li&gt;[[function-calling]] (만일 별도 wiki 있다면)&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>agent</category><category>multi-agent</category><category>supervisor</category><category>handoff</category><category>react</category><category>hitl</category><author>koa (김신건)</author></item><item><title>[Voice AI] LLM Serving: vLLM, PagedAttention, continuous batching</title><link>https://shinkeonkim.com/wiki/ai/llm-serving-vllm/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/llm-serving-vllm/</guid><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;LLM Serving&lt;/strong&gt; = 자체 호스팅 LLM 을 &lt;em&gt;낮은 TTFT + 높은 throughput&lt;/em&gt; 으로 제공. 음성 에이전트의 &lt;em&gt;LLM 단계 지연&lt;/em&gt; 결정.&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;도구&lt;/th&gt;&lt;th&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;vLLM&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;PagedAttention&lt;/em&gt;, 표준. 한국에서도 압도적&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;TGI&lt;/strong&gt; (Hugging Face)&lt;/td&gt;&lt;td&gt;안정, 옛 표준&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SGLang&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;structured output 강함, 2024+&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;LMDeploy&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;InternLM, 중국&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;TensorRT-LLM&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;NVIDIA 전용, 최고 성능&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;pagedattention&quot;&gt;PagedAttention&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1[Request 1&amp;#x3C;br/&gt;&apos;안녕&apos;] --&gt; KV1[KV cache]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q2[Request 2&amp;#x3C;br/&gt;&apos;오늘 날씨&apos;] --&gt; KV2[KV cache]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    KV1 --&gt; Page[&quot;Memory Pages (16 tokens 단위)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    KV2 --&gt; Page&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Page --&gt; GPU[GPU memory]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;기존 (LLaMA, TGI 옛)&lt;/th&gt;&lt;th&gt;PagedAttention (vLLM)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;요청 시작 시 &lt;em&gt;최대 길이 만큼 KV cache 예약&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;Page 단위 동적 할당&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;짧은 응답도 &lt;em&gt;2K-32K 토큰 메모리&lt;/em&gt;&lt;/td&gt;&lt;td&gt;실제 사용 만큼만&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GPU 메모리 &lt;em&gt;심한 단편화&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;&amp;#x3C; 4% 낭비&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Throughput 낮음&lt;/td&gt;&lt;td&gt;&lt;em&gt;2-4x 향상&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;운영체제의 &lt;em&gt;Virtual Memory + paging&lt;/em&gt; 의 &lt;em&gt;LLM inference 적용&lt;/em&gt;. 모든 modern serving 의 기본.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;continuous-batching&quot;&gt;Continuous Batching&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Static[&quot;Static batching:&amp;#x3C;br/&gt;요청 8개 모일 때까지 대기&amp;#x3C;br/&gt;한 batch 끝날 때까지 다음 안 받음&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Cont[&quot;Continuous batching:&amp;#x3C;br/&gt;매 step 마다 batch 재구성&amp;#x3C;br/&gt;새 요청 즉시 합류, 완료된 거 즉시 빠짐&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Static --&gt; Slow[GPU idle 많음, latency 높음]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Cont --&gt; Fast[GPU 100% 활용, latency 낮음]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;step 단위 dynamic batching&lt;/em&gt; = vLLM, TGI 등의 &lt;em&gt;2026 표준&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;ttft-time-to-first-token-vs-tps&quot;&gt;TTFT (Time-to-First-Token) vs TPS&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Req[Request 도착] --&gt;|&quot;prefill (전체 prompt 처리)&quot;| F1[First token]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    F1 --&gt;|&quot;decode (1 토큰씩)&quot;| T2[Token 2]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    T2 --&gt;|decode| T3[Token 3]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note[&quot;TTFT = prefill 시간&amp;#x3C;br/&gt;TPS = decode 속도&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;지표&lt;/th&gt;&lt;th&gt;의미&lt;/th&gt;&lt;th&gt;목표&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;TTFT&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;첫 토큰까지&lt;/td&gt;&lt;td&gt;&lt;em&gt;&amp;#x3C; 200ms&lt;/em&gt; (음성)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;TPS&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;초당 토큰&lt;/td&gt;&lt;td&gt;&gt; 50 tok/s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Throughput&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;동시 요청 처리&lt;/td&gt;&lt;td&gt;GPU 효율&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;음성 에이전트 = &lt;em&gt;TTFT 가 결정적&lt;/em&gt;. sentence aggregator 가 &lt;em&gt;첫 문장 받으면 TTS 시작&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;sse-스트리밍-server-sent-events&quot;&gt;SSE 스트리밍 (Server-Sent Events)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;http&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;GET&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /v1/chat/completions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;Accept&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; text/event-stream&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; {&quot;choices&quot;: [{&quot;delta&quot;: {&quot;content&quot;: &quot;안&quot;}}]}\n\n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; {&quot;choices&quot;: [{&quot;delta&quot;: {&quot;content&quot;: &quot;녕&quot;}}]}\n\n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; {&quot;choices&quot;: [{&quot;delta&quot;: {&quot;content&quot;: &quot;하세요&quot;}}]}\n\n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; [DONE]\n\n&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; openai &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AsyncOpenAI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AsyncOpenAI(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;base_url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://localhost:8000/v1&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;stream &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;llama-3.1-8b-instruct&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    stream&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chunk &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; stream:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    delta &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chunk.choices[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].delta.content&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; delta:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        sentence_aggregator.feed(delta)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자세한 SSE 는 [[SSE]] 의 일반.&lt;/p&gt;
&lt;h2 id=&quot;vllm-시작&quot;&gt;vLLM 시작&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; vllm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# OpenAI 호환 server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;python&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; vllm.entrypoints.openai.api_server&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --model&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; meta-llama/Llama-3.1-8B-Instruct&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --max-model-len&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 8192&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --gpu-memory-utilization&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0.9&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --enable-chunked-prefill&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --enable-prefix-caching&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --port&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 8000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;옵션&lt;/th&gt;&lt;th&gt;의미&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--max-model-len&lt;/code&gt;&lt;/td&gt;&lt;td&gt;최대 context&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--gpu-memory-utilization&lt;/code&gt;&lt;/td&gt;&lt;td&gt;GPU 메모리 사용률 (0.9 권장)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--enable-chunked-prefill&lt;/code&gt;&lt;/td&gt;&lt;td&gt;긴 prompt 를 청크로 분할 (latency 균형)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--enable-prefix-caching&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;같은 prefix 의 KV cache 재사용&lt;/em&gt; (system prompt!)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--tensor-parallel-size N&lt;/code&gt;&lt;/td&gt;&lt;td&gt;N GPU 분산&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;--pipeline-parallel-size N&lt;/code&gt;&lt;/td&gt;&lt;td&gt;pipeline 분산&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;prefix-caching-system-prompt-재사용&quot;&gt;Prefix Caching (system prompt 재사용)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Req1[&quot;Req 1: SYS+&apos;안녕&apos;&quot;] --&gt; Cache[&quot;Prefix Cache (SYS)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Req2[&quot;Req 2: SYS+&apos;오늘&apos;&quot;] --&gt; Cache&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Req3[&quot;Req 3: SYS+&apos;주문&apos;&quot;] --&gt; Cache&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note[&quot;같은 system prompt 의 KV cache 재사용&amp;#x3C;br/&gt;→ TTFT 60-90% 단축&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;모든 요청이 &lt;em&gt;같은 긴 system prompt&lt;/em&gt; 면 &lt;em&gt;prefix caching&lt;/em&gt; 으로 &lt;em&gt;prefill 시간 거의 0&lt;/em&gt;. 음성 에이전트의 &lt;em&gt;고정 페르소나 prompt&lt;/em&gt; 와 완벽 매칭.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;quantization&quot;&gt;Quantization&lt;/h2&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;종류&lt;/th&gt;&lt;th&gt;메모리&lt;/th&gt;&lt;th&gt;정확도&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;FP16&lt;/td&gt;&lt;td&gt;100%&lt;/td&gt;&lt;td&gt;기준&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FP8 (H100+)&lt;/td&gt;&lt;td&gt;50%&lt;/td&gt;&lt;td&gt;~99%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;INT8 (smoothquant)&lt;/td&gt;&lt;td&gt;50%&lt;/td&gt;&lt;td&gt;~98%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;INT4 (AWQ, GPTQ)&lt;/td&gt;&lt;td&gt;25%&lt;/td&gt;&lt;td&gt;~95%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;INT4 + KV cache FP8&lt;/td&gt;&lt;td&gt;작음&lt;/td&gt;&lt;td&gt;~93%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# AWQ 4-bit 모델&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;python&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; vllm.entrypoints.openai.api_server&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --model&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; TheBloke/Llama-3.1-8B-Instruct-AWQ&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --quantization&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; awq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자세한 quantization 은 [[quantization]] 참고.&lt;/p&gt;
&lt;h2 id=&quot;모델-크기-vs-음성-적합성&quot;&gt;모델 크기 vs 음성 적합성&lt;/h2&gt;





















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;모델&lt;/th&gt;&lt;th&gt;한국어&lt;/th&gt;&lt;th&gt;TTFT (8B GPU)&lt;/th&gt;&lt;th&gt;적합&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Llama-3.1 8B Instruct&lt;/td&gt;&lt;td&gt;보통&lt;/td&gt;&lt;td&gt;150ms&lt;/td&gt;&lt;td&gt;일반&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Llama-3.1 70B AWQ&lt;/td&gt;&lt;td&gt;우수&lt;/td&gt;&lt;td&gt;400ms&lt;/td&gt;&lt;td&gt;복잡 task&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Qwen2.5 7B Instruct&lt;/td&gt;&lt;td&gt;우수&lt;/td&gt;&lt;td&gt;130ms&lt;/td&gt;&lt;td&gt;한국어 강함&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;EXAONE 3 7.8B&lt;/td&gt;&lt;td&gt;&lt;em&gt;최우수 (한국어)&lt;/em&gt;&lt;/td&gt;&lt;td&gt;150ms&lt;/td&gt;&lt;td&gt;한국어 voice agent&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Phi-3.5 mini (3.8B)&lt;/td&gt;&lt;td&gt;보통&lt;/td&gt;&lt;td&gt;60ms&lt;/td&gt;&lt;td&gt;edge, latency critical&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GPT-4o-mini (API)&lt;/td&gt;&lt;td&gt;우수&lt;/td&gt;&lt;td&gt;200ms (API)&lt;/td&gt;&lt;td&gt;일반&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Gemini Flash 2.0 (API)&lt;/td&gt;&lt;td&gt;우수&lt;/td&gt;&lt;td&gt;250ms (API)&lt;/td&gt;&lt;td&gt;일반&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;speculative-decoding&quot;&gt;Speculative Decoding&lt;/h2&gt;
&lt;p&gt;작은 &lt;strong&gt;draft model&lt;/strong&gt; 이 여러 토큰을 연속 생성하고, 큰 &lt;strong&gt;target model&lt;/strong&gt; 이 한 번의 forward pass 로 전부 검증. 드래프트가 맞으면 한 번에 여러 토큰 확보, 틀리면 target 이 재생성.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    D[&quot;Draft model (소형)&quot;] --&gt;|&quot;토큰 N개 예측&quot;| V[&quot;Target model (대형)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    V --&gt;|&quot;k개 수락&quot;| OUT[출력]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    V --&gt;|&quot;k+1번째 거절: 재생성&quot;| D&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;항목&lt;/th&gt;&lt;th&gt;값&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;적합한 draft 크기&lt;/td&gt;&lt;td&gt;target 파라미터의 10-20%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;평균 수용률&lt;/td&gt;&lt;td&gt;60-85%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;decode 속도 향상&lt;/td&gt;&lt;td&gt;2-3x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TTFT 영향&lt;/td&gt;&lt;td&gt;없음 (prefill 미변경)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;vLLM 옵션: &lt;code&gt;--num-speculative-tokens 5 --speculative-model /path/to/draft&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;draft 와 target 의 &lt;strong&gt;tokenizer 가 반드시 동일&lt;/strong&gt;해야 함. 다르면 token ID mismatch.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;docker-배포&quot;&gt;Docker 배포&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --runtime&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; nvidia&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --gpus&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; all&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    -v&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ~/.cache/huggingface:/root/.cache/huggingface&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    -p&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 8000:8000&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --ipc=host&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    vllm/vllm-openai:latest&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --model&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; meta-llama/Llama-3.1-8B-Instruct&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --max-model-len&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 8192&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --enable-prefix-caching&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --gpu-memory-utilization&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0.9&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;multi-GPU (tensor parallel):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --runtime&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; nvidia&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --gpus&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; all&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    -p&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 8000:8000&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --ipc=host&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    vllm/vllm-openai:latest&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --model&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; meta-llama/Llama-3.1-70B-Instruct&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --tensor-parallel-size&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;운영-지표&quot;&gt;운영 지표&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    vLLM[&quot;vLLM /metrics&quot;] --&gt;|scrape| Prom[Prometheus]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Prom --&gt; Graf[Grafana]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Graf --&gt;|&quot;TTFT p99 대시보드&quot;| Dashboard[대시보드]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Graf --&gt;|&quot;임계값 초과시&quot;| Alert[알림]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;지표&lt;/th&gt;&lt;th&gt;의미&lt;/th&gt;&lt;th&gt;경보 기준&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;vllm:time_to_first_token_seconds&lt;/code&gt;&lt;/td&gt;&lt;td&gt;TTFT&lt;/td&gt;&lt;td&gt;p99 &gt; 500ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;vllm:e2e_request_latency_seconds&lt;/code&gt;&lt;/td&gt;&lt;td&gt;전체 지연&lt;/td&gt;&lt;td&gt;p99 &gt; 3s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;vllm:num_requests_running&lt;/code&gt;&lt;/td&gt;&lt;td&gt;처리 중 요청 수&lt;/td&gt;&lt;td&gt;&gt; max batch size&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;vllm:num_requests_waiting&lt;/code&gt;&lt;/td&gt;&lt;td&gt;대기 큐&lt;/td&gt;&lt;td&gt;&gt; 50&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;vllm:gpu_cache_usage_perc&lt;/code&gt;&lt;/td&gt;&lt;td&gt;KV cache 점유율&lt;/td&gt;&lt;td&gt;&gt; 90%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;code&gt;--disable-log-requests&lt;/code&gt; 플래그로 액세스 로그 비활성화. Prometheus 스크레이프는 &lt;code&gt;/metrics&lt;/code&gt; 엔드포인트.&lt;/p&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;prefix caching 없이 큰 system prompt&lt;/strong&gt; = 매 요청 prefill 1초+. 활성화 필수.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;streaming 안 함&lt;/strong&gt; = 응답 끝나길 기다림. &lt;em&gt;항상 stream=True&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU memory util 너무 높음 (0.95+)&lt;/strong&gt; = OOM 위험. 0.85-0.9.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;연속 batching 없는 옛 서빙&lt;/strong&gt; = throughput 1/5. vLLM 으로.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[voice-agent-architecture]]&lt;/li&gt;
&lt;li&gt;[[tts-streaming-ssml]] (LLM 토큰 → SSE → TTS)&lt;/li&gt;
&lt;li&gt;[[quantization]]&lt;/li&gt;
&lt;li&gt;[[SSE]]&lt;/li&gt;
&lt;li&gt;[[latency-percentiles]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>llm-serving</category><category>vllm</category><category>paged-attention</category><category>kv-cache</category><category>ttft</category><author>koa (김신건)</author></item><item><title>[Voice AI] Pipecat vs LiveKit Agents: 프레임워크 비교</title><link>https://shinkeonkim.com/wiki/ai/pipecat-livekit/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/pipecat-livekit/</guid><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;2026 시점 &lt;em&gt;voice agent 프레임워크&lt;/em&gt; 4가지 선택지:&lt;/p&gt;






















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Pipecat&lt;/th&gt;&lt;th&gt;LiveKit Agents&lt;/th&gt;&lt;th&gt;Vapi / Retell&lt;/th&gt;&lt;th&gt;자체 구축&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;카테고리&lt;/td&gt;&lt;td&gt;OSS framework&lt;/td&gt;&lt;td&gt;OSS SFU + framework&lt;/td&gt;&lt;td&gt;Managed&lt;/td&gt;&lt;td&gt;직접&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;운영&lt;/td&gt;&lt;td&gt;self-host&lt;/td&gt;&lt;td&gt;self-host 또는 LiveKit Cloud&lt;/td&gt;&lt;td&gt;호스팅&lt;/td&gt;&lt;td&gt;self&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;학습 곡선&lt;/td&gt;&lt;td&gt;중간&lt;/td&gt;&lt;td&gt;중간&lt;/td&gt;&lt;td&gt;&lt;em&gt;낮음&lt;/em&gt;&lt;/td&gt;&lt;td&gt;높음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;비용&lt;/td&gt;&lt;td&gt;인프라만&lt;/td&gt;&lt;td&gt;인프라만 (LK Cloud 옵션)&lt;/td&gt;&lt;td&gt;비쌈 ($0.13-0.30/min)&lt;/td&gt;&lt;td&gt;인프라&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;유연성&lt;/td&gt;&lt;td&gt;&lt;em&gt;높음&lt;/em&gt;&lt;/td&gt;&lt;td&gt;높음&lt;/td&gt;&lt;td&gt;&lt;em&gt;낮음&lt;/em&gt; (블랙박스)&lt;/td&gt;&lt;td&gt;&lt;em&gt;최고&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;시간&lt;/td&gt;&lt;td&gt;1-2주&lt;/td&gt;&lt;td&gt;1-2주&lt;/td&gt;&lt;td&gt;1-2일&lt;/td&gt;&lt;td&gt;1-3개월&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;pipecat&quot;&gt;Pipecat&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Frame[Frame] --&gt; P1[&quot;Input Processor (mic)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P1 --&gt; P2[VAD Processor]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P2 --&gt; P3[STT Processor]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P3 --&gt; P4[LLM Processor]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P4 --&gt; P5[Aggregator]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P5 --&gt; P6[TTS Processor]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    P6 --&gt; P7[&quot;Output Processor (speaker)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Frame 이 processor 파이프라인을 흐름&lt;/em&gt;. Linux pipe 의 기능적 추상. 컴포넌트 &lt;em&gt;한 줄 교체&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pipecat.pipeline.pipeline &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Pipeline&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pipecat.services.deepgram &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DeepgramSTTService&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pipecat.services.openai &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; OpenAILLMService&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pipecat.services.cartesia &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CartesiaTTSService&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pipecat.transports.services.daily &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DailyTransport&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pipecat.vad.silero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SileroVADAnalyzer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;transport &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; DailyTransport(room_url, token, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Bot&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, DailyParams(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    audio_in_enabled&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    audio_out_enabled&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    vad_analyzer&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;SileroVADAnalyzer(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pipeline &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Pipeline([&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    transport.input(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    DeepgramSTTService(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;api_key&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    OpenAILLMService(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;api_key&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CartesiaTTSService(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;api_key&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;voice_id&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    transport.output(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;runner &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; PipelineRunner()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; runner.run(PipelineTask(pipeline))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;pipecat-의-frame-종류&quot;&gt;Pipecat 의 Frame 종류&lt;/h3&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Frame&lt;/th&gt;&lt;th&gt;의미&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;AudioRawFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;오디오 청크&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;TextFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;텍스트&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;TranscriptionFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;전사&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;LLMResponseStartFrame&lt;/code&gt; / &lt;code&gt;EndFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;LLM 응답 경계&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;TTSStartFrame&lt;/code&gt; / &lt;code&gt;EndFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;TTS 시작/종료&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;UserStartedSpeakingFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;사용자 발화 시작&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;UserStoppedSpeakingFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;종료&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;InterruptionFrame&lt;/code&gt;&lt;/td&gt;&lt;td&gt;끼어들기&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Frame 종류 추가 = 새 processor 추가&lt;/em&gt;. 확장이 깔끔.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;livekit-agents&quot;&gt;LiveKit Agents&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User1[&quot;사용자 1&quot;] --&gt;|WebRTC| SFU[LiveKit SFU]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User2[&quot;사용자 2&quot;] --&gt;|WebRTC| SFU&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    SFU --&gt;|Room API| Agent[&quot;Voice Agent&amp;#x3C;br/&gt;(headless participant)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent --&gt; STT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent --&gt; LLM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent --&gt; TTS&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;LiveKit SFU&lt;/em&gt; 가 &lt;em&gt;WebRTC + room&lt;/em&gt; 인프라. &lt;em&gt;Agent 가 room 에 headless participant 로 합류&lt;/em&gt; → 다중 사용자 회의 / 룸 기반 voice agent 자연스러움.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; livekit.agents &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; VoiceAssistant, AutoSubscribe, JobContext, WorkerOptions, cli&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; livekit.agents.llm &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ChatContext&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; livekit.plugins &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; openai, silero, deepgram, cartesia&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; entrypoint&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ctx: JobContext):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ctx.connect(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;auto_subscribe&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;AutoSubscribe.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;AUDIO_ONLY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    initial_ctx &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ChatContext().append(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        role&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        text&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;당신은 친절한 한국어 음성 어시스턴트입니다. 짧게 답하세요.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    assistant &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; VoiceAssistant(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        vad&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;silero.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;VAD&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.load(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        stt&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;deepgram.STT(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;language&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ko&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        llm&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;openai.LLM(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        tts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;cartesia.TTS(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;voice&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;language&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ko&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        chat_ctx&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;initial_ctx,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        min_endpointing_delay&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;        allow_interruptions&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    assistant.start(ctx.room)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; assistant.aclose()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;pipecat-vs-livekit-agents-결정&quot;&gt;Pipecat vs LiveKit Agents 결정&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1{시나리오}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|1:1 콜봇, 전화| Pipecat&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|다중 사용자 방, WebRTC 우선| LK[LiveKit Agents]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|화상 회의 + AI 참여자| LK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|복잡한 frame 변환| Pipecat&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|이미 LiveKit SFU 운영| LK&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Pipecat&lt;/th&gt;&lt;th&gt;LiveKit Agents&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Transport&lt;/td&gt;&lt;td&gt;Daily, Twilio, Plivo, FastAPI 등 다양&lt;/td&gt;&lt;td&gt;LiveKit SFU 중심&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;추상 단위&lt;/td&gt;&lt;td&gt;Frame + Processor&lt;/td&gt;&lt;td&gt;Function 기반&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;회의 / 룸&lt;/td&gt;&lt;td&gt;단순&lt;/td&gt;&lt;td&gt;&lt;em&gt;강력&lt;/em&gt; (Multi-participant)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;&lt;em&gt;우선&lt;/em&gt;&lt;/td&gt;&lt;td&gt;Python + Node + Go&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;학습&lt;/td&gt;&lt;td&gt;약간 가파름&lt;/td&gt;&lt;td&gt;친절한 docs&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;managed-vapi-retell&quot;&gt;Managed (Vapi, Retell)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    You[당신] --&gt;|시스템 프롬프트만| Vapi[Vapi / Retell]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Vapi --&gt;|호스팅 파이프라인| Tel[Twilio 전화]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Vapi --&gt;|기본 STT/LLM/TTS| Pipeline&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;




















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;장점&lt;/th&gt;&lt;th&gt;단점&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Vapi&lt;/td&gt;&lt;td&gt;5분 만에 PoC&lt;/td&gt;&lt;td&gt;&lt;em&gt;블랙박스&lt;/em&gt;, $0.13-0.30/min&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Retell&lt;/td&gt;&lt;td&gt;빠른 시작, 음성 좋음&lt;/td&gt;&lt;td&gt;동일, &lt;em&gt;latency 가시성 낮음&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;build-vs-buy-기준-hamming-ai-가이드&quot;&gt;Build vs Buy 기준 (Hamming AI 가이드)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q{기준}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt;|&quot;월 &amp;#x3C; 10K 분&quot;| Buy[Vapi / Retell]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt;|&quot;월 10-50K 분&quot;| Mid[&quot;Pipecat / LiveKit (자체)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt;|&quot;월 &gt; 50K 분&quot;| Build[자체 + 깊은 최적화]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt;|&quot;엄격한 컴플라이언스 (HIPAA, FINRA)&quot;| Build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt;|&quot;500ms 미만 지연 필수&quot;| Build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt;|&quot;기존 system 깊은 통합&quot;| Build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Build --&gt; Save[&quot;최대 80% 비용 절감 가능&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;em&gt;PoC = Vapi/Retell&lt;/em&gt;. &lt;em&gt;확장 시 → Pipecat/LiveKit 마이그레이션&lt;/em&gt; 흐름이 일반.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;복원력-설계&quot;&gt;복원력 설계&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q[복원력 요소]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt; Fail[Independent failure points: STT, LLM, TTS]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q --&gt; Strat[전략]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Strat --&gt; Retry[Retry + backoff]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Strat --&gt; Fallback[&quot;Fallback (다른 vendor)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Strat --&gt; Graceful[&quot;Graceful: #quot;잠시 후 다시#quot;&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Strat --&gt; Health[&quot;Health check + circuit breaker&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 단계 독립 실패 → 우아하게 처리. 자세한 건 [[retry-with-backoff]] / [[circuit-breaker]].&lt;/p&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Managed 만 사용&lt;/strong&gt; = 비용 폭증 + 가시성 0. 1000분+ 면 self-host.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipecat 의 Frame 무시&lt;/strong&gt; = 직접 콜백으로 짜다가 &lt;em&gt;경합 / 순서 문제&lt;/em&gt;. Frame 모델 활용.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LiveKit 의 transcription frame&lt;/strong&gt; = STT 결과가 &lt;em&gt;partial vs final&lt;/em&gt; 분리 안 보임. 명시 처리.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자체 구축 시 turn detection&lt;/strong&gt; = VAD 만으로 한계. 시맨틱 모델 필요. Pipecat / LK 가 내장한 이유.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;레이턴시-구성-요소&quot;&gt;레이턴시 구성 요소&lt;/h2&gt;
&lt;p&gt;voice agent 의 E2E 레이턴시는 각 단계가 직렬로 합산된다:&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;단계&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;일반적 범위&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;메모&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;VAD 종료 감지&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;200-500ms&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;너무 빠르면 발화 중 끊김&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;STT 첫 응답&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;300-600ms&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;streaming 시 단축됨&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;LLM 첫 토큰&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;500-2000ms&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;모델 크기, 네트워크 의존&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;TTS 첫 청크&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;200-500ms&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;streaming TTS 시 단축됨&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;버퍼 / 전송 지연&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;50-200ms&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;WebRTC jitter buffer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;합계 최적화 전&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;1.2-3.8초&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    VAD[&quot;VAD 종료 감지&quot;] --&gt; STT[&quot;STT 인식&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    STT --&gt; LLM[&quot;LLM 첫 토큰&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM --&gt;|&quot;streaming 출력&quot;| TTS[&quot;TTS 합성&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TTS --&gt; Out[&quot;사용자 출력&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LLM 첫 토큰 도착 즉시 TTS streaming 을 시작하면 LLM 생성 + TTS 합성이 병렬로 겹쳐 전체 체감 레이턴시가 줄어든다.&lt;/p&gt;
&lt;h2 id=&quot;레이턴시-최적화-전략&quot;&gt;레이턴시 최적화 전략&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Streaming 파이프라인&lt;/strong&gt;: LLM 토큰 스트림 + TTS 동시 시작. Pipecat &lt;code&gt;LLMResponseAggregatorService&lt;/code&gt; + &lt;code&gt;TTSService&lt;/code&gt; 직결 시 자동 streaming.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VAD 임계값 튜닝&lt;/strong&gt;: 민감도 높으면 발화 중 끊김, 둔감하면 레이턴시 증가. &lt;code&gt;threshold=0.5&lt;/code&gt;, &lt;code&gt;min_silence_duration_ms=300&lt;/code&gt; 이 출발점.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모델 선택&lt;/strong&gt;: 짧은 응답은 GPT-4o-mini, 복잡한 추론만 GPT-4o. 한국어 TTS 는 Cartesia 가 ElevenLabs 보다 레이턴시 낮은 경우 많음.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;지역 배포&lt;/strong&gt;: STT / TTS API 와 서버 리전을 맞춤. 한국 사용자면 &lt;code&gt;ap-northeast-2&lt;/code&gt; 우선.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebRTC 우선&lt;/strong&gt;: WebSocket 보다 P2P 최적 라우팅. LiveKit SFU 가 이를 담당.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;워밍업 요청&lt;/strong&gt;: 첫 발화 전 LLM / TTS 서비스에 더미 요청해 cold start 제거.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;스택-선택-체크리스트&quot;&gt;스택 선택 체크리스트&lt;/h2&gt;



























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;체크포인트&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Vapi / Retell&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Pipecat&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;LiveKit Agents&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;1주 내 PoC&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;보통&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;보통&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;다중 참여자 룸&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;제한적&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;제한적&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;커스텀 VAD / STT&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;제한적&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;자체 인프라 운영&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;불가&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;비용 예측 가능성&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;선불 요금&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;인프라만&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;인프라만&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;HIPAA / 컴플라이언스&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;미확인&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;self-host 가능&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;self-host 가능&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Python 생태계 우선&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;보통&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Node / Go 지원&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;-&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;제한적&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;프로덕션-운영-팁&quot;&gt;프로덕션 운영 팁&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
Pipecat / LiveKit 모두 asyncio 기반. 블로킹 I/O 를 asyncio loop 안에서 직접 호출하면 전체 파이프라인이 멈춘다. &lt;code&gt;asyncio.to_thread&lt;/code&gt; 또는 전용 executor 로 분리.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;헬스 체크&lt;/strong&gt;: &lt;code&gt;/health&lt;/code&gt; 엔드포인트 + LiveKit room 상태 폴링. 에이전트가 죽으면 참여자는 침묵만 들음.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;그레이스풀 종료&lt;/strong&gt;: &lt;code&gt;SIGTERM&lt;/code&gt; 수신 시 현재 발화 완료 후 종료. Pipecat &lt;code&gt;PipelineRunner.stop_when_done()&lt;/code&gt; 활용.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분산 추적&lt;/strong&gt;: 각 Frame 에 &lt;code&gt;call_id&lt;/code&gt;, &lt;code&gt;turn_id&lt;/code&gt; 메타데이터 부착해 로그 연결.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;요금 폭발 방지&lt;/strong&gt;: 무응답 30초 후 자동 종료. Vapi / Retell idle timeout 설정 확인.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;에코 처리&lt;/strong&gt;: AEC (Acoustic Echo Cancellation) 는 transport layer 담당. Daily.co 는 내장, 직접 WebRTC 구현 시 별도 처리 필요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[voice-agent-architecture]]&lt;/li&gt;
&lt;li&gt;[[vad-silero]]&lt;/li&gt;
&lt;li&gt;[[turn-detection-barge-in]]&lt;/li&gt;
&lt;li&gt;[[webrtc]]&lt;/li&gt;
&lt;li&gt;[[circuit-breaker]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>pipecat</category><category>livekit</category><category>voice-framework</category><category>agent</category><category>sfu</category><author>koa (김신건)</author></item><item><title>[Voice AI] 음성 에이전트 아키텍처: Cascading / Streaming / S2S + Latency Budget</title><link>https://shinkeonkim.com/wiki/ai/voice-agent-architecture/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/voice-agent-architecture/</guid><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;실시간 음성 AI 의 &lt;em&gt;3가지 패턴&lt;/em&gt;. 각자 &lt;em&gt;지연 vs 유연성 vs 비용&lt;/em&gt; 트레이드오프.&lt;/p&gt;
&lt;h2 id=&quot;3-패턴-비교&quot;&gt;3 패턴 비교&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Cascading[&quot;1. Cascading (순차)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        C1[STT] --&gt; C2[LLM] --&gt; C3[TTS]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Note1[&quot;2-4초 지연 (직렬)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph Streaming[&quot;2. Streaming (병행)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        S1[STT chunks] -.partial.-&gt; S2[LLM streaming]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        S2 -.tokens.-&gt; S3[TTS streaming]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Note2[&quot;&amp;#x3C; 1초 지연 (병행)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subgraph S2S[&quot;3. Speech-to-Speech&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        D1[Audio In] --&gt; D2[Multimodal Model]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        D2 --&gt; D3[Audio Out]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Note3[&quot;&amp;#x3C; 300ms (직접 처리)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Cascading&lt;/th&gt;&lt;th&gt;Streaming&lt;/th&gt;&lt;th&gt;S2S&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;종단 지연&lt;/td&gt;&lt;td&gt;&lt;em&gt;2-4초&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;&amp;#x3C; 1초&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;&amp;#x3C; 300ms&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;구현 난이도&lt;/td&gt;&lt;td&gt;쉬움&lt;/td&gt;&lt;td&gt;중간&lt;/td&gt;&lt;td&gt;어려움 (제약)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;유연성&lt;/td&gt;&lt;td&gt;&lt;em&gt;최고&lt;/em&gt; (각 단계 교체)&lt;/td&gt;&lt;td&gt;높음&lt;/td&gt;&lt;td&gt;&lt;em&gt;낮음&lt;/em&gt; (벤더 lock)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;비용&lt;/td&gt;&lt;td&gt;낮음&lt;/td&gt;&lt;td&gt;중간&lt;/td&gt;&lt;td&gt;&lt;em&gt;높음&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Function calling&lt;/td&gt;&lt;td&gt;OK&lt;/td&gt;&lt;td&gt;OK&lt;/td&gt;&lt;td&gt;&lt;em&gt;제한&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;톤/감정 보존&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;&lt;em&gt;예&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;한국어&lt;/td&gt;&lt;td&gt;모델 마다&lt;/td&gt;&lt;td&gt;모델 마다&lt;/td&gt;&lt;td&gt;일부 (Realtime API 한국어)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;사용&lt;/td&gt;&lt;td&gt;MVP / 일반&lt;/td&gt;&lt;td&gt;&lt;em&gt;프로덕션 표준&lt;/em&gt;&lt;/td&gt;&lt;td&gt;고급 UX&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;1-cascading-순차&quot;&gt;1. Cascading (순차)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;STT: 발화 (3초)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over STT: 발화 종료 대기 + 전사 (500ms)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    STT-&gt;&gt;LLM: 전체 텍스트&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over LLM: 응답 생성 (1500ms)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM-&gt;&gt;TTS: 전체 응답&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over TTS: 음성 합성 (800ms)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TTS-&gt;&gt;User: 음성 시작&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over User,TTS: 총: ~3초 지연&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cascaded_pipeline&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(audio_url):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    transcript &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; stt.transcribe(audio_url)   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 발화 끝나길 기다림&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm.chat(transcript)           &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 전체 응답&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    audio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tts.synthesize(response)          &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 전체 합성&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; audio&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;MVP 에는 OK&lt;/em&gt;. 프로덕션은 &lt;em&gt;streaming&lt;/em&gt; 으로 진화.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;2-streaming-현재-표준&quot;&gt;2. Streaming (현재 표준)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;STT: 발화 (3초)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    par&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        STT--&gt;&gt;LLM: partial &quot;안녕&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        STT--&gt;&gt;LLM: partial &quot;안녕하세요&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        STT--&gt;&gt;LLM: FINAL &quot;안녕하세요, 오늘 회의&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        LLM--&gt;&gt;TTS: 토큰 &quot;오늘은&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        LLM--&gt;&gt;TTS: 토큰 &quot;수요일입니다&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        TTS--&gt;&gt;User: 오디오 청크 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        TTS--&gt;&gt;User: 오디오 청크 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over User: 음성 종료 후 &amp;#x3C; 1초 응답&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; streaming_pipeline&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(audio_stream):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; transcript_chunk &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; stt.stream(audio_stream):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; transcript_chunk.is_final:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; token &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; llm.stream(transcript_chunk.text):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                sentence &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; aggregator.feed(token)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; audio_chunk &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tts.stream(sentence):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                        yield&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; audio_chunk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;em&gt;모든 단계 스트리밍 + sentence aggregator&lt;/em&gt;. 2026 시점 &lt;em&gt;프로덕션 음성 AI 의 표준&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;3-speech-to-speech-s2s&quot;&gt;3. Speech-to-Speech (S2S)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;Realtime: 오디오 stream (WebRTC / WS)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Note over Realtime: GPT-4o / Gemini Live&amp;#x3C;br/&gt;(직접 오디오 처리)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Realtime--&gt;&gt;User: 오디오 stream (&amp;#x3C; 300ms)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;모델&lt;/th&gt;&lt;th&gt;출시&lt;/th&gt;&lt;th&gt;한국어&lt;/th&gt;&lt;th&gt;특징&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;OpenAI Realtime API (GPT-4o)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;2024-10&lt;/td&gt;&lt;td&gt;우수&lt;/td&gt;&lt;td&gt;WebRTC / WS, function calling 부분&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Gemini Live (gemini-live-2.5)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;2024-12&lt;/td&gt;&lt;td&gt;우수&lt;/td&gt;&lt;td&gt;Google AI Studio&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Moshi (Kyutai)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;OSS&lt;/td&gt;&lt;td&gt;영어&lt;/td&gt;&lt;td&gt;full-duplex, 자체 호스팅&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
S2S 의 &lt;em&gt;function calling 제약&lt;/em&gt; = enterprise 시스템 연동 어려움. &lt;em&gt;function 이 필수면 cascading + streaming&lt;/em&gt; 채택. [arXiv 참조].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;latency-budget-지연-예산&quot;&gt;Latency Budget (지연 예산)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Mic[&quot;마이크 (사용자 발화 끝)&quot;] --&gt;|VAD endpointing 200-500ms| STT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    STT --&gt;|&quot;STT (100-500ms)&quot;| LLM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM --&gt;|&quot;LLM TTFT (200-2000ms)&quot;| TTS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TTS --&gt;|&quot;TTS TTFA (200-800ms)&quot;| Speaker&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Speaker --&gt;|&amp;#x3C;= 1000ms| User&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;단계&lt;/th&gt;&lt;th&gt;일반&lt;/th&gt;&lt;th&gt;최적&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Network (Mic → Server)&lt;/td&gt;&lt;td&gt;30-100ms&lt;/td&gt;&lt;td&gt;20ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;VAD endpointing&lt;/td&gt;&lt;td&gt;500ms&lt;/td&gt;&lt;td&gt;200ms (시맨틱)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;STT (final)&lt;/td&gt;&lt;td&gt;200-500ms&lt;/td&gt;&lt;td&gt;100ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LLM TTFT (Time-to-First-Token)&lt;/td&gt;&lt;td&gt;500-2000ms&lt;/td&gt;&lt;td&gt;200ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sentence aggregation&lt;/td&gt;&lt;td&gt;50-200ms&lt;/td&gt;&lt;td&gt;0 (streaming)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TTS TTFB&lt;/td&gt;&lt;td&gt;200-800ms&lt;/td&gt;&lt;td&gt;90ms (Cartesia)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Network (Server → Speaker)&lt;/td&gt;&lt;td&gt;30-100ms&lt;/td&gt;&lt;td&gt;20ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;총&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;2-4초&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;&amp;#x3C; 700ms&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;em&gt;800ms 가 “로봇 같지 않게 느껴지는” 임계&lt;/em&gt;. 사람 평균 응답 300-500ms. &lt;em&gt;모든 단계 동시 최적화&lt;/em&gt; 필요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;단계별-최적화&quot;&gt;단계별 최적화&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Opt[지연 줄이기]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Opt --&gt; S1[STT: 시맨틱 endpointing, partial 안 기다림]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Opt --&gt; S2[LLM: 작은 모델, TTFT 최우선, KV-cache]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Opt --&gt; S3[TTS: streaming + Cartesia급 모델]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Opt --&gt; Net[Network: WebRTC &amp;#x3C; WebSocket &amp;#x3C; HTTP]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Opt --&gt; Hop[Hop 축소: 같은 region, edge]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;결정-트리&quot;&gt;결정 트리&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1{지연 요구}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|&amp;#x3C; 300ms 필수| S2S_check{Function calling 필수?}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|&amp;#x3C; 1초 OK| Stream[Streaming pipeline]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Q1 --&gt;|2-3초 OK + MVP| Cascade[Cascading]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    S2S_check --&gt;|아니오| S2S[S2S 모델]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    S2S_check --&gt;|예| Stream&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;한국-시장-권장&quot;&gt;한국 시장 권장&lt;/h2&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;시나리오&lt;/th&gt;&lt;th&gt;권장&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;콜봇 (상담)&lt;/td&gt;&lt;td&gt;Streaming: CLOVA STT + GPT-4o-mini + CLOVA Voice&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;고급 음성 AI&lt;/td&gt;&lt;td&gt;Streaming: Deepgram + GPT-4o + Cartesia&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;비용 절감&lt;/td&gt;&lt;td&gt;Cascading: Whisper + GPT-3.5 + Edge TTS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;톤/감정 critical&lt;/td&gt;&lt;td&gt;S2S: GPT-4o Realtime&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;STT/LLM/TTS 각자 다른 region&lt;/strong&gt; = network hop 누적 → 500ms+. 같은 region.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;batch 모델로 시작했다가 latency 못 맞춤&lt;/strong&gt; = 처음부터 streaming 모델.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 응답 끝나길 기다리고 TTS 시작&lt;/strong&gt; = TTS 의 streaming 의미 없음.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VAD 없이 STT&lt;/strong&gt; = STT 가 &lt;em&gt;전사 못 끝남&lt;/em&gt;. 발화 종료 감지 필수.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;인프라-요구사항&quot;&gt;인프라 요구사항&lt;/h2&gt;
&lt;h3 id=&quot;네트워크&quot;&gt;네트워크&lt;/h3&gt;
&lt;p&gt;음성 에이전트는 낮은 레이턴시가 생명입니다.&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;프로토콜&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;지연&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;용도&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;WebRTC&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최저&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;브라우저 / 모바일 클라이언트. 미디어 서버 (LiveKit, Daily) 경유.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;WebSocket&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버-서버 또는 기기 연결. 텍스트/바이너리 양방향 스트림.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;HTTP chunked&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단순 구현 가능하나 지연 큼. 프로토타입에만 권장.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;vad-voice-activity-detection-선택&quot;&gt;VAD (Voice Activity Detection) 선택&lt;/h3&gt;
&lt;p&gt;발화 종료를 얼마나 정확히, 얼마나 빠르게 감지하느냐가 전체 latency budget 의 핵심입니다.&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;VAD 방식&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;지연&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;설명&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;에너지 기반&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;단순 볼륨 임계값. 오탐 많음.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Silero VAD&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;경량 ML 모델 (5 MB). 정확도-속도 균형. 가장 많이 쓰임.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;시맨틱 endpointing&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중간&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;STT partial 결과를 LLM 으로 “문장이 끝났는가” 판단. 가장 자연스러움.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;sentence-aggregator&quot;&gt;Sentence Aggregator&lt;/h3&gt;
&lt;p&gt;STT 의 partial transcript 를 LLM 에 넘길 적절한 단위로 묶는 컴포넌트.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;너무 짧게 끊으면&lt;/em&gt;: LLM 이 컨텍스트 없이 처리 → 어색한 응답&lt;/li&gt;
&lt;li&gt;&lt;em&gt;너무 길게 기다리면&lt;/em&gt;: TTS 시작이 늦어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;일반적으로 &lt;strong&gt;문장 완성 (마침표, 쉼표 후 길이 임계)&lt;/strong&gt; 기준으로 aggregation.&lt;/p&gt;
&lt;h2 id=&quot;프로덕션-체크리스트&quot;&gt;프로덕션 체크리스트&lt;/h2&gt;
&lt;p&gt;배포 전 검증 항목:&lt;/p&gt;





































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;항목&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;검증 방법&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;p50 / p95 / p99 latency&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실제 통화 10,000 건 이상 메트릭 수집&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Barge-in&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;사용자가 응답 도중 끊을 때 TTS 즉시 중단 + STT 재개&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;VAD 오탐 / 미탐&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;배경 소음 환경 테스트 (사무실, 카페)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;LLM fallback&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;타임아웃 시 “잠시만 기다려 주세요” 응답&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;TTS 오류 복구&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;TTS API 오류 시 기본 합성 폴백&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;동시 세션 수&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;서버당 최대 동시 통화 수 부하 테스트&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;오디오 코덱&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Opus 16 kHz mono (WebRTC 표준), G.711 (전화망)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;모니터링-메트릭&quot;&gt;모니터링 메트릭&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Mic[&quot;사용자 발화 종료&quot;] --&gt;|VAD delay| STT_start[&quot;STT 시작&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    STT_start --&gt;|STT latency| LLM_start[&quot;LLM 호출&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM_start --&gt;|TTFT| TTS_start[&quot;TTS 첫 청크&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TTS_start --&gt;|TTFB| Speaker[&quot;스피커 출력 시작&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;추적해야 하는 메트릭:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;VAD endpointing delay&lt;/strong&gt;: 실제 발화 종료 ~ STT 시작&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;STT latency&lt;/strong&gt;: 오디오 수신 ~ final transcript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM TTFT&lt;/strong&gt; (Time-to-First-Token): 프롬프트 전송 ~ 첫 토큰 수신&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTS TTFB&lt;/strong&gt; (Time-to-First-Byte): 텍스트 전송 ~ 첫 오디오 청크&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;종단 latency&lt;/strong&gt;: VAD 종료 ~ 스피커 첫 소리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 단계를 OpenTelemetry span 으로 기록하면 병목이 어느 단계인지 즉시 파악됩니다.&lt;/p&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[stt-streaming|STT 스트리밍]]&lt;/li&gt;
&lt;li&gt;[[tts-streaming-ssml|TTS 스트리밍 + SSML]]&lt;/li&gt;
&lt;li&gt;[[speech-to-speech-realtime|Speech-to-Speech Realtime]]&lt;/li&gt;
&lt;li&gt;[[vad-silero|VAD Silero]]&lt;/li&gt;
&lt;li&gt;[[turn-detection-barge-in|Turn Detection / Barge-in]]&lt;/li&gt;
&lt;li&gt;[[latency-percentiles|Latency 퍼센타일]]&lt;/li&gt;
&lt;li&gt;[[pipecat-livekit|Pipecat + LiveKit]]&lt;/li&gt;
&lt;li&gt;[[voice-rag|Voice RAG]] (음성 에이전트 + RAG 결합)&lt;/li&gt;
&lt;li&gt;[[voice-first-prompt|Voice-First 프롬프트 설계]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>voice-agent</category><category>architecture</category><category>latency</category><category>streaming</category><category>cascading</category><category>s2s</category><author>koa (김신건)</author></item><item><title>[Voice AI] 음성 우선 프롬프트 + Function Calling + Structured Output</title><link>https://shinkeonkim.com/wiki/ai/voice-first-prompt/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/ai/voice-first-prompt/</guid><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;음성-우선-프롬프트-설계&quot;&gt;음성 우선 프롬프트 설계&lt;/h2&gt;
&lt;p&gt;음성 답변 = &lt;em&gt;귀로 듣는다&lt;/em&gt;. 텍스트 답변과 &lt;em&gt;완전 다르게&lt;/em&gt; 짜야 한다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Text[&quot;텍스트 답변 (긴 답변 OK)&quot;] --&gt; A1[&quot;**bold**, # 헤딩, 표&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Voice[&quot;음성 답변 (짧고 자연스럽게)&quot;] --&gt; A2[&quot;1-2 문장, 의문문으로 turn 넘김&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    A1 --&gt; Diff&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    A2 --&gt; Diff&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Diff{둘은 완전 다름}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;음성-프롬프트의-핵심-원칙&quot;&gt;음성 프롬프트의 핵심 원칙&lt;/h2&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;원칙&lt;/th&gt;&lt;th&gt;의미&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;짧게&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;한 답변 1-2 문장. 50-80 글자&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;자연스럽게&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;”$5 = ‘오 달러’” (숫자 정규화 사전 정의)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;마크다운 금지&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;**&lt;/code&gt;, &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt; 등 모두 &lt;em&gt;음성에 안 들어감&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;listicle 분해&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;”1, 2, 3…” 대신 &lt;em&gt;대화로 분배&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;turn 넘기기&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;질문으로 끝내거나 “도와드릴까요?”&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;에스컬레이션&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;”사람 상담원 연결해드릴까요?” 명시&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;SYSTEM_PROMPT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;당신은 친절한 한국어 콜센터 상담원입니다.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;응답 규칙:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 한 응답은 *1-2 문장* 으로 짧게&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 자연스러운 구어체 사용 (&quot;입니다&quot; 보다 &quot;이에요&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 숫자는 풀어쓰기 (예: &quot;100만 원&quot; 보다 &quot;백만 원&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 마크다운, 영어 약어, 코드 사용 금지&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 모르는 정보면 &quot;확인이 어렵네요. 사람 상담원 연결해드릴까요?&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 답변 끝에 *질문* 으로 turn 을 사용자에게 넘김&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;페르소나:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 침착하고 공감하는 톤&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 고객을 &quot;고객님&quot; 으로 호칭&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 절대 &quot;AI&quot; 라고 본인을 칭하지 말 것&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;function--tool-calling&quot;&gt;Function / Tool Calling&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sequenceDiagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    autonumber&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    User-&gt;&gt;Agent: &quot;내 주문 상태 확인해줘&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent-&gt;&gt;LLM: prompt + tool definitions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM--&gt;&gt;Agent: function_call: get_order_status(user_id=42)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent-&gt;&gt;API: GET /orders?user=42&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    API--&gt;&gt;Agent: { status: &quot;shipped&quot;, eta: &quot;내일&quot; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent-&gt;&gt;LLM: tool_result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    LLM--&gt;&gt;Agent: &quot;고객님 주문은 배송 중이며, 내일 도착 예정이에요.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    Agent-&gt;&gt;TTS: 음성 합성&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    TTS-&gt;&gt;User: 음성 응답&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;openai-function-calling&quot;&gt;OpenAI Function Calling&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_order_status&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;사용자의 주문 상태를 조회합니다&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;parameters&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;user_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;integer&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;사용자 ID&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;order_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;주문 ID (선택)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user_id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;transfer_to_human&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;사람 상담원에게 연결합니다&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &quot;parameters&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;properties&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;reason&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                    &quot;priority&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;enum&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;low&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;high&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;reason&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.create(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;messages,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tools&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tools,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tool_choice&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;auto&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    stream&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;병렬-function-calling&quot;&gt;병렬 Function Calling&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 같은 응답에서 여러 함수 동시 호출 가능&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  &quot;tool_calls&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;call_1&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_weather&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;arguments&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    { &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;call_2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;get_traffic&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;arguments&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 병렬 실행&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;results &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; asyncio.gather(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    get_weather(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    get_traffic(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;직렬&lt;/em&gt; 보다 &lt;em&gt;수배 빠름&lt;/em&gt;. 독립 호출이면 활용.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;결과를-대화에-자연스럽게&quot;&gt;결과를 대화에 자연스럽게&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@function_tool&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get_order_status&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(user_id: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    order &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db.get_order(user_id)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;status&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: order.status,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;eta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: order.eta,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        # 함수 결과는 *데이터* 만. *음성 문장* 은 LLM 이 합성&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 잘못된 예: 함수가 문장 반환&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@function_tool&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get_order_status_bad&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(user_id: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) -&gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    order &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db.get_order(user_id)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;주문 &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;order.id&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 는 &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;order.status&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 상태이며 ETA &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;order.eta&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 입니다.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    # ← TTS 가 &quot;ETA&quot; 를 영어로 발음하거나 어색&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;structured-output&quot;&gt;Structured Output&lt;/h2&gt;
&lt;p&gt;LLM 응답을 &lt;em&gt;JSON schema 강제&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; IntentExtraction&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;BaseModel&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    intent: Literal[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;order_status&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;refund&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;complaint&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;transfer&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;other&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    user_id: Optional[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    order_id: Optional[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    urgency: Literal[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;low&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;normal&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;high&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.chat.completions.parse(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;gpt-4o-mini&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    messages&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: user_text}],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_format&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;IntentExtraction,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;intent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.choices[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].message.parsed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# intent.intent == &quot;order_status&quot;  ← 타입 안전&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;슬롯-채우기-slot-filling&quot;&gt;슬롯 채우기 (Slot Filling)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 사용자가 부분 정보만 주면 → 부족한 슬롯 묻기&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; BookingRequest&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;BaseModel&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    restaurant: Optional[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    date: Optional[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    party_size: Optional[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    is_complete: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; False&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 첫 발화: &quot;내일 5명 예약하고싶어&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# extracted: { date: &quot;내일&quot;, party_size: 5, restaurant: None, is_complete: false }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# LLM 이 부족한 정보 *질문*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; extracted.restaurant:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    response &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;어느 식당으로 예약 도와드릴까요?&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;페르소나-일관성&quot;&gt;페르소나 일관성&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PERSONA&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;이름: 민지&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;성격: 친절, 차분, 약간 유머&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;역할: 카페 음성 주문 도우미&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;말투: 격식 있는 존댓말 (&quot;이에요&quot;, &quot;괜찮으세요?&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;금지: 비속어, 정치/종교, 의료 조언&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;SYSTEM&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;{PERSONA}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;응답 규칙:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 항상 페르소나 일관성 유지&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;- 메뉴 외 질문은 정중히 거절 + 본업으로 유도&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;흔한-함정&quot;&gt;흔한 함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;시스템 프롬프트가 &lt;em&gt;길고 마크다운&lt;/em&gt;&lt;/strong&gt; = TTS 가 안 읽지만, &lt;em&gt;LLM 의 응답이 마크다운 따라함&lt;/em&gt;. 출력 형식 명시.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;숫자 발음&lt;/strong&gt; = “1500000원” → “일오영영영영영원”. &lt;em&gt;별도 정규화&lt;/em&gt; 또는 SSML.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;function 결과로 &lt;em&gt;긴 텍스트 반환&lt;/em&gt;&lt;/strong&gt; = LLM 이 그대로 &lt;em&gt;읽음&lt;/em&gt;. 데이터만.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tool calling 중 &lt;em&gt;interruption 허용&lt;/em&gt;&lt;/strong&gt; = DB write 중간에 끊김. &lt;code&gt;disallow_interruptions&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[voice-agent-architecture]]&lt;/li&gt;
&lt;li&gt;[[voice-rag]]&lt;/li&gt;
&lt;li&gt;[[agent-patterns]]&lt;/li&gt;
&lt;li&gt;[[turn-detection-barge-in]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>prompt</category><category>function-calling</category><category>structured-output</category><category>voice-llm</category><author>koa (김신건)</author></item></channel></rss>