From e176826ab0ec9bc0af3ce97739daad741093ed47 Mon Sep 17 00:00:00 2001 From: Hank Kim Date: Thu, 15 Jan 2026 11:10:07 +0900 Subject: [PATCH 1/3] Update [03-Agent] 01-LangGraph-Agents tutorial --- 03-Agent/01-LangGraph-Agents.ipynb | 788 ++++++++++++++++++++-------- 03-Agent/assets/langgraph-agent.png | Bin 0 -> 54222 bytes 2 files changed, 574 insertions(+), 214 deletions(-) create mode 100644 03-Agent/assets/langgraph-agent.png diff --git a/03-Agent/01-LangGraph-Agents.ipynb b/03-Agent/01-LangGraph-Agents.ipynb index d1ca9cc..18053aa 100644 --- a/03-Agent/01-LangGraph-Agents.ipynb +++ b/03-Agent/01-LangGraph-Agents.ipynb @@ -3,18 +3,46 @@ { "cell_type": "markdown", "metadata": {}, - "source": "# 에이전트 (Agent)\n\n에이전트는 언어 모델(LLM)과 도구(Tool)를 결합하여 복잡한 작업을 수행하는 시스템입니다. 에이전트는 주어진 작업에 대해 추론하고, 필요한 도구를 선택하며, 목표를 향해 반복적으로 작업을 수행합니다.\n\nLangChain의 `create_agent` 함수는 프로덕션 수준의 에이전트 구현을 제공합니다. 이 함수를 사용하면 모델 선택, 도구 연동, 미들웨어 설정 등을 손쉽게 구성할 수 있습니다.\n\n> 참고 문서: [LangGraph Agents](https://docs.langchain.com/oss/python/langgraph/agents.md)" + "source": [ + "# 에이전트 (Agent)\n", + "\n", + "에이전트는 언어 모델(LLM)과 도구(Tool)를 결합하여 복잡한 작업을 수행하는 시스템입니다. 에이전트는 주어진 작업에 대해 추론하고, 필요한 도구를 선택하며, 목표를 향해 반복적으로 작업을 수행합니다.\n", + "\n", + "![](./assets/langgraph-agent.png)\n", + "\n", + "LangChain의 `create_agent` 함수는 프로덕션 수준의 에이전트 구현을 제공합니다. 이 함수를 사용하면 모델 선택, 도구 연동, 미들웨어 설정 등을 손쉽게 구성할 수 있습니다.\n", + "\n", + "> 참고 문서: [LangChain Agents](https://docs.langchain.com/oss/python/langchain/agents)" + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "## 환경 설정\n\n에이전트 튜토리얼을 시작하기 전에 필요한 환경을 설정합니다. `dotenv`를 사용하여 API 키를 로드하고, `langchain_teddynote`의 로깅 기능을 활성화하여 LangSmith에서 실행 추적을 확인할 수 있도록 합니다.\n\nLangSmith 추적을 활성화하면 에이전트의 추론 과정, 도구 호출, 응답 생성 등을 시각적으로 디버깅할 수 있어 개발에 큰 도움이 됩니다.\n\n아래 코드는 환경 변수를 로드하고 LangSmith 프로젝트를 설정합니다." + "source": [ + "## 환경 설정\n", + "\n", + "에이전트 튜토리얼을 시작하기 전에 필요한 환경을 설정합니다. `dotenv`를 사용하여 API 키를 로드하고, `langchain_teddynote`의 로깅 기능을 활성화하여 LangSmith에서 실행 추적을 확인할 수 있도록 합니다.\n", + "\n", + "LangSmith 추적을 활성화하면 에이전트의 추론 과정, 도구 호출, 응답 생성 등을 시각적으로 디버깅할 수 있어 개발에 큰 도움이 됩니다.\n", + "\n", + "아래 코드는 환경 변수를 로드하고 LangSmith 프로젝트를 설정합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LangSmith 추적을 시작합니다.\n", + "[프로젝트명]\n", + "LangGraph-V1-Tutorial\n" + ] + } + ], "source": [ "from dotenv import load_dotenv\n", "from langchain_teddynote import logging\n", @@ -22,43 +50,83 @@ "# 환경 변수 로드\n", "load_dotenv(override=True)\n", "# 추적을 위한 프로젝트 이름 설정\n", - "logging.langsmith(\"LangChain-V1-Tutorial\")" + "logging.langsmith(\"LangGraph-V1-Tutorial\")" ] }, { "cell_type": "markdown", "metadata": {}, - "source": "## 모델 (Model)\n\n에이전트의 추론 엔진인 LLM은 `create_agent` 함수의 첫 번째 인자로 전달합니다. 가장 간단한 방법은 `provider:model` 형식의 문자열을 사용하는 것입니다. 이 방식은 빠른 프로토타이핑에 적합합니다.\n\n아래 코드는 모델 식별자 문자열을 사용하여 기본 에이전트를 생성합니다." + "source": [ + "## 모델 (Model)\n", + "\n", + "에이전트의 추론 엔진인 LLM은 `create_agent` 함수의 첫 번째 인자로 전달합니다. 모델을 지정하는 방법은 크게 두 가지가 있습니다.\n", + "\n", + "### 방법 1: 문자열 식별자 (provider:model)\n", + "\n", + "가장 간단한 방법은 `provider:model` 형식의 문자열을 직접 `create_agent`에 전달하는 것입니다. 이 방식은 빠른 프로토타이핑에 적합합니다.\n", + "\n", + "### 방법 2: init_chat_model 함수\n", + "\n", + "`init_chat_model` 함수를 사용하면 모델 인스턴스를 먼저 생성한 후 전달할 수 있습니다. 이 방식은 모델 옵션을 세밀하게 제어할 때 유용합니다.\n", + "\n", + "아래 코드는 두 가지 방법을 모두 보여주는 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from langchain.agents import create_agent\n", + "from langchain.chat_models import init_chat_model\n", + "\n", + "# 방법 1: 문자열 식별자를 직접 전달 (빠른 프로토타이핑에 적합)\n", + "# agent = create_agent(\"anthropic:claude-sonnet-4-5\", tools=[])\n", + "\n", + "# 방법 2: init_chat_model로 모델 인스턴스 생성 후 전달\n", + "# OpenAI 키를 사용하는 경우 gpt-4.1-mini, gpt-4.1 등으로 변경하세요\n", + "model = init_chat_model(\"claude-sonnet-4-5\")\n", "\n", - "# 모델 식별자 문자열을 사용한 간단한 방법\n", - "agent = create_agent(\"openai:gpt-4.1-mini\", tools=[])" + "# 모델 인스턴스를 사용하여 에이전트 생성\n", + "agent = create_agent(model, tools=[])" ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### 모델 세부 설정\n\n더 세밀한 제어가 필요한 경우, 모델 클래스를 직접 인스턴스화하여 다양한 옵션을 설정할 수 있습니다. `temperature`는 응답의 무작위성을, `max_tokens`는 생성할 최대 토큰 수를, `timeout`은 요청 타임아웃을 제어합니다.\n\n아래 코드는 ChatOpenAI 클래스를 사용하여 세부 옵션이 설정된 에이전트를 생성합니다." + "source": [ + "### 모델 세부 설정\n", + "\n", + "더 세밀한 제어가 필요한 경우, 모델 생성 시 추가 옵션을 전달하여 다양한 설정을 적용할 수 있습니다.\n", + "\n", + "- `temperature`: 응답의 무작위성을 제어합니다 (0에 가까울수록 일관된 응답, 1에 가까울수록 다양한 응답)\n", + "- `max_tokens`: 생성할 최대 토큰 수를 제한합니다\n", + "- `timeout`: 요청 타임아웃(초)을 설정합니다\n", + "\n", + "모델 세부 설정을 적용하는 방법은 두 가지가 있습니다.\n", + "\n", + "**방법 1: init_chat_model 사용**\n", + "\n", + "`init_chat_model` 함수에 추가 옵션을 전달하는 방식입니다. Provider에 관계없이 동일한 인터페이스로 사용할 수 있어 편리합니다.\n", + "\n", + "**방법 2: Provider별 클래스 직접 사용**\n", + "\n", + "`ChatAnthropic`, `ChatOpenAI` 등 Provider별 클래스를 직접 인스턴스화하는 방식입니다. Provider 고유의 옵션을 세밀하게 제어할 때 유용합니다.\n", + "\n", + "아래 코드는 두 가지 방법을 모두 보여주는 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "from langchain.agents import create_agent\n", - "from langchain_openai import ChatOpenAI\n", - "\n", - "# 모델 인스턴스를 직접 초기화하여 더 세밀한 제어\n", - "model = ChatOpenAI(\n", - " model=\"gpt-4.1-mini\",\n", + "# 방법 1: init_chat_model에 추가 옵션 전달\n", + "# Provider에 관계없이 동일한 인터페이스로 사용 가능\n", + "model = init_chat_model(\n", + " \"claude-sonnet-4-5\", # OpenAI 키를 사용하는 경우 gpt-4.1-mini, gpt-4.1 등으로 변경하세요\n", " temperature=0.1, # 응답의 무작위성 제어\n", " max_tokens=1000, # 최대 생성 토큰 수\n", " timeout=30, # 요청 타임아웃(초)\n", @@ -67,29 +135,64 @@ "agent = create_agent(model, tools=[])" ] }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# 방법 2: Provider별 클래스 직접 사용\n", + "# Provider 고유의 옵션을 세밀하게 제어할 때 유용\n", + "from langchain_anthropic import ChatAnthropic\n", + "# from langchain_openai import ChatOpenAI # OpenAI 사용 시\n", + "\n", + "model = ChatAnthropic(\n", + " model=\"claude-sonnet-4-5\",\n", + " temperature=0.1,\n", + " max_tokens=1000,\n", + " timeout=30,\n", + ")\n", + "\n", + "agent = create_agent(model, tools=[])" + ] + }, { "cell_type": "markdown", "metadata": {}, - "source": "### 동적 모델 선택\n\n동적 모델 선택은 런타임에 현재 상태와 컨텍스트를 기반으로 사용할 모델을 결정하는 패턴입니다. 이를 통해 정교한 라우팅 로직과 비용 최적화가 가능합니다. 예를 들어, 간단한 질문에는 경량 모델을, 복잡한 대화에는 고급 모델을 사용할 수 있습니다.\n\n`wrap_model_call` 데코레이터를 사용하면 모델 호출 전에 요청을 검사하고 수정할 수 있는 미들웨어를 생성할 수 있습니다.\n\n![](assets/wrap_model_call.png)\n\n아래 코드는 대화 길이에 따라 모델을 동적으로 선택하는 예시입니다." + "source": [ + "### 동적 모델 선택\n", + "\n", + "동적 모델 선택은 런타임에 현재 상태와 컨텍스트를 기반으로 사용할 모델을 결정하는 패턴입니다. 이를 통해 정교한 라우팅 로직과 비용 최적화가 가능합니다. 예를 들어, 간단한 질문에는 경량 모델을, 복잡한 대화에는 고급 모델을 사용할 수 있습니다.\n", + "\n", + "`wrap_model_call` 데코레이터를 사용하면 모델 호출 전에 요청을 검사하고 수정할 수 있는 미들웨어를 생성할 수 있습니다.\n", + "\n", + "![](assets/wrap_model_call.png)\n", + "\n", + "아래 코드는 대화 길이에 따라 모델을 동적으로 선택하는 예시입니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### ModelRequest 속성\n\n`ModelRequest`는 에이전트의 모델 호출 정보를 담는 데이터 클래스로, 미들웨어에서 요청을 검사하고 수정할 때 사용됩니다. `override()` 메서드를 통해 여러 속성을 동시에 변경할 수 있습니다.\n\n아래 코드는 ModelRequest를 사용하여 동적으로 모델과 시스템 프롬프트를 변경하는 예시입니다." + "source": [ + "### ModelRequest 속성\n", + "\n", + "`ModelRequest`는 에이전트의 모델 호출 정보를 담는 데이터 클래스로, 미들웨어에서 요청을 검사하고 수정할 때 사용됩니다. `override()` 메서드를 통해 여러 속성을 동시에 변경할 수 있습니다.\n", + "\n", + "아래 코드는 ModelRequest를 사용하여 동적으로 모델과 시스템 프롬프트를 변경하는 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "from langchain_openai import ChatOpenAI\n", - "from langchain.agents import create_agent\n", "from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse\n", "\n", "# 기본 모델과 고급 모델 정의\n", - "basic_model = ChatOpenAI(model=\"gpt-4.1-mini\")\n", - "advanced_model = ChatOpenAI(model=\"gpt-4.1\")\n", + "basic_model = init_chat_model(\"claude-haiku-4-5\")\n", + "advanced_model = init_chat_model(\"claude-sonnet-4-5\")\n", "\n", "\n", "@wrap_model_call\n", @@ -114,9 +217,98 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/var/folders/v7/jvdq74bd213fzs8k9cmpl_7w0000gn/T/ipykernel_46472/4199075104.py:19: DeprecationWarning: Direct attribute assignment to ModelRequest.model is deprecated. Use request.override(model=...) instead to create a new request with the modified attribute.\n", + " request.model = model\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "# 머신러닝의 동작 원리\n", + "\n", + "머신러닝은 **데이터로부터 패턴을 학습하여 예측하는 기술**입니다. 기본적인 동작 방식을 설명하겠습니다.\n", + "\n", + "## 🔄 기본 프로세스\n", + "\n", + "```\n", + "데이터 수집 → 학습 → 모델 생성 → 예측\n", + "```\n", + "\n", + "### 1️⃣ **데이터 학습 단계**\n", + "- 많은 양의 예제 데이터를 모델에 제공\n", + "- 입력값(X)과 정답(Y)의 관계를 찾아냄\n", + "- 예: 수백 장의 고양이 사진으로 \"이건 고양이다\"라고 학습\n", + "\n", + "### 2️⃣ **패턴 인식**\n", + "- 모델이 데이터의 숨겨진 규칙을 발견\n", + "- 가중치(weight)와 편향(bias) 값을 조정하며 최적화\n", + "\n", + "### 3️⃣ **오차 수정**\n", + "```\n", + "예측값과 실제값의 차이(오차) 계산\n", + " ↓\n", + "오차를 줄이는 방향으로 가중치 조정\n", + " ↓\n", + "반복 (더 정확해짐)\n", + "```\n", + "\n", + "### 4️⃣ **예측**\n", + "- 학습이 완료되면 새로운 데이터에 대해 예측\n", + "\n", + "---\n", + "\n", + "## 📊 주요 머신러닝 유형\n", + "\n", + "| 유형 | 설명 | 예시 |\n", + "|------|------|------|\n", + "| **지도학습** | 정답이 있는 데이터로 학습 | 메일 스팸 분류, 주택 가격 예측 |\n", + "| **비지도학습** | 정답이 없는 데이터를 그룹화 | 고객 세분화, 데이터 압축 |\n", + "| **강화학습** | 보상으로부터 학습 | 게임 AI, 로봇 제어 |\n", + "\n", + "---\n", + "\n", + "## 🎯 간단한 예시\n", + "\n", + "**\"온도와 습도로 내일 비 올 확률 예측\"**\n", + "\n", + "```python\n", + "# 과거 데이터\n", + "온도 25°C, 습도 80% → 비 옴 ✓\n", + "온도 30°C, 습도 30% → 안 옴 ✓\n", + "...\n", + "\n", + "# 모델이 학습\n", + "\"습도가 높으면 비가 올 가능성이 높다\"\n", + "\"온도가 낮으면 비가 올 가능성이 높다\"\n", + "\n", + "# 새로운 예측\n", + "내일 온도 22°C, 습도 75% \n", + "→ 모델: \"비 올 확률 85%\"\n", + "```\n", + "\n", + "---\n", + "\n", + "## ⚠️ 중요한 개념\n", + "\n", + "- **과적합(Overfitting)**: 학습 데이터에만 잘 맞고 새 데이터에는 실패\n", + "- **일반화(Generalization)**: 새로운 데이터에도 잘 작동하도록 하는 것이 목표\n", + "\n", + "더 궁금한 부분이 있으신가요?" + ] + } + ], "source": [ "from langchain_teddynote.messages import stream_graph\n", "from langchain_core.messages import HumanMessage\n", @@ -132,11 +324,27 @@ { "cell_type": "markdown", "metadata": {}, - "source": "**ModelRequest 주요 속성:**\n\n| 속성 | 설명 |\n|:---|:---|\n| `model` | 사용할 `BaseChatModel` 인스턴스 |\n| `system_prompt` | 시스템 프롬프트 (선택적) |\n| `messages` | 대화 메시지 리스트 (시스템 프롬프트 제외) |\n| `tool_choice` | 도구 선택 설정 |\n| `tools` | 사용 가능한 도구 리스트 |\n| `response_format` | 응답 형식 지정 |\n| `state` | 현재 에이전트 상태 (`AgentState`) |\n| `runtime` | 에이전트 런타임 정보 |\n| `model_settings` | 추가 모델 설정 (dict) |\n\n아래 코드는 `override()` 메서드를 사용하여 여러 속성을 동시에 변경하는 예시입니다." + "source": [ + "**ModelRequest 주요 속성:**\n", + "\n", + "| 속성 | 설명 |\n", + "|:---|:---|\n", + "| `model` | 사용할 `BaseChatModel` 인스턴스 |\n", + "| `system_prompt` | 시스템 프롬프트 (선택적) |\n", + "| `messages` | 대화 메시지 리스트 (시스템 프롬프트 제외) |\n", + "| `tool_choice` | 도구 선택 설정 |\n", + "| `tools` | 사용 가능한 도구 리스트 |\n", + "| `response_format` | 응답 형식 지정 |\n", + "| `state` | 현재 에이전트 상태 (`AgentState`) |\n", + "| `runtime` | 에이전트 런타임 정보 |\n", + "| `model_settings` | 추가 모델 설정 (dict) |\n", + "\n", + "아래 코드는 `override()` 메서드를 사용하여 여러 속성을 동시에 변경하는 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -157,9 +365,9 @@ " return handler(new_request)\n", " else:\n", " new_request = request.override(\n", + " model=basic_model,\n", " system_prompt=\"한 문장으로 간결하게 답변해줘. emoji 는 사용하지 말아줘.\",\n", " tool_choice=\"auto\",\n", - " model=basic_model,\n", " )\n", " return handler(new_request)\n", "\n", @@ -172,13 +380,50 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### 글자수 기반 모델 선택 테스트\n\n아래는 글자수 10자 미만일 때의 응답입니다. 간결한 답변을 생성하도록 설정되어 있습니다." + "source": [ + "### 글자수 기반 모델 선택 테스트\n", + "\n", + "아래는 글자수 10자 미만일 때의 응답입니다. 간결한 답변을 생성하도록 설정되어 있습니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "글자수: 9\n", + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "# 머신러닝 동작원리\n", + "\n", + "머신러닝은 데이터로부터 패턴을 학습하여 새로운 데이터에 대한 예측이나 분류를 수행하는 기술입니다.\n", + "\n", + "## 기본 동작 과정\n", + "\n", + "1. **데이터 수집 및 전처리** - 학습에 필요한 데이터를 모으고 정제합니다.\n", + "\n", + "2. **모델 선택** - 문제에 적합한 알고리즘(회귀, 분류, 군집화 등)을 선택합니다.\n", + "\n", + "3. **학습(Training)** - 알고리즘이 데이터의 패턴을 찾아 가중치를 조정하며, 오차를 줄이는 방향으로 반복 업데이트합니다.\n", + "\n", + "4. **검증 및 평가** - 학습된 모델의 성능을 테스트 데이터로 평가합니다.\n", + "\n", + "5. **예측(Inference)** - 학습된 모델으로 새로운 데이터에 대한 예측을 수행합니다.\n", + "\n", + "## 핵심 개념\n", + "\n", + "- **손실함수**: 예측값과 실제값의 차이를 계산하여 모델 개선 방향을 제시합니다.\n", + "- **최적화**: 경사하강법 등으로 손실함수를 최소화하는 가중치를 찾습니다.\n", + "- **일반화**: 학습 데이터뿐 아니라 미본 데이터에서도 좋은 성능을 내도록 학습합니다." + ] + } + ], "source": [ "stream_graph(agent, inputs={\"messages\": [HumanMessage(content=\"머신러닝 동작원리\")]})" ] @@ -186,13 +431,71 @@ { "cell_type": "markdown", "metadata": {}, - "source": "아래는 글자수 10자 이상일 때의 응답입니다. 이모지를 사용하여 친근한 답변을 생성하도록 설정되어 있습니다." + "source": [ + "아래는 글자수 10자 이상일 때의 응답입니다. 이모지를 사용하여 친근한 답변을 생성하도록 설정되어 있습니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "글자수: 25\n", + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "# 머신러닝의 동작 원리 🤖\n", + "\n", + "머신러닝을 쉽게 설명해드릴게요! 😊\n", + "\n", + "## 1️⃣ 기본 개념\n", + "머신러닝은 컴퓨터가 **명시적으로 프로그래밍되지 않고도 데이터로부터 학습**하는 기술이에요 📚\n", + "\n", + "## 2️⃣ 핵심 동작 과정\n", + "\n", + "### 🔹 데이터 수집\n", + "```\n", + "예시: 고양이 🐱 사진 1000장, 강아지 🐶 사진 1000장\n", + "```\n", + "\n", + "### 🔹 학습 (Training)\n", + "1. **입력**: 사진 데이터를 모델에 제공\n", + "2. **예측**: 모델이 \"이건 고양이일까? 강아지일까?\" 추측\n", + "3. **오차 계산**: 정답과 비교해서 틀린 정도 측정 📊\n", + "4. **가중치 조정**: 오차를 줄이는 방향으로 내부 파라미터 수정 🔧\n", + "5. **반복**: 2~4 과정을 수천~수만 번 반복 🔄\n", + "\n", + "### 🔹 예측 (Prediction)\n", + "학습된 모델에 새로운 사진을 보여주면 → 정확하게 분류! ✨\n", + "\n", + "## 3️⃣ 핵심 요소\n", + "\n", + "| 요소 | 설명 | 이모지 |\n", + "|------|------|--------|\n", + "| 데이터 | 학습의 재료 | 📊 |\n", + "| 모델 | 학습 알고리즘 | 🧠 |\n", + "| 손실함수 | 오차 측정 도구 | 📏 |\n", + "| 최적화 | 성능 개선 방법 | ⚡ |\n", + "\n", + "## 4️⃣ 비유로 이해하기 🎯\n", + "\n", + "**아기가 말을 배우는 과정과 비슷해요!**\n", + "- 부모가 \"멍멍\" 하며 강아지를 가리킴 👉🐕\n", + "- 아기가 여러 번 보고 듣음 👂👀\n", + "- 점점 강아지를 보면 \"멍멍\"이라고 말함 🗣️\n", + "- 실수하면 교정받고 다시 학습 ✅\n", + "\n", + "이것이 바로 머신러닝의 원리예요! 💡\n", + "\n", + "궁금한 점 있으면 더 물어보세요! 🙋‍♀️" + ] + } + ], "source": [ "stream_graph(\n", " agent,\n", @@ -207,21 +510,36 @@ { "cell_type": "markdown", "metadata": {}, - "source": "---\n\n## 프롬프트\n\n에이전트의 동작을 제어하는 핵심 요소 중 하나는 시스템 프롬프트입니다. 시스템 프롬프트를 통해 에이전트의 역할, 응답 스타일, 제약 조건 등을 정의할 수 있습니다." + "source": [ + "---\n", + "\n", + "## 프롬프트\n", + "\n", + "에이전트의 동작을 제어하는 핵심 요소 중 하나는 시스템 프롬프트입니다. 시스템 프롬프트를 통해 에이전트의 역할, 응답 스타일, 제약 조건 등을 정의할 수 있습니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### 시스템 프롬프트\n\n`system_prompt` 매개변수를 사용하여 에이전트의 기본 동작을 정의할 수 있습니다. 시스템 프롬프트는 모든 대화에서 일관되게 적용되며, 에이전트의 페르소나와 응답 가이드라인을 설정하는 데 사용됩니다.\n\n아래 코드는 간결하고 정확한 응답을 생성하도록 시스템 프롬프트를 설정한 에이전트를 생성합니다." + "source": [ + "### 시스템 프롬프트\n", + "\n", + "`system_prompt` 매개변수를 사용하여 에이전트의 기본 동작을 정의할 수 있습니다. 시스템 프롬프트는 모든 대화에서 일관되게 적용되며, 에이전트의 페르소나와 응답 가이드라인을 설정하는 데 사용됩니다.\n", + "\n", + "아래 코드는 간결하고 정확한 응답을 생성하도록 시스템 프롬프트를 설정한 에이전트를 생성합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ + "# OpenAI 키를 사용하는 경우 gpt-4.1-mini, gpt-4.1 등으로 변경하세요\n", + "model = init_chat_model(\"claude-sonnet-4-5\")\n", + "\n", "agent = create_agent(\n", - " \"openai:gpt-4.1-mini\",\n", + " model,\n", " system_prompt=\"You are a helpful assistant. Be concise and accurate.\",\n", ")" ] @@ -229,13 +547,27 @@ { "cell_type": "markdown", "metadata": {}, - "source": "아래는 설정된 시스템 프롬프트를 사용한 에이전트의 응답 예시입니다." + "source": [ + "아래는 설정된 시스템 프롬프트를 사용한 에이전트의 응답 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "대한민국의 수도는 서울입니다." + ] + } + ], "source": [ "stream_graph(\n", " agent,\n", @@ -246,16 +578,23 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### 동적 시스템 프롬프트 (Dynamic Prompting)\n\n런타임 컨텍스트나 에이전트 상태를 기반으로 시스템 프롬프트를 동적으로 생성해야 하는 경우가 있습니다. `dynamic_prompt` 데코레이터를 사용하면 요청마다 다른 시스템 프롬프트를 적용할 수 있습니다.\n\n이 기능은 사용자 역할, 언어 설정, 응답 형식 등을 런타임에 결정해야 할 때 유용합니다. `context_schema`를 정의하여 에이전트 호출 시 필요한 컨텍스트 정보를 전달할 수 있습니다.\n\n아래 코드는 답변 형식과 길이를 동적으로 설정하는 에이전트를 생성합니다." + "source": [ + "### 동적 시스템 프롬프트 (Dynamic Prompting)\n", + "\n", + "런타임 컨텍스트나 에이전트 상태를 기반으로 시스템 프롬프트를 동적으로 생성해야 하는 경우가 있습니다. `dynamic_prompt` 데코레이터를 사용하면 요청마다 다른 시스템 프롬프트를 적용할 수 있습니다.\n", + "\n", + "이 기능은 사용자 역할, 언어 설정, 응답 형식 등을 런타임에 결정해야 할 때 유용합니다. `context_schema`를 정의하여 에이전트 호출 시 필요한 컨텍스트 정보를 전달할 수 있습니다.\n", + "\n", + "아래 코드는 답변 형식과 길이를 동적으로 설정하는 에이전트를 생성합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "from typing import TypedDict\n", - "from langchain.agents import create_agent\n", "from langchain.agents.middleware import dynamic_prompt, ModelRequest\n", "\n", "\n", @@ -292,7 +631,7 @@ "\n", "# 컨텍스트 스키마와 user_role_prompt 미들웨어를 사용하여 에이전트 생성\n", "agent = create_agent(\n", - " model=\"openai:gpt-4.1-mini\",\n", + " model=model,\n", " middleware=[user_role_prompt],\n", " context_schema=Context,\n", ")" @@ -300,9 +639,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "# 머신러닝, 컴퓨터가 스스로 학습하는 원리 파헤치기\n", + "\n", + "**[IT/기술]** 인공지능 시대의 핵심 기술로 자리잡은 머신러닝의 작동 메커니즘이 주목받고 있다.\n", + "\n", + "머신러닝(Machine Learning)은 컴퓨터가 명시적인 프로그래밍 없이 데이터로부터 패턴을 학습하여 스스로 판단하고 예측하는 인공지능 기술이다. 전통적인 프로그래밍이 규칙을 직접 입력하는 방식이라면, 머신러닝은 데이터에서 규칙을 찾아내는 방식이다.\n", + "\n", + "## 3단계 학습 과정\n", + "\n", + "머신러닝의 동작 원리는 크게 세 단계로 나뉜다. 첫째, **데이터 수집 및 전처리** 단계에서는 학습에 필요한 대량의 데이터를 모으고 정제한다. 둘째, **모델 학습** 단계에서는 알고리즘이 데이터의 패턴을 분석하고 수학적 모델을 구축한다. 셋째, **예측 및 평가** 단계에서는 학습된 모델로 새로운 데이터를 판단하고 정확도를 측정한다.\n", + "\n", + "## 핵심은 최적화\n", + "\n", + "학습 과정의 핵심은 '오차 최소화'다. 모델은 예측값과 실제값의 차이(오차)를 계산하고, 이를 줄이는 방향으로 내부 파라미터를 반복적으로 조정한다. 이 과정을 '경사하강법'이라 부르며, 수천에서 수만 번 반복하면서 최적의 예측 모델을 만들어낸다.\n", + "\n", + "## 세 가지 학습 방식\n", + "\n", + "머신러닝은 학습 방법에 따라 구분된다. **지도학습**은 정답이 있는 데이터로 학습하며, 이메일 스팸 분류나 질병 진단에 활용된다. **비지도학습**은 정답 없이 데이터의 구조를 파악하며, 고객 세분화에 사용된다. **강화학습**은 시행착오를 통해 보상을 최대화하는 방법을 학습하며, 게임 AI나 자율주행에 적용된다.\n", + "\n", + "업계 전문가들은 \"머신러닝은 데이터가 많을수록, 학습 시간이 길수록 성능이 향상되는 특징이 있다\"며 \"양질의 데이터 확보가 성공의 열쇠\"라고 강조했다." + ] + } + ], "source": [ "# 컨텍스트에 따라 시스템 프롬프트가 동적으로 설정됩니다\n", "stream_graph(\n", @@ -316,9 +685,27 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "🤖 머신러닝은 데이터로 학습해요!\n", + "\n", + "📊 데이터 → 패턴 발견 → 예측 모델 생성\n", + "\n", + "반복 학습으로 정확도 향상! 🎯\n", + "\n", + "#AI #머신러닝" + ] + } + ], "source": [ "stream_graph(\n", " agent,\n", @@ -332,158 +719,24 @@ { "cell_type": "markdown", "metadata": {}, - "source": "---\n\n## 구조화된 답변 출력 (Response Format)\n\n특정 형식으로 에이전트의 출력을 반환하고 싶을 때가 있습니다. LangChain은 `response_format` 매개변수를 통해 구조화된 출력 전략을 제공합니다. 이를 통해 자연어 응답 대신 JSON 객체, Pydantic 모델 등의 형태로 구조화된 데이터를 얻을 수 있습니다.\n\n**지원 타입:**\n- **Pydantic model class**: Pydantic 모델 클래스\n- **`ToolStrategy`**: 도구 기반 구조화 전략 (대부분의 모델에서 작동)\n- **`ProviderStrategy`**: Provider 기반 구조화 전략 (OpenAI 등 지원 모델에서만 작동)\n\n구조화된 응답은 `response_format` 설정에 따라 에이전트 상태의 `structured_response` 키에 반환됩니다." - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": "### Pydantic 모델 기반 처리\n\nPydantic 모델을 사용하면 스키마 검증이 자동으로 이루어지며, 필드 설명을 통해 모델이 각 필드의 의미를 이해할 수 있습니다. `Field`의 `description` 매개변수는 모델이 올바른 값을 추출하는 데 도움이 됩니다.\n\n아래 코드는 연락처 정보를 추출하는 Pydantic 모델을 정의합니다." - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pydantic import BaseModel, Field\n", - "\n", - "\n", - "class ContactInfo(BaseModel):\n", - " \"\"\"Response schema for the agent.\"\"\"\n", - "\n", - " name: str = Field(description=\"The name of the person\")\n", - " email: str = Field(description=\"The email of the person\")\n", - " phone: str = Field(description=\"The phone number of the person\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "agent = create_agent(model=\"openai:gpt-4.1-mini\", tools=[], response_format=ContactInfo)\n", - "\n", - "result = agent.invoke(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Extract contact info from: 테디는 AI 엔지니어 입니다. 그의 이메일은 teddy@example.com 이고, 전화번호는 010-1234-5678 입니다.\",\n", - " }\n", - " ]\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": "아래에서 정형화된 출력 결과를 확인할 수 있습니다. `structured_response` 키에 Pydantic 모델 인스턴스가 반환됩니다." - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result[\"structured_response\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": "### ToolStrategy\n\n`ToolStrategy`는 도구 호출(Tool Calling)을 사용하여 구조화된 출력을 생성합니다. 이 방식은 도구 호출을 지원하는 대부분의 모델에서 작동하므로 호환성이 높습니다.\n\n아래 코드는 ToolStrategy를 사용하여 연락처 정보를 추출하는 예시입니다." - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ - "from pydantic import BaseModel\n", - "from langchain.agents import create_agent\n", - "from langchain.agents.structured_output import ToolStrategy\n", - "\n", - "\n", - "# 응답 스키마 정의\n", - "class ContactInfo(BaseModel):\n", - " name: str\n", - " email: str\n", - " phone: str\n", + "---\n", "\n", + "## 미들웨어\n", "\n", - "agent = create_agent(\n", - " model=\"openai:gpt-4.1-mini\", tools=[], response_format=ToolStrategy(ContactInfo)\n", - ")\n", + "미들웨어를 사용하면 모델 호출 전후에 커스텀 로직을 실행할 수 있습니다. `@before_model` 및 `@after_model` 데코레이터를 사용하여 모델 호출을 감싸는 훅을 정의할 수 있습니다.\n", "\n", - "result = agent.invoke(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Extract contact info from: 테디는 AI 엔지니어 입니다. 그의 이메일은 teddy@example.com 이고, 전화번호는 010-1234-5678 입니다.\",\n", - " }\n", - " ]\n", - " }\n", - ")\n", + "**미들웨어 활용 사례:**\n", + "- 모델 호출 전 메시지 전처리 (예: 쿼리 재작성)\n", + "- 모델 호출 후 응답 후처리 (예: 필터링, 로깅)\n", + "- 상태 기반 동적 라우팅\n", "\n", - "result[\"structured_response\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": "### ProviderStrategy\n\n`ProviderStrategy`는 모델 제공자의 네이티브 구조화된 출력 기능을 사용합니다. OpenAI와 같이 네이티브 구조화된 출력을 지원하는 제공자에서만 작동하지만, 더 안정적인 결과를 제공합니다.\n\n아래 코드는 ProviderStrategy를 사용하는 예시입니다." - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.agents.structured_output import ProviderStrategy\n", - "\n", - "agent = create_agent(\n", - " model=\"openai:gpt-4.1\", response_format=ProviderStrategy(ContactInfo)\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result = agent.invoke(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Extract contact info from: 테디는 AI 엔지니어 입니다. 그의 이메일은 teddy@example.com 이고, 전화번호는 010-1234-5678 입니다.\",\n", - " }\n", - " ]\n", - " }\n", - ")" + "아래 코드는 모델 호출 전후에 로깅을 수행하는 미들웨어 예시입니다." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "result[\"structured_response\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": "---\n\n## 미들웨어\n\n미들웨어를 사용하면 모델 호출 전후에 커스텀 로직을 실행할 수 있습니다. `@before_model` 및 `@after_model` 데코레이터를 사용하여 모델 호출을 감싸는 훅을 정의할 수 있습니다.\n\n**미들웨어 활용 사례:**\n- 모델 호출 전 메시지 전처리 (예: 쿼리 재작성)\n- 모델 호출 후 응답 후처리 (예: 필터링, 로깅)\n- 상태 기반 동적 라우팅\n\n아래 코드는 모델 호출 전후에 로깅을 수행하는 미들웨어 예시입니다." - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -495,11 +748,7 @@ " AgentState,\n", " ModelRequest,\n", " ModelResponse,\n", - " dynamic_prompt,\n", ")\n", - "from langchain.chat_models import init_chat_model\n", - "from langchain.messages import AIMessage, AnyMessage\n", - "from langchain_teddynote.messages import invoke_graph\n", "from langchain_core.prompts import PromptTemplate\n", "from langgraph.runtime import Runtime\n", "from typing import Any, Callable\n", @@ -512,7 +761,8 @@ " f\"\\033[95m\\n\\n모델 호출 전 메시지 {len(state['messages'])}개가 있습니다\\033[0m\"\n", " )\n", " last_message = state[\"messages\"][-1].content\n", - " llm = init_chat_model(\"openai:gpt-4.1-mini\")\n", + " # OpenAI 키를 사용하는 경우 gpt-4.1-mini, gpt-4.1 등으로 변경하세요\n", + " llm = init_chat_model(\"claude-sonnet-4-5\")\n", "\n", " query_rewrite = (\n", " PromptTemplate.from_template(\n", @@ -538,12 +788,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "agent = create_agent(\n", - " \"openai:gpt-4.1-mini\",\n", + " model,\n", " middleware=[\n", " log_before_model,\n", " log_after_model,\n", @@ -553,9 +803,53 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[95m\n", + "\n", + "모델 호출 전 메시지 1개가 있습니다\u001b[0m\n", + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mlog_before_model.before_model\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "What is the capital city of South Korea?\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "# Capital of South Korea\n", + "\n", + "The capital city of South Korea is **Seoul** (서울).\n", + "\n", + "## Key Facts about Seoul:\n", + "- **Population**: Approximately 9.7 million in the city proper, with over 25 million in the greater metropolitan area\n", + "- **Location**: Northwestern South Korea, along the Han River\n", + "- **Status**: Largest city in South Korea and the political, economic, and cultural center\n", + "- **History**: Has served as Korea's capital for over 600 years, since the Joseon Dynasty (1394)\n", + "\n", + "Seoul is a major global city known for its modern technology, K-pop culture, historical palaces, and vibrant urban life.\u001b[95m\n", + "\n", + "모델 호출 후 메시지 3개가 있습니다\u001b[0m\n", + "[0] 대한민국 수도\n", + "[1] What is the capital city of South Korea?\n", + "[2] # Capital of South Korea\n", + "\n", + "The capital city of South Korea is **Seoul** (서울).\n", + "\n", + "## Key Facts about Seoul:\n", + "- **Population**: Approximately 9.7 million in the city proper, with over 25 million in the greater metropolitan area\n", + "- **Location**: Northwestern South Korea, along the Han River\n", + "- **Status**: Largest city in South Korea and the political, economic, and cultural center\n", + "- **History**: Has served as Korea's capital for over 600 years, since the Joseon Dynasty (1394)\n", + "\n", + "Seoul is a major global city known for its modern technology, K-pop culture, historical palaces, and vibrant urban life.\n" + ] + } + ], "source": [ "stream_graph(\n", " agent,\n", @@ -566,11 +860,19 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### 클래스 기반 미들웨어\n\n데코레이터 대신 클래스 기반 미들웨어를 사용할 수 있습니다. `AgentMiddleware` 클래스를 상속하고 `before_model` 및 `after_model` 메서드를 오버라이드하여 커스텀 로직을 구현합니다.\n\n클래스 기반 미들웨어는 커스텀 상태 스키마를 정의하거나 복잡한 미들웨어 로직을 구조화할 때 유용합니다.\n\n아래 코드는 클래스 기반 미들웨어를 사용하여 커스텀 상태를 관리하는 예시입니다." + "source": [ + "### 클래스 기반 미들웨어\n", + "\n", + "데코레이터 대신 클래스 기반 미들웨어를 사용할 수 있습니다. `AgentMiddleware` 클래스를 상속하고 `before_model` 및 `after_model` 메서드를 오버라이드하여 커스텀 로직을 구현합니다.\n", + "\n", + "클래스 기반 미들웨어는 커스텀 상태 스키마를 정의하거나 복잡한 미들웨어 로직을 구조화할 때 유용합니다.\n", + "\n", + "아래 코드는 클래스 기반 미들웨어를 사용하여 커스텀 상태를 관리하는 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -593,7 +895,7 @@ " pass\n", "\n", "\n", - "agent = create_agent(\"openai:gpt-4.1-mini\", tools=[], middleware=[CustomMiddleware()])\n", + "agent = create_agent(model, tools=[], middleware=[CustomMiddleware()])\n", "\n", "# 에이전트는 이제 메시지 외에 추가 상태를 추적할 수 있습니다\n", "result = agent.invoke(\n", @@ -607,11 +909,17 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### 모델 오류 시 재시도 로직\n\n`wrap_model_call` 데코레이터를 사용하면 모델 호출 실패 시 자동으로 재시도하는 로직을 구현할 수 있습니다. 이는 네트워크 오류나 일시적인 API 장애에 대응하는 데 유용합니다.\n\n아래 코드는 최대 3회까지 재시도하는 미들웨어 예시입니다." + "source": [ + "### 모델 오류 시 재시도 로직\n", + "\n", + "`wrap_model_call` 데코레이터를 사용하면 모델 호출 실패 시 자동으로 재시도하는 로직을 구현할 수 있습니다. 이는 네트워크 오류나 일시적인 API 장애에 대응하는 데 유용합니다.\n", + "\n", + "아래 코드는 최대 3회까지 재시도하는 미들웨어 예시입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -631,21 +939,73 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ + "# OpenAI 키를 사용하는 경우 gpt-4.1-mini, gpt-4.1 등으로 변경하세요\n", + "# 일부러 존재하지 않는 모델명을 사용하여 재시도 로직을 테스트합니다\n", + "model = init_chat_model(\"claude-sonnet-4-5-invalid\")\n", + "\n", "agent = create_agent(\n", - " \"openai:gpt-4.1-minis\", # 일부러 모델 호출 실패하도록 설정(모델명 오류)\n", + " model,\n", " middleware=[retry_model],\n", ")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "오류 발생으로 1/3 번째 재시도합니다: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-sonnet-4-5-invalid'}, 'request_id': 'req_011CX8LweDEK9NgLt9dhexUc'}\n", + "오류 발생으로 2/3 번째 재시도합니다: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-sonnet-4-5-invalid'}, 'request_id': 'req_011CX8LwfW7bVThHqr49DugM'}\n" + ] + }, + { + "ename": "NotFoundError", + "evalue": "Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-sonnet-4-5-invalid'}, 'request_id': 'req_011CX8LwhFYHFhGVh4wmrHXi'}", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNotFoundError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[21]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mstream_graph\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 2\u001b[39m \u001b[43m \u001b[49m\u001b[43magent\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3\u001b[39m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m=\u001b[49m\u001b[43m{\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmessages\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mHumanMessage\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcontent\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m대한민국의 수도는?\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 4\u001b[39m \u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_teddynote/messages.py:369\u001b[39m, in \u001b[36mstream_graph\u001b[39m\u001b[34m(graph, inputs, config, context, node_names, callback)\u001b[39m\n\u001b[32m 366\u001b[39m prev_node = \u001b[33m\"\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 368\u001b[39m \u001b[38;5;66;03m# LangGraph v1.0에서 stream_mode=\"messages\"는 2-튜플 (message, metadata)를 반환\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m369\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mchunk_msg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mgraph\u001b[49m\u001b[43m.\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 370\u001b[39m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcontext\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcontext\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_mode\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmessages\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\n\u001b[32m 371\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 372\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# metadata에서 노드 정보 추출\u001b[39;49;00m\n\u001b[32m 373\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# v1.0에서는 'langgraph_node' 키를 통해 노드 이름에 접근\u001b[39;49;00m\n\u001b[32m 374\u001b[39m \u001b[43m \u001b[49m\u001b[43mcurr_node\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mlanggraph_node\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 376\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# node_names가 비어있거나 현재 노드가 node_names에 있는 경우에만 처리\u001b[39;49;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/pregel/main.py:2646\u001b[39m, in \u001b[36mPregel.stream\u001b[39m\u001b[34m(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, subgraphs, debug, **kwargs)\u001b[39m\n\u001b[32m 2644\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m task \u001b[38;5;129;01min\u001b[39;00m loop.match_cached_writes():\n\u001b[32m 2645\u001b[39m loop.output_writes(task.id, task.writes, cached=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m-> \u001b[39m\u001b[32m2646\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrunner\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtick\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 2647\u001b[39m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mt\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mt\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mloop\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtasks\u001b[49m\u001b[43m.\u001b[49m\u001b[43mvalues\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mt\u001b[49m\u001b[43m.\u001b[49m\u001b[43mwrites\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2648\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstep_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2649\u001b[39m \u001b[43m \u001b[49m\u001b[43mget_waiter\u001b[49m\u001b[43m=\u001b[49m\u001b[43mget_waiter\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2650\u001b[39m \u001b[43m \u001b[49m\u001b[43mschedule_task\u001b[49m\u001b[43m=\u001b[49m\u001b[43mloop\u001b[49m\u001b[43m.\u001b[49m\u001b[43maccept_push\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2651\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 2652\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# emit output\u001b[39;49;00m\n\u001b[32m 2653\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield from\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_output\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 2654\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_mode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprint_mode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msubgraphs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mqueue\u001b[49m\u001b[43m.\u001b[49m\u001b[43mEmpty\u001b[49m\n\u001b[32m 2655\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 2656\u001b[39m loop.after_tick()\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/pregel/_runner.py:258\u001b[39m, in \u001b[36mPregelRunner.tick\u001b[39m\u001b[34m(self, tasks, reraise, timeout, retry_policy, get_waiter, schedule_task)\u001b[39m\n\u001b[32m 256\u001b[39m \u001b[38;5;66;03m# panic on failure or timeout\u001b[39;00m\n\u001b[32m 257\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m258\u001b[39m \u001b[43m_panic_or_proceed\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 259\u001b[39m \u001b[43m \u001b[49m\u001b[43mfutures\u001b[49m\u001b[43m.\u001b[49m\u001b[43mdone\u001b[49m\u001b[43m.\u001b[49m\u001b[43munion\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mt\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mfutures\u001b[49m\u001b[43m.\u001b[49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mt\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 260\u001b[39m \u001b[43m \u001b[49m\u001b[43mpanic\u001b[49m\u001b[43m=\u001b[49m\u001b[43mreraise\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 261\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 262\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 263\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m tb := exc.__traceback__:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/pregel/_runner.py:520\u001b[39m, in \u001b[36m_panic_or_proceed\u001b[39m\u001b[34m(futs, timeout_exc_cls, panic)\u001b[39m\n\u001b[32m 518\u001b[39m interrupts.append(exc)\n\u001b[32m 519\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m fut \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m SKIP_RERAISE_SET:\n\u001b[32m--> \u001b[39m\u001b[32m520\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[32m 521\u001b[39m \u001b[38;5;66;03m# raise combined interrupts\u001b[39;00m\n\u001b[32m 522\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m interrupts:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/pregel/_executor.py:80\u001b[39m, in \u001b[36mBackgroundExecutor.done\u001b[39m\u001b[34m(self, task)\u001b[39m\n\u001b[32m 78\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Remove the task from the tasks dict when it's done.\"\"\"\u001b[39;00m\n\u001b[32m 79\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m80\u001b[39m \u001b[43mtask\u001b[49m\u001b[43m.\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 81\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m GraphBubbleUp:\n\u001b[32m 82\u001b[39m \u001b[38;5;66;03m# This exception is an interruption signal, not an error\u001b[39;00m\n\u001b[32m 83\u001b[39m \u001b[38;5;66;03m# so we don't want to re-raise it on exit\u001b[39;00m\n\u001b[32m 84\u001b[39m \u001b[38;5;28mself\u001b[39m.tasks.pop(task)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.pyenv/versions/3.11.14/lib/python3.11/concurrent/futures/_base.py:449\u001b[39m, in \u001b[36mFuture.result\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 447\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n\u001b[32m 448\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state == FINISHED:\n\u001b[32m--> \u001b[39m\u001b[32m449\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m__get_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 451\u001b[39m \u001b[38;5;28mself\u001b[39m._condition.wait(timeout)\n\u001b[32m 453\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state \u001b[38;5;129;01min\u001b[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.pyenv/versions/3.11.14/lib/python3.11/concurrent/futures/_base.py:401\u001b[39m, in \u001b[36mFuture.__get_result\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 399\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exception:\n\u001b[32m 400\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m401\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exception\n\u001b[32m 402\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 403\u001b[39m \u001b[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001b[39;00m\n\u001b[32m 404\u001b[39m \u001b[38;5;28mself\u001b[39m = \u001b[38;5;28;01mNone\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.pyenv/versions/3.11.14/lib/python3.11/concurrent/futures/thread.py:58\u001b[39m, in \u001b[36m_WorkItem.run\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 55\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m 57\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m58\u001b[39m result = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 59\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 60\u001b[39m \u001b[38;5;28mself\u001b[39m.future.set_exception(exc)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/pregel/_retry.py:42\u001b[39m, in \u001b[36mrun_with_retry\u001b[39m\u001b[34m(task, retry_policy, configurable)\u001b[39m\n\u001b[32m 40\u001b[39m task.writes.clear()\n\u001b[32m 41\u001b[39m \u001b[38;5;66;03m# run the task\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m42\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtask\u001b[49m\u001b[43m.\u001b[49m\u001b[43mproc\u001b[49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtask\u001b[49m\u001b[43m.\u001b[49m\u001b[43minput\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 43\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m ParentCommand \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 44\u001b[39m ns: \u001b[38;5;28mstr\u001b[39m = config[CONF][CONFIG_KEY_CHECKPOINT_NS]\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/_internal/_runnable.py:656\u001b[39m, in \u001b[36mRunnableSeq.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 654\u001b[39m \u001b[38;5;66;03m# run in context\u001b[39;00m\n\u001b[32m 655\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m set_config_context(config, run) \u001b[38;5;28;01mas\u001b[39;00m context:\n\u001b[32m--> \u001b[39m\u001b[32m656\u001b[39m \u001b[38;5;28minput\u001b[39m = \u001b[43mcontext\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstep\u001b[49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 657\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 658\u001b[39m \u001b[38;5;28minput\u001b[39m = step.invoke(\u001b[38;5;28minput\u001b[39m, config)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langgraph/_internal/_runnable.py:400\u001b[39m, in \u001b[36mRunnableCallable.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 398\u001b[39m run_manager.on_chain_end(ret)\n\u001b[32m 399\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m400\u001b[39m ret = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 401\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.recurse \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ret, Runnable):\n\u001b[32m 402\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m ret.invoke(\u001b[38;5;28minput\u001b[39m, config)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain/agents/factory.py:1133\u001b[39m, in \u001b[36mcreate_agent..model_node\u001b[39m\u001b[34m(state, runtime)\u001b[39m\n\u001b[32m 1130\u001b[39m response = _execute_model_sync(request)\n\u001b[32m 1131\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1132\u001b[39m \u001b[38;5;66;03m# Call composed handler with base handler\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1133\u001b[39m response = \u001b[43mwrap_model_call_handler\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_execute_model_sync\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1135\u001b[39m \u001b[38;5;66;03m# Extract state updates from ModelResponse\u001b[39;00m\n\u001b[32m 1136\u001b[39m state_updates = {\u001b[33m\"\u001b[39m\u001b[33mmessages\u001b[39m\u001b[33m\"\u001b[39m: response.result}\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain/agents/factory.py:146\u001b[39m, in \u001b[36m_chain_model_call_handlers..normalized_single\u001b[39m\u001b[34m(request, handler)\u001b[39m\n\u001b[32m 142\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mnormalized_single\u001b[39m(\n\u001b[32m 143\u001b[39m request: ModelRequest,\n\u001b[32m 144\u001b[39m handler: Callable[[ModelRequest], ModelResponse],\n\u001b[32m 145\u001b[39m ) -> ModelResponse:\n\u001b[32m--> \u001b[39m\u001b[32m146\u001b[39m result = \u001b[43msingle_handler\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mhandler\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m _normalize_to_model_response(result)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain/agents/middleware/types.py:1767\u001b[39m, in \u001b[36mwrap_model_call..decorator..wrapped\u001b[39m\u001b[34m(_self, request, handler)\u001b[39m\n\u001b[32m 1762\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mwrapped\u001b[39m(\n\u001b[32m 1763\u001b[39m _self: AgentMiddleware[StateT, ContextT],\n\u001b[32m 1764\u001b[39m request: ModelRequest,\n\u001b[32m 1765\u001b[39m handler: Callable[[ModelRequest], ModelResponse],\n\u001b[32m 1766\u001b[39m ) -> ModelCallResult:\n\u001b[32m-> \u001b[39m\u001b[32m1767\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mhandler\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[19]\u001b[39m\u001b[32m, line 8\u001b[39m, in \u001b[36mretry_model\u001b[39m\u001b[34m(request, handler)\u001b[39m\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m attempt \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[32m3\u001b[39m):\n\u001b[32m 7\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mhandler\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 9\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m attempt == \u001b[32m2\u001b[39m:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain/agents/factory.py:1101\u001b[39m, in \u001b[36mcreate_agent.._execute_model_sync\u001b[39m\u001b[34m(request)\u001b[39m\n\u001b[32m 1098\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m request.system_message:\n\u001b[32m 1099\u001b[39m messages = [request.system_message, *messages]\n\u001b[32m-> \u001b[39m\u001b[32m1101\u001b[39m output = \u001b[43mmodel_\u001b[49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1102\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m name:\n\u001b[32m 1103\u001b[39m output.name = name\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:5557\u001b[39m, in \u001b[36mRunnableBindingBase.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 5550\u001b[39m \u001b[38;5;129m@override\u001b[39m\n\u001b[32m 5551\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minvoke\u001b[39m(\n\u001b[32m 5552\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 5555\u001b[39m **kwargs: Any | \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 5556\u001b[39m ) -> Output:\n\u001b[32m-> \u001b[39m\u001b[32m5557\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mbound\u001b[49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 5558\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 5559\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_merge_configs\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 5560\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43m{\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 5561\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:402\u001b[39m, in \u001b[36mBaseChatModel.invoke\u001b[39m\u001b[34m(self, input, config, stop, **kwargs)\u001b[39m\n\u001b[32m 388\u001b[39m \u001b[38;5;129m@override\u001b[39m\n\u001b[32m 389\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minvoke\u001b[39m(\n\u001b[32m 390\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 395\u001b[39m **kwargs: Any,\n\u001b[32m 396\u001b[39m ) -> AIMessage:\n\u001b[32m 397\u001b[39m config = ensure_config(config)\n\u001b[32m 398\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(\n\u001b[32m 399\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mAIMessage\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 400\u001b[39m cast(\n\u001b[32m 401\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mChatGeneration\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m--> \u001b[39m\u001b[32m402\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mgenerate_prompt\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 403\u001b[39m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_convert_input\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 404\u001b[39m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 405\u001b[39m \u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcallbacks\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 406\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtags\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 407\u001b[39m \u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmetadata\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 408\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mrun_name\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 409\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mrun_id\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 410\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 411\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m.generations[\u001b[32m0\u001b[39m][\u001b[32m0\u001b[39m],\n\u001b[32m 412\u001b[39m ).message,\n\u001b[32m 413\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:1121\u001b[39m, in \u001b[36mBaseChatModel.generate_prompt\u001b[39m\u001b[34m(self, prompts, stop, callbacks, **kwargs)\u001b[39m\n\u001b[32m 1112\u001b[39m \u001b[38;5;129m@override\u001b[39m\n\u001b[32m 1113\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mgenerate_prompt\u001b[39m(\n\u001b[32m 1114\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 1118\u001b[39m **kwargs: Any,\n\u001b[32m 1119\u001b[39m ) -> LLMResult:\n\u001b[32m 1120\u001b[39m prompt_messages = [p.to_messages() \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m prompts]\n\u001b[32m-> \u001b[39m\u001b[32m1121\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprompt_messages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:931\u001b[39m, in \u001b[36mBaseChatModel.generate\u001b[39m\u001b[34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001b[39m\n\u001b[32m 928\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i, m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(input_messages):\n\u001b[32m 929\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 930\u001b[39m results.append(\n\u001b[32m--> \u001b[39m\u001b[32m931\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_generate_with_cache\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 932\u001b[39m \u001b[43m \u001b[49m\u001b[43mm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 933\u001b[39m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 934\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 935\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 936\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 937\u001b[39m )\n\u001b[32m 938\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 939\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:1190\u001b[39m, in \u001b[36mBaseChatModel._generate_with_cache\u001b[39m\u001b[34m(self, messages, stop, run_manager, **kwargs)\u001b[39m\n\u001b[32m 1188\u001b[39m index = -\u001b[32m1\u001b[39m\n\u001b[32m 1189\u001b[39m index_type = \u001b[33m\"\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m1190\u001b[39m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mchunk\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_stream\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 1191\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunk\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmessage\u001b[49m\u001b[43m.\u001b[49m\u001b[43mresponse_metadata\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43m_gen_info_and_msg_metadata\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchunk\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1192\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43moutput_version\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mv1\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\n\u001b[32m 1193\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Overwrite .content with .content_blocks\u001b[39;49;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_anthropic/chat_models.py:1271\u001b[39m, in \u001b[36mChatAnthropic._stream\u001b[39m\u001b[34m(self, messages, stop, run_manager, stream_usage, **kwargs)\u001b[39m\n\u001b[32m 1269\u001b[39m payload = \u001b[38;5;28mself\u001b[39m._get_request_payload(messages, stop=stop, **kwargs)\n\u001b[32m 1270\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1271\u001b[39m stream = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_create\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpayload\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1272\u001b[39m coerce_content_to_string = (\n\u001b[32m 1273\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m _tools_in_params(payload)\n\u001b[32m 1274\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m _documents_in_params(payload)\n\u001b[32m 1275\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m _thinking_in_params(payload)\n\u001b[32m 1276\u001b[39m )\n\u001b[32m 1277\u001b[39m block_start_event = \u001b[38;5;28;01mNone\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/langchain_anthropic/chat_models.py:1250\u001b[39m, in \u001b[36mChatAnthropic._create\u001b[39m\u001b[34m(self, payload)\u001b[39m\n\u001b[32m 1248\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mbetas\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m payload:\n\u001b[32m 1249\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._client.beta.messages.create(**payload)\n\u001b[32m-> \u001b[39m\u001b[32m1250\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mpayload\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/anthropic/_utils/_utils.py:282\u001b[39m, in \u001b[36mrequired_args..inner..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 280\u001b[39m msg = \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mMissing required argument: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mquote(missing[\u001b[32m0\u001b[39m])\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 281\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg)\n\u001b[32m--> \u001b[39m\u001b[32m282\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/anthropic/resources/messages/messages.py:932\u001b[39m, in \u001b[36mMessages.create\u001b[39m\u001b[34m(self, max_tokens, messages, model, metadata, service_tier, stop_sequences, stream, system, temperature, thinking, tool_choice, tools, top_k, top_p, extra_headers, extra_query, extra_body, timeout)\u001b[39m\n\u001b[32m 925\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m model \u001b[38;5;129;01min\u001b[39;00m DEPRECATED_MODELS:\n\u001b[32m 926\u001b[39m warnings.warn(\n\u001b[32m 927\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mThe model \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmodel\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m is deprecated and will reach end-of-life on \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mDEPRECATED_MODELS[model]\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33mPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 928\u001b[39m \u001b[38;5;167;01mDeprecationWarning\u001b[39;00m,\n\u001b[32m 929\u001b[39m stacklevel=\u001b[32m3\u001b[39m,\n\u001b[32m 930\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m932\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_post\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 933\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m/v1/messages\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 934\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmaybe_transform\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 935\u001b[39m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[32m 936\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmax_tokens\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_tokens\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 937\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmessages\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 938\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmodel\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 939\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmetadata\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 940\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mservice_tier\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mservice_tier\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 941\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstop_sequences\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop_sequences\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 942\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mstream\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 943\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43msystem\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43msystem\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 944\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtemperature\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtemperature\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 945\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mthinking\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mthinking\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 946\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtool_choice\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtool_choice\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 947\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtools\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtools\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 948\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_k\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_k\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 949\u001b[39m \u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtop_p\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_p\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 950\u001b[39m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 951\u001b[39m \u001b[43m \u001b[49m\u001b[43mmessage_create_params\u001b[49m\u001b[43m.\u001b[49m\u001b[43mMessageCreateParamsStreaming\u001b[49m\n\u001b[32m 952\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\n\u001b[32m 953\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mmessage_create_params\u001b[49m\u001b[43m.\u001b[49m\u001b[43mMessageCreateParamsNonStreaming\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 954\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 955\u001b[39m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmake_request_options\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 956\u001b[39m \u001b[43m \u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_query\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextra_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\n\u001b[32m 957\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 958\u001b[39m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m=\u001b[49m\u001b[43mMessage\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 959\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 960\u001b[39m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mStream\u001b[49m\u001b[43m[\u001b[49m\u001b[43mRawMessageStreamEvent\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 961\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/anthropic/_base_client.py:1361\u001b[39m, in \u001b[36mSyncAPIClient.post\u001b[39m\u001b[34m(self, path, cast_to, body, content, options, files, stream, stream_cls)\u001b[39m\n\u001b[32m 1352\u001b[39m warnings.warn(\n\u001b[32m 1353\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mPassing raw bytes as `body` is deprecated and will be removed in a future version. \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 1354\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mPlease pass raw bytes via the `content` parameter instead.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 1355\u001b[39m \u001b[38;5;167;01mDeprecationWarning\u001b[39;00m,\n\u001b[32m 1356\u001b[39m stacklevel=\u001b[32m2\u001b[39m,\n\u001b[32m 1357\u001b[39m )\n\u001b[32m 1358\u001b[39m opts = FinalRequestOptions.construct(\n\u001b[32m 1359\u001b[39m method=\u001b[33m\"\u001b[39m\u001b[33mpost\u001b[39m\u001b[33m\"\u001b[39m, url=path, json_data=body, content=content, files=to_httpx_files(files), **options\n\u001b[32m 1360\u001b[39m )\n\u001b[32m-> \u001b[39m\u001b[32m1361\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(ResponseT, \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[43m)\u001b[49m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/braincrew/langgraph-v1-tutorial/.venv/lib/python3.11/site-packages/anthropic/_base_client.py:1134\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, stream, stream_cls)\u001b[39m\n\u001b[32m 1131\u001b[39m err.response.read()\n\u001b[32m 1133\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRe-raising status error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1134\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._make_status_error_from_response(err.response) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 1136\u001b[39m \u001b[38;5;28;01mbreak\u001b[39;00m\n\u001b[32m 1138\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m response \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[33m\"\u001b[39m\u001b[33mcould not resolve response (should never happen)\u001b[39m\u001b[33m\"\u001b[39m\n", + "\u001b[31mNotFoundError\u001b[39m: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-sonnet-4-5-invalid'}, 'request_id': 'req_011CX8LwhFYHFhGVh4wmrHXi'}", + "During task with name 'model' and id 'c98c9117-44be-713d-10f4-8125285b9ea0'" + ] + } + ], "source": [ "stream_graph(\n", " agent,\n", @@ -656,7 +1016,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": ".venv (3.11.14)", "language": "python", "name": "python3" }, @@ -670,9 +1030,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/03-Agent/assets/langgraph-agent.png b/03-Agent/assets/langgraph-agent.png new file mode 100644 index 0000000000000000000000000000000000000000..e58f7f55a9a0b2d99aaecf2dd4ba06bfb351d271 GIT binary patch literal 54222 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%0DE)1vLc{WDV27v~^9cyp)e`Q!;qF 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 Date: Tue, 10 Feb 2026 23:37:26 +0900 Subject: [PATCH 2/3] chore: update Agent tutorial notebook outputs and diagram png --- 03-Agent/01-LangGraph-Agents.ipynb | 189 ++++++++++++---------------- 03-Agent/assets/langgraph-agent.png | Bin 54222 -> 27249 bytes 2 files changed, 78 insertions(+), 111 deletions(-) diff --git a/03-Agent/01-LangGraph-Agents.ipynb b/03-Agent/01-LangGraph-Agents.ipynb index 18053aa..a69433c 100644 --- a/03-Agent/01-LangGraph-Agents.ipynb +++ b/03-Agent/01-LangGraph-Agents.ipynb @@ -119,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -137,7 +137,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -166,7 +166,7 @@ "\n", "`wrap_model_call` 데코레이터를 사용하면 모델 호출 전에 요청을 검사하고 수정할 수 있는 미들웨어를 생성할 수 있습니다.\n", "\n", - "![](assets/wrap_model_call.png)\n", + "![](../assets/wrap_model_call.png)\n", "\n", "아래 코드는 대화 길이에 따라 모델을 동적으로 선택하는 예시입니다." ] @@ -184,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -207,6 +207,7 @@ " model = basic_model\n", "\n", " request.model = model\n", + " print(f\"모델 선택: {request.model.model}\")\n", " return handler(request)\n", "\n", "\n", @@ -217,14 +218,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/var/folders/v7/jvdq74bd213fzs8k9cmpl_7w0000gn/T/ipykernel_46472/4199075104.py:19: DeprecationWarning: Direct attribute assignment to ModelRequest.model is deprecated. Use request.override(model=...) instead to create a new request with the modified attribute.\n", + "/var/folders/v7/jvdq74bd213fzs8k9cmpl_7w0000gn/T/ipykernel_63447/2629723978.py:19: DeprecationWarning: Direct attribute assignment to ModelRequest.model is deprecated. Use request.override(model=...) instead to create a new request with the modified attribute.\n", " request.model = model\n" ] }, @@ -232,80 +233,68 @@ "name": "stdout", "output_type": "stream", "text": [ + "모델 선택: claude-haiku-4-5\n", "\n", "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", "# 머신러닝의 동작 원리\n", "\n", - "머신러닝은 **데이터로부터 패턴을 학습하여 예측하는 기술**입니다. 기본적인 동작 방식을 설명하겠습니다.\n", + "머신러닝은 **데이터로부터 패턴을 학습하여 예측이나 판단을 하는 기술**입니다. 기본 동작 과정을 설명하겠습니다.\n", "\n", - "## 🔄 기본 프로세스\n", + "## 🎯 기본 개념\n", "\n", "```\n", - "데이터 수집 → 학습 → 모델 생성 → 예측\n", + "데이터 입력 → 패턴 학습 → 모델 생성 → 예측/판단\n", "```\n", "\n", - "### 1️⃣ **데이터 학습 단계**\n", - "- 많은 양의 예제 데이터를 모델에 제공\n", - "- 입력값(X)과 정답(Y)의 관계를 찾아냄\n", - "- 예: 수백 장의 고양이 사진으로 \"이건 고양이다\"라고 학습\n", + "## 1️⃣ **학습 데이터 수집**\n", + "- 충분한 양의 데이터가 필요합니다\n", + "- 예: 고양이 사진 10,000장\n", + "\n", + "## 2️⃣ **특징(Feature) 추출**\n", + "- 데이터에서 중요한 정보를 뽑아냅니다\n", + "- 예: 사진의 색상, 모양, 질감 등\n", "\n", - "### 2️⃣ **패턴 인식**\n", - "- 모델이 데이터의 숨겨진 규칙을 발견\n", - "- 가중치(weight)와 편향(bias) 값을 조정하며 최적화\n", + "## 3️⃣ **모델 학습 (가중치 조정)**\n", "\n", - "### 3️⃣ **오차 수정**\n", "```\n", - "예측값과 실제값의 차이(오차) 계산\n", - " ↓\n", - "오차를 줄이는 방향으로 가중치 조정\n", - " ↓\n", - "반복 (더 정확해짐)\n", + "초기값 → 계산 → 오류 측정 → 가중치 조정 \n", + " ↑\n", + " 반복\n", "```\n", "\n", - "### 4️⃣ **예측**\n", - "- 학습이 완료되면 새로운 데이터에 대해 예측\n", + "- **손실함수**: 예측값과 실제값의 차이를 계산\n", + "- **경사하강법**: 오류를 줄이는 방향으로 계속 조정\n", "\n", - "---\n", + "## 4️⃣ **성능 평가**\n", + "- 학습하지 않은 테스트 데이터로 검증\n", + "- 정확도, 재현율 등으로 평가\n", "\n", - "## 📊 주요 머신러닝 유형\n", - "\n", - "| 유형 | 설명 | 예시 |\n", - "|------|------|------|\n", - "| **지도학습** | 정답이 있는 데이터로 학습 | 메일 스팸 분류, 주택 가격 예측 |\n", - "| **비지도학습** | 정답이 없는 데이터를 그룹화 | 고객 세분화, 데이터 압축 |\n", - "| **강화학습** | 보상으로부터 학습 | 게임 AI, 로봇 제어 |\n", + "## 5️⃣ **예측**\n", + "- 학습된 모델이 새로운 데이터를 분류/예측\n", "\n", "---\n", "\n", - "## 🎯 간단한 예시\n", - "\n", - "**\"온도와 습도로 내일 비 올 확률 예측\"**\n", - "\n", - "```python\n", - "# 과거 데이터\n", - "온도 25°C, 습도 80% → 비 옴 ✓\n", - "온도 30°C, 습도 30% → 안 옴 ✓\n", - "...\n", + "## 📊 머신러닝의 주요 유형\n", "\n", - "# 모델이 학습\n", - "\"습도가 높으면 비가 올 가능성이 높다\"\n", - "\"온도가 낮으면 비가 올 가능성이 높다\"\n", - "\n", - "# 새로운 예측\n", - "내일 온도 22°C, 습도 75% \n", - "→ 모델: \"비 올 확률 85%\"\n", - "```\n", + "| 유형 | 설명 | 예시 |\n", + "|------|------|------|\n", + "| **지도학습** | 정답을 알려주며 학습 | 스팸 메일 분류 |\n", + "| **비지도학습** | 정답 없이 패턴을 찾음 | 고객 분류 |\n", + "| **강화학습** | 보상으로 학습 | 게임 AI |\n", "\n", "---\n", "\n", - "## ⚠️ 중요한 개념\n", + "## 💡 쉬운 비유\n", "\n", - "- **과적합(Overfitting)**: 학습 데이터에만 잘 맞고 새 데이터에는 실패\n", - "- **일반화(Generalization)**: 새로운 데이터에도 잘 작동하도록 하는 것이 목표\n", + "**아이가 동물을 배우는 과정:**\n", + "1. 많은 고양이 사진을 본다 (데이터)\n", + "2. \"귀가 있고, 수염이 있고...\" 특징을 인식 (특징 추출)\n", + "3. 규칙을 만들어간다 (모델 학습)\n", + "4. 새로운 고양이 사진을 보고 \"고양이다!\" 판단 (예측)\n", "\n", - "더 궁금한 부분이 있으신가요?" + "궁금한 부분이 있으면 더 자세히 설명해드릴 수 있습니다! 😊" ] } ], @@ -344,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -362,16 +351,16 @@ " system_prompt=\"emoji 를 사용해서 답변해줘\",\n", " tool_choice=\"auto\",\n", " )\n", - " return handler(new_request)\n", " else:\n", " new_request = request.override(\n", " model=basic_model,\n", " system_prompt=\"한 문장으로 간결하게 답변해줘. emoji 는 사용하지 말아줘.\",\n", " tool_choice=\"auto\",\n", " )\n", - " return handler(new_request)\n", - "\n", + " print(f\"모델 선택: {new_request.model.model}\")\n", + " return handler(new_request)\n", "\n", + " \n", "agent = create_agent(\n", " model=basic_model, tools=[], middleware=[dynamic_model_selection] # 기본 모델\n", ")" @@ -388,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -396,31 +385,14 @@ "output_type": "stream", "text": [ "글자수: 9\n", + "모델 선택: claude-haiku-4-5\n", "\n", "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", "# 머신러닝 동작원리\n", "\n", - "머신러닝은 데이터로부터 패턴을 학습하여 새로운 데이터에 대한 예측이나 분류를 수행하는 기술입니다.\n", - "\n", - "## 기본 동작 과정\n", - "\n", - "1. **데이터 수집 및 전처리** - 학습에 필요한 데이터를 모으고 정제합니다.\n", - "\n", - "2. **모델 선택** - 문제에 적합한 알고리즘(회귀, 분류, 군집화 등)을 선택합니다.\n", - "\n", - "3. **학습(Training)** - 알고리즘이 데이터의 패턴을 찾아 가중치를 조정하며, 오차를 줄이는 방향으로 반복 업데이트합니다.\n", - "\n", - "4. **검증 및 평가** - 학습된 모델의 성능을 테스트 데이터로 평가합니다.\n", - "\n", - "5. **예측(Inference)** - 학습된 모델으로 새로운 데이터에 대한 예측을 수행합니다.\n", - "\n", - "## 핵심 개념\n", - "\n", - "- **손실함수**: 예측값과 실제값의 차이를 계산하여 모델 개선 방향을 제시합니다.\n", - "- **최적화**: 경사하강법 등으로 손실함수를 최소화하는 가중치를 찾습니다.\n", - "- **일반화**: 학습 데이터뿐 아니라 미본 데이터에서도 좋은 성능을 내도록 학습합니다." + "머신러닝은 프로그래밍된 규칙 대신 데이터로부터 패턴을 학습하여 예측이나 분류를 수행하는 기술로, 크게 데이터 수집 → 특성 추출 → 모델 선택 → 학습(가중치 조정) → 예측 단계를 거쳐 작동합니다." ] } ], @@ -437,7 +409,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -445,54 +417,49 @@ "output_type": "stream", "text": [ "글자수: 25\n", + "모델 선택: claude-sonnet-4-5\n", "\n", "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", "# 머신러닝의 동작 원리 🤖\n", "\n", - "머신러닝을 쉽게 설명해드릴게요! 😊\n", + "머신러닝은 컴퓨터가 데이터로부터 스스로 학습하는 기술이에요! 🎯\n", "\n", - "## 1️⃣ 기본 개념\n", - "머신러닝은 컴퓨터가 **명시적으로 프로그래밍되지 않고도 데이터로부터 학습**하는 기술이에요 📚\n", + "## 기본 동작 과정 🔄\n", "\n", - "## 2️⃣ 핵심 동작 과정\n", + "### 1️⃣ 데이터 수집 📊\n", + "- 학습에 필요한 데이터를 모아요\n", + "- 예: 고양이 사진 1000장 🐱\n", "\n", - "### 🔹 데이터 수집\n", + "### 2️⃣ 모델 선택 🏗️\n", + "- 문제에 맞는 알고리즘을 선택해요\n", + "- 신경망, 결정트리, SVM 등\n", + "\n", + "### 3️⃣ 학습 과정 📚\n", "```\n", - "예시: 고양이 🐱 사진 1000장, 강아지 🐶 사진 1000장\n", + "입력 데이터 → 모델 → 예측 결과\n", + " ↓\n", + " 실제 답과 비교\n", + " ↓\n", + " 오차 계산 📉\n", + " ↓\n", + " 모델 파라미터 조정 🔧\n", "```\n", "\n", - "### 🔹 학습 (Training)\n", - "1. **입력**: 사진 데이터를 모델에 제공\n", - "2. **예측**: 모델이 \"이건 고양이일까? 강아지일까?\" 추측\n", - "3. **오차 계산**: 정답과 비교해서 틀린 정도 측정 📊\n", - "4. **가중치 조정**: 오차를 줄이는 방향으로 내부 파라미터 수정 🔧\n", - "5. **반복**: 2~4 과정을 수천~수만 번 반복 🔄\n", - "\n", - "### 🔹 예측 (Prediction)\n", - "학습된 모델에 새로운 사진을 보여주면 → 정확하게 분류! ✨\n", - "\n", - "## 3️⃣ 핵심 요소\n", - "\n", - "| 요소 | 설명 | 이모지 |\n", - "|------|------|--------|\n", - "| 데이터 | 학습의 재료 | 📊 |\n", - "| 모델 | 학습 알고리즘 | 🧠 |\n", - "| 손실함수 | 오차 측정 도구 | 📏 |\n", - "| 최적화 | 성능 개선 방법 | ⚡ |\n", + "### 4️⃣ 반복 학습 🔁\n", + "- 오차가 줄어들 때까지 반복해요\n", + "- 점점 정확도가 높아져요! ⬆️\n", "\n", - "## 4️⃣ 비유로 이해하기 🎯\n", + "### 5️⃣ 평가 및 예측 ✅\n", + "- 새로운 데이터로 성능 테스트\n", + "- 실전에 적용! 🚀\n", "\n", - "**아기가 말을 배우는 과정과 비슷해요!**\n", - "- 부모가 \"멍멍\" 하며 강아지를 가리킴 👉🐕\n", - "- 아기가 여러 번 보고 듣음 👂👀\n", - "- 점점 강아지를 보면 \"멍멍\"이라고 말함 🗣️\n", - "- 실수하면 교정받고 다시 학습 ✅\n", + "## 핵심 원리 💡\n", "\n", - "이것이 바로 머신러닝의 원리예요! 💡\n", + "**\"경험(데이터)을 통해 성능을 개선하는 것\"**\n", "\n", - "궁금한 점 있으면 더 물어보세요! 🙋‍♀️" + "마치 아기가 넘어지면서 걷기를 배우는 것처럼, 컴퓨터도 실수를 반복하며 배워요! 👶➡️🚶" ] } ], @@ -1016,7 +983,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv (3.11.14)", + "display_name": "feat-agent (3.11.14)", "language": "python", "name": "python3" }, diff --git a/03-Agent/assets/langgraph-agent.png b/03-Agent/assets/langgraph-agent.png index e58f7f55a9a0b2d99aaecf2dd4ba06bfb351d271..e9ce89cf9250bca5505e1162645734acd404592e 100644 GIT binary patch literal 27249 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%0DE)1vLc{WDV27v~^9cyp)e`Q!;qF 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 Date: Tue, 10 Feb 2026 23:38:22 +0900 Subject: [PATCH 3/3] feat: add used excalidraw file --- 03-Agent/assets/langgraph-agent.excalidraw | 527 +++++++++++++++++++++ 1 file changed, 527 insertions(+) create mode 100644 03-Agent/assets/langgraph-agent.excalidraw diff --git a/03-Agent/assets/langgraph-agent.excalidraw b/03-Agent/assets/langgraph-agent.excalidraw new file mode 100644 index 0000000..3abd80b --- /dev/null +++ b/03-Agent/assets/langgraph-agent.excalidraw @@ -0,0 +1,527 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "mermaid-to-excalidraw", + "elements": [ + { + "id": "QUERY", + "type": "rectangle", + "groupIds": [], + "x": 112.6484375, + "y": 0, + "width": 84.296875, + "height": 44, + "strokeWidth": 2, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "link": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "QUERY-text" + } + ] + }, + { + "id": "QUERY-text", + "type": "text", + "x": 124.796875, + "y": 9.5, + "width": 60, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 435946922, + "version": 1, + "versionNonce": 1499418233, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "input", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QUERY", + "originalText": "input", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "LLM", + "type": "diamond", + "groupIds": [], + "x": 90.7421875, + "y": 94, + "width": 128.109375, + "height": 128.109375, + "strokeWidth": 2, + "strokeColor": "#ca8a04", + "backgroundColor": "#fef08a", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "link": null, + "boundElements": [ + { + "type": "text", + "id": "LLM-text" + } + ] + }, + { + "id": "LLM-text", + "type": "text", + "x": 124.796875, + "y": 145.5546875, + "width": 60, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 789595348, + "version": 1, + "versionNonce": 1591726080, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "model", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "LLM", + "originalText": "model", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "TOOL", + "type": "rectangle", + "groupIds": [], + "x": 60.18359375, + "y": 301.109375, + "width": 69.25, + "height": 44, + "strokeWidth": 2, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "link": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "TOOL-text" + } + ] + }, + { + "id": "TOOL-text", + "type": "text", + "x": 64.80859375, + "y": 310.609375, + "width": 60, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 1734077799, + "version": 1, + "versionNonce": 1144502286, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "tools", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "TOOL", + "originalText": "tools", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "ANSWER", + "type": "rectangle", + "groupIds": [], + "x": 229.796875, + "y": 301.109375, + "width": 100.5, + "height": 44, + "strokeWidth": 2, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "link": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "ANSWER-text" + } + ] + }, + { + "id": "ANSWER-text", + "type": "text", + "x": 244.046875, + "y": 310.609375, + "width": 72, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 160711134, + "version": 1, + "versionNonce": 1008445031, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "output", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ANSWER", + "originalText": "output", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "QUERY_LLM", + "type": "arrow", + "groupIds": [], + "x": 154.797, + "y": 44, + "strokeWidth": 2, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "points": [ + [ + 0, + 0 + ], + [ + 0.396000000000015, + 45.20099999999999 + ] + ], + "roundness": { + "type": 2 + }, + "start": { + "id": "QUERY" + }, + "end": { + "id": "LLM" + } + }, + { + "id": "LLM_TOOL", + "type": "arrow", + "groupIds": [], + "x": 120.917, + "y": 188.229, + "strokeWidth": 2, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "points": [ + [ + 0, + 0 + ], + [ + -86.09700000000001, + 73.37999999999997 + ], + [ + -51.268, + 109.08599999999998 + ] + ], + "roundness": { + "type": 2 + }, + "start": { + "id": "LLM" + }, + "end": { + "id": "TOOL" + }, + "boundElements": [ + { + "type": "text", + "id": "LLM_TOOL-text" + } + ] + }, + { + "id": "LLM_TOOL-text", + "type": "text", + "x": -5, + "y": 235, + "width": 72, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 942062837, + "version": 1, + "versionNonce": 1083494293, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "action", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "LLM_TOOL", + "originalText": "action", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "TOOL_LLM", + "type": "arrow", + "groupIds": [], + "x": 116.268, + "y": 301.109, + "strokeWidth": 2, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "points": [ + [ + 0, + 0 + ], + [ + 38.528999999999996, + -39.5 + ], + [ + 38.96100000000001, + -73.19999999999999 + ] + ], + "roundness": { + "type": 2 + }, + "start": { + "id": "TOOL" + }, + "end": { + "id": "LLM" + }, + "boundElements": [ + { + "type": "text", + "id": "TOOL_LLM-text" + } + ] + }, + { + "id": "TOOL_LLM-text", + "type": "text", + "x": 130, + "y": 255, + "width": 132, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 1390254560, + "version": 1, + "versionNonce": 1523828737, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "observation", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "TOOL_LLM", + "originalText": "observation", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "LLM_ANSWER", + "type": "arrow", + "groupIds": [], + "x": 190.361, + "y": 187.545, + "strokeWidth": 2, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "roughness": 0, + "opacity": 100, + "points": [ + [ + 0, + 0 + ], + [ + 89.68600000000004, + 74.064 + ], + [ + 89.68600000000004, + 108.26400000000004 + ] + ], + "roundness": { + "type": 2 + }, + "start": { + "id": "LLM" + }, + "end": { + "id": "ANSWER" + }, + "boundElements": [ + { + "type": "text", + "id": "LLM_ANSWER-text" + } + ] + }, + { + "id": "LLM_ANSWER-text", + "type": "text", + "x": 275, + "y": 235, + "width": 72, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": null, + "roundness": null, + "seed": 430140322, + "version": 1, + "versionNonce": 1005965341, + "isDeleted": false, + "boundElements": null, + "updated": 1770733281448, + "link": null, + "locked": false, + "text": "finish", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "LLM_ANSWER", + "originalText": "finish", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "theme": "light", + "viewBackgroundColor": "#ffffff", + "currentItemFontFamily": 1 + }, + "files": {} +}