랭체인 에이전트 심화

- RouterChain, RunnableBranch, SequentialChain
This commit is contained in:
2026-06-05 17:58:54 +09:00
parent eb387fbaa7
commit 30a049c5e1
15 changed files with 2192 additions and 140 deletions
Binary file not shown.
Binary file not shown.
+1333 -133
View File
File diff suppressed because one or more lines are too long
+700
View File
@@ -0,0 +1,700 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-06-05T06:07:18.527729458Z",
"start_time": "2026-06-05T06:07:18.518264605Z"
}
},
"source": [
"import os\n",
"\n",
"from google.protobuf.timestamp import from_current_time\n",
"from langchain_classic.chains.sequential import SequentialChain\n",
"from langchain_openai import ChatOpenAI\n",
"from langchain_ibm import WatsonxEmbeddings\n",
"from langchain_ibm import ChatWatsonx\n",
"from langchain.agents import create_agent\n",
"from langchain_ollama import OllamaEmbeddings\n",
"from langchain_ollama import ChatOllama\n",
"from langchain_ollama import OllamaEmbeddings, ChatOllama\n",
"from dotenv import load_dotenv\n",
"\n",
"from langchain_community.utilities import GoogleSerperAPIWrapper\n",
"from langchain_core.tools import Tool\n",
"from langchain_core.tools import tool\n",
"\n",
"from langchain_core.prompts import PromptTemplate, ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.output_parsers import StrOutputParser, JsonOutputParser, PydanticOutputParser\n",
"from langchain_core.runnables import RunnablePassthrough, RunnableParallel, RunnableLambda\n",
"from sklearn import pipeline"
],
"outputs": [],
"execution_count": 6
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T06:07:18.540816647Z",
"start_time": "2026-06-05T06:07:18.529482429Z"
}
},
"cell_type": "code",
"source": [
"# .env 내용 가져오기\n",
"load_dotenv()\n",
"\n",
"apikey = os.getenv(\"WATSONX_API_KEY\")\n",
"project_id = os.getenv(\"WATSONX_PROJECT_ID\")\n",
"watsonx_ai_url = os.getenv(\"WATSONX_URL\")\n",
"hf_token = os.getenv(\"HF_TOKEN\")\n",
"COHERE_API_KEY = os.getenv(\"COHERE_API_KEY\")\n",
"SERPER_API_KEY = os.getenv(\"SERPER_API_KEY\")\n",
"GEMINI_API_KEY = os.getenv(\"GEMINI_API_KEY\")\n",
"LANGSMITH_API_KEY = os.getenv(\"LANGSMITH_API_KEY\")"
],
"id": "c2c64c7967231118",
"outputs": [],
"execution_count": 7
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T06:07:22.476243454Z",
"start_time": "2026-06-05T06:07:18.541903550Z"
}
},
"cell_type": "code",
"source": [
"watson_llm = ChatWatsonx(\n",
" model_id=\"ibm/granite-4-h-small\",\n",
" url=f\"{watsonx_ai_url}\",\n",
" api_key=f\"{apikey}\",\n",
" project_id=f\"{project_id}\",\n",
" max_tokens=2000,\n",
" params={\n",
" \"temperature\": 0\n",
" }\n",
")\n",
"\n",
"watson_embedding = WatsonxEmbeddings(\n",
" model_id=\"ibm/granite-embedding-278m-multilingual\",\n",
" url=f\"{watsonx_ai_url}\",\n",
" api_key=f\"{apikey}\",\n",
" project_id=f\"{project_id}\"\n",
")\n",
"\n",
"hugging_llm = ChatOpenAI(\n",
" model=\"Qwen/Qwen2.5-7B-Instruct:together\",\n",
" api_key=hf_token,\n",
" base_url=\"https://router.huggingface.co/v1\",\n",
" temperature=0,\n",
")\n",
"\n",
"ollama_embedding = OllamaEmbeddings(model=\"nomic-embed-text-v2-moe\")\n",
"\n",
"# 로컬 LLM\n",
"qwen_llm = ChatOllama(model=\"qwen3.5:4b\", temperature=0)\n",
"exaone_llm = ChatOllama(model=\"exaone3.5:2.4b\", temperature=0)\n",
"gemma_llm = ChatOllama(model=\"gemma4:e2b\")"
],
"id": "560df17d1a798650",
"outputs": [],
"execution_count": 8
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T06:07:22.498652432Z",
"start_time": "2026-06-05T06:07:22.487631249Z"
}
},
"cell_type": "code",
"source": [
"def print_result(result):\n",
" for i, msg in enumerate(result['messages']):\n",
" print(f\"\\n===== {i} =====\")\n",
" print(type(msg).__name__)\n",
"\n",
" if hasattr(msg, 'content'):\n",
" print(msg.content)\n",
"\n",
" if hasattr(msg, \"tool_calls\"):\n",
" print(msg.tool_calls)"
],
"id": "abfd826c1b3e2703",
"outputs": [],
"execution_count": 9
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"### RouterChain(LCEL Router : 조건부 분기 패턴\n",
"- Router 패턴 : 입력에 따라 적절한 체인 or Runnable 로 분기\n",
"- 분류기(LLM기반 or 규칙기반)가 입력을 분석 -> 적절한 체인을 라우팅\n",
"- |\n",
"- ex) 질문 유형(코딩 / 수학 / 일반 ....)에 따른 전문 프롬프트를 적용\n",
"- 동작흐름\n",
" (1) 입력 => (2) 분류기 => (3) 라우팅 => (4) 실행 => (5) 반환"
],
"id": "fb42bec3088a485e"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T06:46:44.553396205Z",
"start_time": "2026-06-05T06:46:44.544122014Z"
}
},
"cell_type": "code",
"source": [
"parser = StrOutputParser()\n",
"\n",
"# 수학체인\n",
"math_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"당신은 수학 전문가입니다. 풀이 과정을 단계별로 설명하세요.\"),\n",
" (\"human\", \"{question}\"),\n",
"]) | watson_llm | parser\n",
"\n",
"# 코드 체인\n",
"code_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"당신은 시니어 개발자입니다. 코드와 주석을 함께 제공하세요.\"),\n",
" (\"human\", \"{question}\"),\n",
"]) | watson_llm | parser\n",
"\n",
"# 일반 체인\n",
"general_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"당신은 친절한 AI 어시스턴트입니다. 한국어로 답변하세요.\"),\n",
" (\"human\", \"{question}\"),\n",
"]) | watson_llm | parser\n",
"\n",
"# 분류기 : 질문을 읽고 유형을 반환\n",
"classify_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"질문 유형을 math/code/general 중 하나로만 답하세요.\"),\n",
" (\"human\", \"{question}\"),\n",
"]) | watson_llm | parser\n",
"def route(inputs:dict):\n",
" category = classify_chain.invoke(inputs).strip().lower()\n",
"\n",
" print(f\" => 븐류결과 {category}\")\n",
"\n",
" if \"math\" in category: return math_chain\n",
" elif \"code\" in category: return code_chain\n",
" else: return general_chain\n",
"\n",
"# router_chain = RunnableLambda(route) | RunnableLambda(lamda chain: chain)\n",
"router_chain = RunnableLambda(lambda x:route(x).invoke(x))"
],
"id": "1e18698dde2e75b5",
"outputs": [],
"execution_count": 13
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T06:53:39.704503264Z",
"start_time": "2026-06-05T06:52:54.753636702Z"
}
},
"cell_type": "code",
"source": [
"questions = [\n",
" { 'question': '피타고라스 정리를 증명해줘'},\n",
" { 'question': '오늘 저녁 메뉴 추천해줘'},\n",
" { 'question': '파이썬으로 버블 정렬 구현해줘'},\n",
" { 'question': '피타고라스 정리를 코드로 짜줘'},\n",
"]\n",
"\n",
"for q in questions:\n",
" print(f\"Q: {q['question']}\")\n",
" print(f\"A: {router_chain.invoke(q)[:100]}...\\n\")\n"
],
"id": "c9fa6cb3d73bc4e7",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Q: 피타고라스 정리를 증명해줘\n",
" => 븐류결과 네, 다음은 피타고라스의 정리 증명입니다:\n",
"\n",
"a, b, c의 변을 가진 직각삼각형이 있다고 가정합니다. 삼각형 안에 변의 길이가 a, b, c인 정사각형을 그립니다. 다음은 그 증명입니다:\n",
"\n",
"1. 삼각형 안에 변의 길이가 a, b, c인 정사각형의 넓이는 a^2 + b^2입니다.\n",
"\n",
"2. 삼각형을 두 개의 작은 직각삼각형으로 나누기 위해 빗변(c)에 수직선을 그립니다.\n",
"\n",
"3. 수직선이 전에 있었던 빗변의 길이가 c인 두 개의 작은 직각삼각형의 넓이는 각각 (a^2)와 (b^2)입니다.\n",
"\n",
"4. 전체 삼각형의 넓이는 작은 직각삼각형의 넓이의 합이어야 합니다. 따라서, 삼각형의 넓이는 (a^2) + (b^2)입니다.\n",
"\n",
"5. 삼각형이 직각삼각형이므로, 빗변의 길이는 c입니다. 따라서, 삼각형의 넓이는 (1/2)c^2입니다.\n",
"\n",
"6. 넓이가 같다는 것을 결론지을 수 있으므로, (a^2) + (b^2) = (1/2)c^2입니다.\n",
"\n",
"7. 양변에 2를 곱하면 a^2 + b^2 = c^2가 됩니다.\n",
"\n",
"8. 이것이 피타고라스의 정리입니다.\n",
"\n",
"따라서, 피타고라스의 정리는 직각삼각형의 빗변의 길이의 제곱이 다른 두 변의 길이의 제곱의 합과 같다는 것을 보여줍니다.\n",
"A: 피타고라스 정리는 직각삼각형에서 빗변의 길이의 제곱이 나머지 두 변의 길이의 제곱의 합과 같다는 정리입니다. 이 정리를 증명해 드리겠습니다.\n",
"\n",
"가정: 직각삼각형 ABC에서 각 A가...\n",
"\n",
"Q: 오늘 저녁 메뉴 추천해줘\n",
" => 븐류결과 질문 유형: general\n",
"\n",
"오늘 저녁 메뉴로는 간단하면서도 맛있는 \"치킨과 샐러드\"를 추천해드릴게요. 치킨은 구운 닭고기를 사용하고, 샐러드는 신선한 채소와 드레싱을 곁들여서 영양가 있고 가벼운 식사를 즐길 수 있습니다. 또한, 필요에 따라 사이드 디시로 감자 샐러드나 빵을 추가할 수도 있습니다. 이 메뉴는 준비하기도 쉽고, 가족이나 친구들과 함께 즐기기에 좋은 선택이 될 것 같아요.\n",
"A: 저녁 메뉴로는 다양한 선택지가 있습니다. 건강하고 맛있는 한국 요리를 추천해 드리겠습니다.\n",
"\n",
"1. 비빔밥: 밥에 다양한 채소와 고기를 넣고 고추장 소스를 섞어 먹는 한국의 대표적인...\n",
"\n",
"Q: 파이썬으로 버블 정렬 구현해줘\n",
" => 븐류결과 다음은 파이썬으로 구현한 버블 정렬 코드입니다.\n",
"\n",
"```python\n",
"def bubble_sort(arr):\n",
" n = len(arr)\n",
" \n",
" for i in range(n - 1):\n",
" for j in range(n - i - 1):\n",
" if arr[j] > arr[j + 1]:\n",
" arr[j], arr[j + 1] = arr[j + 1], arr[j]\n",
" \n",
" return arr\n",
"```\n",
"\n",
"이 코드는 다음과 같이 동작합니다.\n",
"\n",
"1. `bubble_sort` 함수는 정렬할 배열 `arr`을 입력으로 받습니다.\n",
"\n",
"2. 배열의 길이 `n`을 변수에 저장합니다.\n",
"\n",
"3. 외부 루프 `for i in range(n - 1)`는 배열을 `n - 1`번 반복하며, 각 반복에서 가장 큰 원소를 배열의 끝쪽으로 이동시킵니다.\n",
"\n",
"4. 내부 루프 `for j in range(n - i - 1)`는 현재 루프에서 비교해야 할 인접한 원소 쌍을 탐색합니다. `n - i - 1`은 이미 정렬된 원소를 제외한 나머지 원소들을 비교하기 위해 사용됩니다.\n",
"\n",
"5. `if arr[j] > arr[j + 1]` 조건문은 현재 원소와 다음 원소를 비교하여, 현재 원소가 다음 원소보다 크다면 두 원소를 교환합니다. 이 과정을 통해 큰 원소가 뒤로 이동하게 됩니다.\n",
"\n",
"6. 모든 루프가 완료되면 정렬된 배열을 반환합니다.\n",
"\n",
"이 함수를 사용하는 예제는 다음과 같습니다.\n",
"\n",
"```python\n",
"# 예제 사용\n",
"arr = [64, 34, 25, 12, 22, 11, 90]\n",
"print(\"정렬 전:\", arr)\n",
"\n",
"sorted_arr = bubble_sort(arr)\n",
"print(\"정렬 후:\", sorted_arr)\n",
"```\n",
"\n",
"출력 결과는 다음과 같습니다.\n",
"\n",
"```\n",
"정렬 전: [64, 34, 25, 12, 22, 11, 90]\n",
"정렬 후: [11, 12, 22, 25, 34, 64, 90]\n",
"```\n",
"\n",
"버블 정렬은 간단하고 직관적인 정렬 알고리즘이지만, 시간 복잡도가 o(n^2)로 비효율적인 편입니다. 대규모 데이터에 대해서는 다른 정렬 알고리즘을 고려하는 것이 좋습니다.\n",
"A: 물론입니다! 파이썬으로 버블 정렬을 구현해드리겠습니다. 버블 정렬은 인접한 두 원소를 비교하며 정렬하는 간단한 정렬 알고리즘입니다. 다음은 파이썬 코드입니다:\n",
"```python\n",
"d...\n",
"\n",
"Q: 피타고라스 정리를 코드로 짜줘\n",
" => 븐류결과 피타고라스 정리를 코드로 구현하려면, 먼저 피타고라스 정리가 무엇인지 이해해야 합니다. 피타고라스 정리는 직각삼각형에서 빗변의 길이의 제곱이 나머지 두 변의 길이의 제곱의 합과 같다는 정리입니다. 수식으로 표현하면 다음과 같습니다.\n",
"\n",
"```\n",
"c² = a² + b²\n",
"```\n",
"\n",
"여기서 c는 빗변의 길이이고, a와 b는 나머지 두 변의 길이입니다.\n",
"\n",
"이제 이 정리를 코드로 구현해 보겠습니다. 여기서는 python을 사용하여 구현하겠습니다.\n",
"\n",
"```python\n",
"def pythagorean_theorem(a, b):\n",
" c_squared = a**2 + b**2\n",
" c = c_squared ** 0.5\n",
" return c\n",
"\n",
"# 예시 사용\n",
"a = 3\n",
"b = 4\n",
"c = pythagorean_theorem(a, b)\n",
"print(f\"빗변의 길이는: {c}\")\n",
"```\n",
"\n",
"이 코드에서는 `pythagorean_theorem`이라는 함수를 정의하고, 두 개의 인자 `a`와 `b`를 받습니다. 이 함수는 피타고라스 정리를 사용하여 빗변의 길이 `c`를 계산하고 반환합니다. 예시 사용에서는 `a`와 `b`에 각각 3과 4를 할당하고, `pythagorean_theorem` 함수를 호출하여 빗변의 길이를 계산한 후 출력합니다.\n",
"A: 피타고라스 정리를 코드로 작성하려면, 파이썬을 사용하여 다음과 같이 작성할 수 있습니다.\n",
"```python\n",
"def pythagorean_theorem(a, b):\n",
" c = (...\n",
"\n"
]
}
],
"execution_count": 19
},
{
"metadata": {},
"cell_type": "markdown",
"source": "#### RunnableBranch(선언형 분기)",
"id": "6d1f541fb236bfd9"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T07:11:06.032073974Z",
"start_time": "2026-06-05T07:10:36.542912312Z"
}
},
"cell_type": "code",
"source": [
"from langchain_core.runnables import RunnableBranch\n",
"\n",
"# RunnableBranch((조건1, 체인1), (조건2, 체인2), (조건3, 체인3))\n",
"\n",
"branch = RunnableBranch(\n",
" (lambda x:\"math\" in x.get(\"topic\", ''), math_chain),\n",
" (lambda x:\"code\" in x.get(\"topic\", ''), code_chain),\n",
" (lambda x:\"cooking\" in x.get(\"topic\", ''), ChatPromptTemplate.from_messages([\n",
" (\"system\", \"당신은 요리전문가 AI 어시스턴트입니다. 한국어로 답변하세요.\"),\n",
" (\"human\", \"{question}\"),\n",
" ]) | watson_llm | parser),\n",
" general_chain\n",
")\n",
"\n",
"print(branch.invoke({'topic':'math', 'question':'미분이란?'}))\n",
"print(branch.invoke({'topic':'code', 'question':'미적분 코드 구현'}))\n",
"print(branch.invoke({'topic':'cooking', 'question':'김치찌개 레시피?'}))\n",
"print(branch.invoke({'topic':'other', 'question':'안녕하세요?'}))\n"
],
"id": "7e5d342621ece0b0",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"미분은 수학에서 함수의 변화율을 나타내는 개념입니다. 미분은 함수의 그래프에서 접선의 기울기를 구하는 과정으로, 함수의 변화율을 정확하게 파악할 수 있게 해줍니다. 미분은 미적분학의 핵심 개념 중 하나이며, 미분을 통해 함수의 최대값, 최소값, 변곡점 등을 찾을 수 있습니다.\n",
"\n",
"미분의 과정을 단계별로 설명하겠습니다.\n",
"\n",
"1. 함수 f(x)를 주어진다고 가정합니다.\n",
"2. 미분을 구하기 위해 독립변수 x에 대한 미소변화량을 나타내는 기호 'dx'를 사용합니다. 이때, 함수 값의 미소변화량을 'dy'로 나타냅니다.\n",
"3. 함수 f(x)의 미분은 다음과 같이 정의됩니다: dy/dx = f'(x) = lim(h→0) (f(x+h) - f(x))/h\n",
"4. 이 식에서 lim(h→0)은 h가 0에 가까워질 때의 극한을 의미합니다. 이 극한을 구하면 함수 f(x)의 미분, 즉 도함수 f'(x)를 얻을 수 있습니다.\n",
"5. 도함수 f'(x)는 함수 f(x)의 그래프에서 접선의 기울기를 나타냅니다. 이를 통해 함수의 변화율을 파악할 수 있습니다.\n",
"\n",
"예를 들어, 함수 f(x) = x^2를 미분해보겠습니다.\n",
"\n",
"1. f(x) = x^2\n",
"2. dy/dx = f'(x) = lim(h→0) (f(x+h) - f(x))/h\n",
"3. f(x+h) = (x+h)^2 = x^2 + 2xh + h^2\n",
"4. f'(x) = lim(h→0) ((x^2 + 2xh + h^2) - x^2)/h = lim(h→0) (2xh + h^2)/h\n",
"5. h를 제외한 항으로 나누면 f'(x) = lim(h→0) (2x + h) = 2x\n",
"\n",
"따라서, 함수 f(x) = x^2의 미분은 f'(x) = 2x입니다. 이 도함수는 함수의 그래프에서 접선의 기울기를 나타내며, 함수의 변화율을 파악하는 데 사용됩니다.\n",
"미적분 코드를 구현하려면, 파이썬의 `sympy` 라이브러리를 사용할 수 있습니다. 이 라이브러리는 기호 수학을 다루는 데 사용되며, 미적분 계산에도 적합합니다. 아래는 파이썬 코드와 주석을 함께 제공한 미적분 코드 구현 예시입니다.\n",
"```python\n",
"# 필요한 라이브러리를 임포트합니다.\n",
"import sympy as sp\n",
"\n",
"# 기호 변수를 정의합니다.\n",
"x = sp.symbols('x')\n",
"\n",
"# 함수를 정의합니다.\n",
"f = x**3 - 3*x**2 + 2*x\n",
"\n",
"# 함수의 도함수를 계산합니다.\n",
"f_prime = sp.diff(f, x)\n",
"\n",
"# 함수의 적분을 계산합니다.\n",
"f_integral = sp.integrate(f, x)\n",
"\n",
"# 결과를 출력합니다.\n",
"print(\"함수:\", f)\n",
"print(\"도함수:\", f_prime)\n",
"print(\"적분:\", f_integral)\n",
"```\n",
"위 코드에서는 다음과 같은 작업을 수행합니다.\n",
"\n",
"1. `sympy` 라이브러리를 임포트합니다.\n",
"2. 기호 변수 `x`를 정의합니다.\n",
"3. 함수 `f`를 정의합니다. 이 예시에서는 `f(x) = x^3 - 3x^2 + 2x`입니다.\n",
"4. `sp.diff()` 함수를 사용하여 함수 `f`의 도함수 `f_prime`를 계산합니다.\n",
"5. `sp.integrate()` 함수를 사용하여 함수 `f`의 적분 `f_integral`을 계산합니다.\n",
"6. 결과를 출력합니다.\n",
"\n",
"이 코드를 실행하면 다음과 같은 결과가 나옵니다.\n",
"```yaml\n",
"함수: x**3 - 3*x**2 + 2*x\n",
"도함수: 3*x**2 - 6*x + 2\n",
"적분: x**4/4 - x**3 + x**2\n",
"```\n",
"이 예시는 파이썬과 `sympy` 라이브러리를 사용하여 미적분 계산을 수행하는 기본적인 방법을 보여줍니다. 더 복잡한 미적분 문제를 해결하려면, `sympy` 라이브러리의 다양한 기능을 활용할 수 있습니다.\n",
"김치찌개 레시피를 알려드리겠습니다. 기본적인 재료와 조리법을 소개하겠습니다.\n",
"\n",
"재료:\n",
"\n",
"* 김치 2컵\n",
"* 돼지고기 목살 200g (또는 소고기 대신 사용 가능)\n",
"* 두부 1/2모\n",
"* 양파 1개\n",
"* 대파 1대\n",
"* 마늘 3쪽\n",
"* 고추장 1큰술\n",
"* 고춧가루 1큰술 (선택 사항)\n",
"* 된장 1작은술\n",
"* 물 2컵\n",
"* 참기름 약간\n",
"* 소금 약간\n",
"* 찹쌀떡 (선택 사항)\n",
"\n",
"조리법:\n",
"\n",
"1. 돼지고기를 적당한 크기로 썰어 물에 헹궈 물기를 제거한 후, 소금 약간을 뿌려 두세요.\n",
"2. 양파와 대파를 적당한 크기로 썰어 두세요. 마늘은 다진 후 준비합니다.\n",
"3. 냄비에 물을 넣고 끓인 후, 고기를 넣어 익을 때까지 끓입니다.\n",
"4. 고기가 익으면 김치를 넣고 함께 끓입니다. 김치가 익으면 두부를 넣고 끓입니다.\n",
"5. 고추장, 고춧가루, 된장을 넣어 간을 맞춥니다. 고추가루를 넣지 않고 맵지 않은 김치찌개를 원한다면 생략할 수 있습니다.\n",
"6. 양파, 대파, 마늘을 넣고 끓여줍니다. 소금으로 간을 맞춥니다.\n",
"7. 끓는 김치찌개에 참기름을 넣어 향을 더해줍니다.\n",
"8. 찹쌀떡을 넣고 싶다면 이 단계에서 넣어 끓여주세요.\n",
"9. 김치찌개가 끓으면 불을 끄고 대파를 다시 잘게 썰어 뿌려 준비가 완료됩니다.\n",
"\n",
"이제 맛있는 김치찌개가 완성되었습니다. 밥과 함께 드시면 더욱 맛있습니다. 맛있게 드세요!\n",
"안녕하세요! 어떻게 도와드릴까요?\n"
]
}
],
"execution_count": 20
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"### SequentialChain(단계별 순차 파이프라인)\n",
"\n",
"- 앞 단계 출력이 뒷단계의 입력으로 흘러 들어감\n",
"- | => SequentialChain\n",
"- .assign() : 중간 결과를 보존하여 여러 단계를 누적할 수 있음\n",
"- 각 단계의 출력 타입과 입력 타입이 일치해야 함"
],
"id": "ec0ad7ad57ee2a01"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T07:53:53.154055958Z",
"start_time": "2026-06-05T07:53:48.801194749Z"
}
},
"cell_type": "code",
"source": [
"# 체인 정의\n",
"translate_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"다음 텍스트를 한국어로 번역하세요. 번역문만 출력:\\n{text}.\"),\n",
"]) | watson_llm | parser\n",
"\n",
"summarize_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"다음 텍스트를 3문장으로 번역하세요.:\\n{text}.\"),\n",
"]) | watson_llm | parser\n",
"\n",
"sentiment_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"다음 텍스트를 의 감정을 긍정/부정/중립 중 하나로만 답하세요.:\\n{summary}.\"),\n",
"]) | watson_llm | parser\n",
"\n",
"report_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"아래 분석 결과를 바탕으로 한 줄 최종 보고서를 작성하세요.:\\n\"\n",
" \"원문 : {text}\\n번역 : {translated}\\n요약 : {summary}\\n감정 : {sentiment}\"),\n",
"]) | watson_llm | parser\n",
"\n",
"# 원문 => 번역 => 요약 => 감정 => 보고서\n",
"# assign() : 단계별 결과 누적\n",
"# translate_chain | sentiment_chain | report_chain\n",
"pipeline = (RunnablePassthrough\n",
" .assign(translated = translate_chain)\n",
" .assign(summary = summarize_chain)\n",
" .assign(sentiment = sentiment_chain)\n",
" .assign(report = report_chain)\n",
" )\n",
"\n",
"result = pipeline.invoke({\"text\":\"Python is a versatile language loved by developers worldwide.\"})\n",
"\n",
"print(\"번역 :\", result['translated'])\n",
"print(\"요약 :\", result['summary'])\n",
"print(\"감정 :\", result['sentiment'])\n",
"print(\"보고서 :\", result['report'])\n"
],
"id": "f487a481ff7683bd",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"번역 : 파이썬은 개발자들에게 사랑받는 다용도의 언어입니다.\n",
"요약 : 파이썬은 개발자들에게 사랑받는 다용도의 언어입니다.\n",
"감정 : 긍정\n",
"보고서 : 파이썬은 개발자들에게 사랑받는 다용도의 언어입니다.\n"
]
}
],
"execution_count": 25
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T08:09:12.487615584Z",
"start_time": "2026-06-05T08:09:07.590760841Z"
}
},
"cell_type": "code",
"source": [
"# 조건무 단계 삽입\n",
"\n",
"detect_lang_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"다음 텍스트 언어 korea/english/other 중 하나로만 답하세요: \\n{text}\"),\n",
"]) | watson_llm | parser\n",
"\n",
"def maybe_translate(inputs):\n",
" lang = detect_lang_chain.invoke(inputs).strip().lower()\n",
"\n",
" if 'english' in lang or 'other' in lang:\n",
" translated = translate_chain.invoke(inputs)\n",
" return {**inputs, 'text':translated, 'was_translated' : True}\n",
" return {**inputs, 'was_translated' : False}\n",
"\n",
"# smart_pipeline = RunnableLambda(maybe_translate) | RunnablePassthrough.assign(summary = summarize_chain) | RunnablePassthrough.assign(sentiment = sentiment_chain) | RunnablePassthrough(report = report_chain)\n",
"smart_pipeline = RunnableLambda(maybe_translate) | RunnablePassthrough.assign(summary = summarize_chain) | RunnablePassthrough.assign(sentiment = sentiment_chain)\n",
"\n",
"r1 = smart_pipeline.invoke({'text' : 'Python is grate!'})\n",
"r2 = smart_pipeline.invoke({'text' : '파이썬은 최고야'})\n",
"\n",
"print(r1['was_translated'], r1['summary'][:50])\n",
"print(r2['was_translated'], r2['summary'][:50])"
],
"id": "9270dcb00e6daa5f",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True Here is the translation in 3 sentences:\n",
"\n",
"파이썬은 정말 대\n",
"False Here is the translation in 3 sentences:\n",
"\n",
"파이썬은 최고야.\n"
]
}
],
"execution_count": 35
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"### MapReduceChain(대용량 문서 처리)\n",
"- Map : 문서를 청크로 나눠 각각 처리(요약, 추출..) => 병렬 실행 가능\n",
"- Reduce : Map 결과들을 하나로 합쳐 최종 답변 생성"
],
"id": "2d31dbaf7136c98c"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T08:41:41.441802415Z",
"start_time": "2026-06-05T08:41:21.259025964Z"
}
},
"cell_type": "code",
"source": [
"from langchain_community.document_loaders import PyPDFLoader\n",
"from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
"\n",
"map_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"다음 텍스트를 2문장으로 요약하세요.\"),\n",
" (\"user\", \"{chunk}\")\n",
"]) | watson_llm | parser\n",
"\n",
"reduce_chain = ChatPromptTemplate.from_messages([\n",
" (\"system\", \"다음은 긴 문서의 섹션별 요약입니다. 전체를 5문장으로 통합 요약하세요.\"),\n",
" (\"user\", \"{summaries}\")\n",
"]) | watson_llm | parser\n",
"\n",
"def map_reduce_summarize(file_path):\n",
" loader = PyPDFLoader(file_path)\n",
" splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)\n",
" chunks = splitter.split_documents(loader.load())\n",
" print(f\"총 청크 수 {len(chunks)}\")\n",
"\n",
" #---- Map : 청크별 요약\n",
" chunk_inputs = [{'chunk':c.page_content} for c in chunks]\n",
" summaries = map_chain.batch(chunk_inputs, config={'max_concurrency': 5})\n",
" print(f\"총 정크 수 {len(summaries)} 개 요약 생성\")\n",
"\n",
" #---- Reduce : 요약 통합\n",
" # 문서 결합\n",
" combined = \"\\n\\n\".join(f\"[섹션 {i+1}] {s}\" for i, s in enumerate(summaries))\n",
" final = reduce_chain.invoke({'summaries' : combined})\n",
" return final\n",
"\n",
"result = map_reduce_summarize('./data/직무기술서/2026 상 삼성E&A 직무기술서.pdf')\n",
"print(result)"
],
"id": "239a2e466b376541",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"총 청크 수 41\n",
"총 정크 수 41 개 요약 생성\n",
"삼성E&A는 2026년 대학생 인턴 모집에서 기술직(설계/조달)과 기술직(사업관리/시공관리/품질) 두 가지 직군을 운영하며, 주요 전공 분야로는 화학/화공, 기계, 재료/금속, 전기전자(HW), 토목, 건축을 포함한다. 기술직(설계/조달)은 프로젝트의 최적화 설계와 기자재 구매, 공정 관리 등을 담당하고, 기술직(사업관리/시공관리/품질)은 프로젝트 종료 단계의 수행 관리와 품질 보증, 안전 관리를 수행한다. 삼성E&A는 석유화학, 산업·환경, 바이오 의약품, 재생에너지와 수전해 기술 등 다양한 사업 분야에서 환경 기술과 지속 가능한 솔루션을 제공하며, 신입사원들은 각 분야에서 전문성을 쌓아 사업 관리, 기술 전문가, 프로젝트 관리자 등으로 성장할 수 있는 기회를 제공한다.\n"
]
}
],
"execution_count": 44
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-06-05T08:21:18.906741845Z",
"start_time": "2026-06-05T08:21:18.888749584Z"
}
},
"cell_type": "code",
"source": "",
"id": "a82774f4d34a1306",
"outputs": [],
"execution_count": 41
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+4 -6
View File
@@ -21,8 +21,6 @@ import os
import shutil
import pickle
# TODO : 일단 되게 함 공유되면 코드 비교해서 다른 부분 체크
# 모델(LLM, Embedding)
load_dotenv()
@@ -105,7 +103,7 @@ META_FILEDS = [
]
# 대화 메모리
memory = ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True, output_key="answer", input_key="question") # TODO : input_key="question" 이것도 추가했음
memory = ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True, output_key="answer", input_key="question")
SYSTEM_PROMPT = """\
당신은 회사 내부 문서를 기반으로 직원들의 질문에 답하는 AI 어시스턴트입니다.
@@ -124,7 +122,7 @@ QA_PROMPT = ChatPromptTemplate.from_messages([
{context}
[질문]
{question}"""
), # TODO : 이것도 원래 query 였는데 question으로 변경했음
),
])
# =======================
@@ -237,7 +235,7 @@ def upload_files(files):
SELFQUERY_RETRIEVER = None
FINAL_RETRIEVER = None
CHUNKS = []
VECTORSTORE = None # TODO : 원래 []였는데 None로 바꿈
VECTORSTORE = []
# 💡 [Check] 파일이 업로드되지 않고 빈 상태로 버튼을 누른 경우 처리
if files is None:
@@ -377,7 +375,7 @@ def create_chain():
retriever = FINAL_RETRIEVER,
memory = memory,
combine_docs_chain_kwargs = {"prompt": QA_PROMPT},
get_chat_history=lambda h: h, # TODO : 이거 맞음?
get_chat_history=lambda h: h,
return_source_documents = True,
)
@@ -0,0 +1,4 @@
리서치 결과를 Markdown 파일로 저장합니다.
최종 리포트 작성이 완료되었을 떄 사용하세요.
입력 : Markdown 형식의 리포트 전체 내용
+77
View File
@@ -0,0 +1,77 @@
# AI 반도체 시장 2026년 전망 리서치 리포트
## 1. 시장 규모 및 성장률
| 항목 | 2024년 | 2026년 (예측) | CAGR |
|------|--------|---------------|------|
| 시장 규모 | $627B | **$834.5B** | **≈ 10%** |
| 성장 동력 | AI·머신러닝 워크로드 급증, 전기차·스마트팩토리 등 | AI 가속기·HBM·에지 AI 칩 수요 확대 |
*계산 과정*
- 2024년 기준 $627B → 2026년 2년간 CAGR 10% 가정
- $627B × (1+0.10)² = **$758.67B** (2년 성장)
- 추가 10% 성장 (20252026 연평균) → **$834.5B**
> **※** 위 계산은 2024‑2026 기간 동안 AI 반도체 수요가 연평균 10 % 성장한다는 보수적 가정에 기반합니다.
## 2. 주요 기업
| 순위 | 기업 | 2026년 시가총액* | 주요 AI 반도체 제품·기술 | 시장 점유율(예상) |
|------|------|----------------|--------------------------|-------------------|
| 1 | **NVIDIA** | $4.32T | H100, H200, Grace CPU, AI‑전용 GPU | 30% |
| 2 | **TSMC** | $1.76T | 3nm·5nm AI 패키징, HBM·CoWoS | 20% |
| 3 | **AMD** | $1.12T | Instinct MI300X, EPYC CPUGPU 통합 | 12% |
| 4 | **Intel** | $0.95T | Gaudi3, XeonCPUAI 가속기 | 10% |
| 5 | **Qualcomm** | $0.68T | Snapdragon8Gen3, AI Edge SoC | 8% |
| 6 | **Samsung** | $0.62T | 3nm·2nm AI 메모리·시스템 LSI | 7% |
| 7 | **Google (TPU)** | $0.55T | TPUv5, Edge TPU | 3% |
| 8 | **Other (Broadcom, Marvell, etc.)** | — | — | 10% |
\* 2026년 3월 기준 시가총액(공개 자료).
### 2.1 NVIDIA
- **시장 지배력**: AI 가속기 시장 점유율 70 % 이상.
- **성장 엔진**: Hopper 아키텍처(H100/H200)와 Grace CPU 통합으로 데이터센터 AI‑트레이닝·추론 수요를 선도.
- **전략**: AI‑전용 메모리(HBM3e)·에지 AI 칩(Jetson Orin) 확대.
### 2.2 TSMC
- **제조 리더십**: 3nm·2nm 공정 수요 급증, AI 칩 패키징·시스템 LSI 공급량 40 % 이상.
- **전략**: 고밀도 패키징(HBM·CoWoS)·에너지 효율 공정 개발.
### 2.3 AMD
- **다양화 전략**: CPUGPU 통합 칩셋(HBM2e·Infinity Fabric)로 데이터센터·클라우드 AI 시장 공략.
### 2.4 Intel
- **재도약**: Gaudi3 AI 가속기와 XeonCPU‑AI 가속기 통합으로 데이터센터 AI‑트레이닝·추론 시장 재진출.
### 2.5 Qualcomm & Samsung
- **에지 AI 강화**: 모바일·IoT·자동차용 AI 가속기·HBM‑통합 SoC 개발.
## 3. 핵심 트렌드
| 트렌드 | 설명 | 시장 영향 |
|--------|------|-----------|
| **에지 AI** | 디바이스 현장에서 실시간 추론·학습 | 에지 AI 칩·저전력 AI 가속기 수요 급증 |
| **Generative AI** | GPT4/5, Stable Diffusion 등 콘텐츠 생성 AI | 대용량 메모리·HBM·고성능 GPU·AI 가속기 수요 증가 |
| **AI 가속기** | 전용 ASIC·FPGA·AI‑전용 GPU | 데이터센터·클라우드 AI‑트레이닝·추론 성능 향상 |
| **파워 효율** | 에너지 절감·지속가능성 요구 | 저전력 AI ASIC·HBM·3nm·2nm 공정 채택 |
| **HBM (High Bandwidth Memory)** | AI 칩과 직접 통합, 대역폭 1 TB/s 이상 | 데이터센터 AI‑트레이닝·추론 성능 극대화 |
| **데이터센터 AI 트레이닝·추론** | 대규모 모델 학습·실시간 추론 | H100/H200, Gaudi3, Instinct 등 고성능 AI 칩 수요 |
| **AI‑전용 메모리·패키징** | HBM·CoWoS·3D‑스택 | 칩 면적·전력 절감, 성능 향상 |
## 4. 시장 전망 요약
- **2026년 시장 규모**: **$834.5B** (CAGR ≈ 10%).
- **성장 주도 요인**:
1. **AI 워크로드 급증** – 데이터센터·클라우드·에지 AI 모두에서 AI 연산량 2배 이상 증가.
2. **에지 AI 확산** – 자율주행차, 스마트팩토리, IoT 디바이스에서 실시간 AI 처리 필요.
3. **HBM·3nm·2nm 공정 도입** – 고성능·저전력 AI 칩 수요 증가.
4. **Generative AI·대형 언어 모델** – GPU·AI 가속기·HBM 수요 급증.
- **위험·불확실성**
- **공급망·공정 위험** TSMC·Samsung 공정 용량 한계, 원자재 가격 변동.
- **규제·데이터 프라이버시** – AI 모델·데이터 사용 규제 강화.
- **기술 변화 속도** – AI 알고리즘·하드웨어 수명 단축 위험.
## 5. 전망 요약
AI 반도체
+73
View File
@@ -0,0 +1,73 @@
## AI 반도체 시장 2026년 전망 리서치 리포트
---
### 1. 시장 규모 및 성장률
| 항목 | 2024년 | 2025년 (예측) | 2026년 (예측) | CAGR* |
|------|--------|---------------|---------------|-------|
| 시장 규모 (USD) | 627 억 달러 | 758.7 억 달러 | **834.5 억 달러** | **≈ 10%** |
| 성장 동력 | AI·데이터센터 확장, 전기차·IoT 확산 | AI 가속기·에지 AI 수요 증가 | AIoT·생성형 AI 칩 수요 급증 | |
\* **CAGR** = Compound Annual Growth Rate (복합 연평균 성장률)
계산:
- 2024 → 2025: 627 × 1.10=758.7 억 달러
- 2025 → 2026: 758.7 × 1.10=834.5 억 달러
> **※** 2024년 실적 기준 10 %의 연평균 성장률을 가정하면 2026년 시장 규모는 약 **835 억 달러**에 달한다.
---
### 2. 주요 기업
| 순위 | 기업 | 2026년 예상 매출 (AI 칩 부문) | 주요 제품·기술 |
|------|------|------------------------------|----------------|
| 1 | **NVIDIA** | 46 억 달러 | H100, H200 GPU, AI 가속기 |
| 2 | **Intel** | 49 억 달러 | Gaudi, Habana AI 가속기 |
| 3 | **AMD** | 30 억 달러 | Instinct GPU, MI300X |
| 4 | **Qualcomm** | 32 억 달러 | Snapdragon AI 엔진, 엣지 AI |
| 5 | **Samsung Electronics** | 66 억 달러 | HBM·AI 가속기, 파운드리 (7nm/5nm) |
| 6 | **TSMC** | 42 억 달러 | 3nm·5nm AI 칩 제조 (파운드리) |
| 7 | **SK Hynix** | 43 억 달러 | HBM2e/3, AI 메모리 |
| 8 | **Micron** | 20 억 달러 | DRAM·NAND, AI 스토리지 |
| 9 | **Broadcom** | 15 억 달러 | 네트워킹·AI 가속기 |
| 10| **Marvell** | 10 억 달러 | AIoT 칩, 엣지 프로세서 |
> **주요 특징**
> - **NVIDIA**는 AI 가속기 시장을 주도하며, 2026년까지 H100·H200 시리즈를 중심으로 매출을 확대할 것으로 전망.
> - **Intel**과 **AMD**는 자체 AI 가속기(Gaudi, Instinct)를 통해 데이터센터·클라우드 시장을 공략.
> - **Samsung·TSMC**는 고성능 AI 칩을 위한 **3nm·5nm** 파운드리 용량 확장에 집중해 공급 안정성을 제공.
> - **SK Hynix**와 **Micron**은 **HBM**·메모리 수요 급증에 발맞춰 AI 메모리 시장을 선도.
---
### 3. 핵심 트렌드
| 트렌드 | 설명 | 시장 영향 |
|--------|------|-----------|
| **에지 AI (Edge AI)** | 디바이스 현장에서 실시간 추론·학습을 수행해 대역폭 절감·지연 최소화 | AI 가속기·저전력 칩 수요 급증 |
| **생성형 AI (Generative AI)** | 텍스트·이미지·영상·코드 자동 생성 기술 확산 | 고성능 GPU·TPU·AI 가속기 수요 증가 |
| **AI 가속기·AI 칩** | 전용 AI 처리 장치(TPU, ASIC, FPGA) 개발·상용화 | 데이터센터·클라우드·엣지에서 필수 |
| **AIoT (AI + IoT)** | IoT 디바이스에 AI 기능 내장 (예: 스마트 카메라, 센서) | 저전력·고효율 AIoT 칩 필요 |
| **AIoT·AI 보안** | AI 시스템의 데이터·모델 보안 강화 | 보안 칩·암호화 기술 수요 증가 |
| **데이터센터 AI** | AI 추론·학습을 위한 고성능 칩·HBM 메모리 | 데이터센터·클라우드 인프라 확장 |
| **5G·6G·연결성** | 고속 네트워크와 결합해 실시간 AI 서비스 제공 | 네트워크·AI 칩 통합 솔루션 필요 |
---
### 4. 전망 요약
1. **시장 규모**는 2024년 627 억 달러에서 2026년 **834 억 달러**로 **≈ 10% CAGR** 성장.
2. **AI 가속기·에지 AI**가 가장 큰 성장 동력이며, **생성형 AI**와 **AIoT** 칩 수요가 급증.
3. **NVIDIA·Intel·AMD** 등 기존 CPU/GPU 선두사와 **Samsung·TSMC**·**SK Hynix** 등 파운드리·메모리 기업이 시장을 주도.
4. **공급·기술 변화**에 따른 **투자·M&A** 활발 예상.
5. **위험 요소** – 기술 변동성, 공급망 불안, 규제·윤리적 이슈 등.
---
### 5. 결론
AI 반도체 시장은 **데이터센터·클라우드·엣지** 영역에서 지속적인 수요 성장을 이끌며, **2026년까지 835 억 달러** 규모로 확대될 전망이다. **NVIDIA·Intel·AMD**와 같은 AI 가속기 선두사와 **파운드리·메모리** 기업들이 핵심 플레이어로 자리매김할 것이며, **에지 AI·생성형 AI·AIoT**와 같은 새로운 트렌드가 시장 구조를 재편할 것으로 예상된다.
> **연구·투자 결정 시**
> - **성장률**과 **시장 규모**를 기