랭체인 코리아

팔로워 아이콘

팔로워80

대회 아이콘

주최대회0

팔로우
글쓰기
총 117

Agentic AI Meetup 25Q1 - Event Highlights 📸

Hello, everyone! This is Taeyoung Kim from LangChain Korea. 😄 Our LangChain Korea 2025Q1 Meetup on the theme of "Agentic AI" was a great success, with a total of 164 attendees (143 participants, 11 speakers, and 10 organizers & staff)! 🎉 This event focused on Agentic AI, a rising trend in the AI industry, covering: Single-agent systems, Multi-agent architectures, LangGraph, Various frameworks and real-world applications. A total of 11 expert speakers delivered sessions packed with practical insights and case studies that can be directly applied to real-world projects. 💡 Now, let's take a look at some highlights from the event! 📸🎬 Behind the Scenes: Getting Ready!📍 The meetup took place on the 13th floor of Microsoft Korea! The spacious venue, large screens, and well-arranged tables made it an ideal setting for presentations. ❄️ Despite the snowy weather across the country, many attendees traveled from afar to join us—thank you for your dedication! 🙏🎥 Special Message from LangChain Team's Jess!Jess from LangChain Team sent a special message celebrating our event! 🎊 She also shared the latest updates on the Interrupt(https://interrupt.langchain.com/). ✨ We truly appreciate the warm support from afar! 💙 💙 Consistent Support from Microsoft Korea & Space-S🎙️ Director Soyoung Lee from Microsoft Korea delivered a welcome speech! Fun fact: reserving an entire floor for an event requires months of preparation, and Microsoft's staff provided incredible support throughout the event! 👀 A huge thank you to Microsoft Korea for sponsoring our venue! 🙌 🚀 CEO Choongil Lee also shared inspiring words about building "Warm AI" through innovation. Thank you for your continued support!🏆 Exciting News! 🎉🥳 TeddyNote (Kyungrok Lee) has been officially appointed as a LangChain Ambassador! A huge congratulations! 👏👏👏📅 Session Schedule🔥 A non-stop, 6-hour knowledge-packed event from 3:00 PM to 9:00 PM! The dedication from our participants was truly inspiring. 💪 For the next meetup, we plan to include networking opportunities and a dinner break! 😆⏰ Session ListTimeSessionSpeaker15:00 - 15:25Building Multi-Agent Collaborative Networks with LangGraphKyungrok Lee (BrainCrew)15:30 - 15:55Building Agentic AI Systems with AssistWorksTaeyoung Kim (AI Factory)16:00 - 16:25Building Systems with PydanticAIJungjoon Heo (Engineer)16:30 - 16:55The Future of Search in the Agentic AI EraSeungyoon Baek (Engineer)17:00 - 17:25AI Collaboration Systems Using OpenAI SwarmHogan Seo (Korea Atomic Energy Research Institute)17:30 - 17:55Building an Agentic Search System: A Focus on Autonomy LevelsHoon Heo (Engineer)18:30 - 18:55The Future of Productivity with Agentic AIJiwon Seol (Engineer)19:00 - 19:25System Development with Microsoft Magentic-OneSeongjae Yoon (AI Consultant)19:30 - 19:55Building Agentic AI Systems with CrewAIJinhyung Lee (Engineer)20:00 - 20:25Building AI Systems with Copilot StudioHyunah Yoo (IT Content Creator)20:30 - 20:55Developing Multi-Agent Systems for Enterprises with AutoGenWonseok Jung (AI Researcher)15:00 ~ 15:25 Building Multi-Agent Collaborative Networks with LangGraph, Kyungrok Lee (BrainCrew)15:30 ~ 15:55 Building Agentic AI Systems with AssiWorks, Taeyoung Kim (AI Factory)16:00 ~ 16:25 Building Systems with PydanticAI, Jungjoon Heo (Engineer)16:30 ~ 16:55 The Future of Search in the Agentic AI Era, Seungyoon Baek (Engineer)17:00 ~ 17:25 AI Collaboration Systems Using OpenAI Swarm, Hogan Seo (Korea Atomic Energy Research Institute)17:30 ~ 17:55 Building an Agentic Search System: A Focus on Autonomy Levels, Hoon Heo (Engineer)18:30 ~ 18:55 The Future of Productivity with Agentic AI, Jiwon Seol (Engineer)19:00 ~ 19:25 System Development with Microsoft Magentic-One, Seongjae Yoon (AI Consultant)19:30 ~ 19:55 Building Agentic AI Systems with CrewAI, Jinhyung Lee (Engineer)20:00 ~ 20:25 Building AI Systems with Copilot Studio, Hyunah Yoo (IT Content Creator)20:30 ~ 20:55 Developing Multi-Agent Systems for Enterprises with AutoGen, Wonseok Jung (AI Researcher)🔥 The Unstoppable Passion of Our Participants!📚 From 3:00 PM to 9:00 PM, without breaks, fully focused on learning! Participants actively engaged in discussions, knowledge sharing, and deep dives into Agentic AI. For the next event, we will add networking and dinner breaks to make it even better! 😆 📸 Here’s a snapshot of our final “chain pose” of LangChain group photo! 📷💪 LangChain Korea Organizer Team🎤 A huge shoutout to the LangChain Korea organizers who planned, prepared, and managed this amazing event! 👏 (From left to right: Taeyoung Kim, Seoyeon Jang, Jiseok Lee, Hyunah Yoo, Mijeong Jeon) Thank you for making this possible! 💙 Please continue to support and engage with the LangChain Korea Community!🚀 Stay Tuned for the Next Meetup! We’ll be back with even more valuable content and networking opportunities! Thank you all, and see you next time! 🙌💙📢 Presentation Materials & Recorded Sessions 🎥📑We will soon share presentation slides and recorded videos with attendees! ⏳📩 Stay tuned for updates, and get ready to revisit the key insights from the event! 🚀✨

AIFactory_PR
0

에이전틱AI밋업25Q1 - 현장스케치📸

안녕하세요! 랭체인코리아의 김태영입니다. 😄 지난 랭체인코리아 2025Q1 밋업이 "에이전틱 AI"를 주제로 총 164명(참가자 143명, 연사 11명, 오거나이저 및 스태프 10명)이 모여 성황리에 마무리되었습니다! 🎉 이번 밋업에서는 최근 AI 업계에서 주목받고 있는 에이전틱 AI를 중심으로 진행되었으며, 단일 에이전트부터 멀티 에이전트 시스템과 다양한 프레임워크까지 폭넓게 다뤘습니다. 총 11명의 전문가가 각기 다른 세션에서 실무에서 바로 적용할 수 있는 기술과 다양한 사례를 공유해 주셨는데요.💡 함께 현장 스케치를 살펴볼까요? 📸🎬 준비하는 현장부터 시작!📍 이번 밋업 장소는 한국마이크로소프트 13층이었습니다! 넓고 쾌적한 공간 덕분에 긴 스크린과 넓은 책상이 마련되어 있어 발표 슬라이드를 보기에 최적이었어요. ❄️ 전국 곳곳에 눈이 내리는 날씨에도 멀리 지방에서 와주신 참가자분들께 진심으로 감사드립니다! 🙏🎥 LangChain Team의 Jess님 축전!LangChain Team의 Jess님께서 본 행사를 위해 축전을 보내주셨습니다! 🎊 또한, 최신 소식인 Interrupt 행사(https://interrupt.langchain.com/) 도 함께 소개해 주셨어요.✨ 이렇게 멀리서도 따뜻한 인사를 전해주셔서 감사드립니다! 💙 변함없는 후원: 한국마이크로소프트 & 대덕특구 Space-S🎙️ 마이크로소프트 이소영 이사님께서 환영 인사를 전해주셨습니다! 사실 한 층 전체를 예약하려면 몇 달 전부터 준비해야 하고, 행사 당일에도 마이크로소프트 직원분들의 서포트가 필요하다는 사실, 알고 계셨나요? 👀 매번 장소를 후원해 주시는 마이크로소프트에 다시 한번 감사드립니다. 🙌🚀 이충일 대표님께서 "따뜻한 AI"를 만들기 위한 메시지도 전해주셨습니다. 감사합니다!🏆 축하할 소식! 🎉🥳 테디노트(이경록)님께서 랭체인 공식 엠배서더로 선정되셨습니다! 이 자리를 빌려 진심으로 축하드립니다! 👏👏👏📅 세션 일정🔥 오후 3시부터 밤 9시까지, 6시간 논스톱 세션! 참가자분들의 열정이 정말 대단했는데요! 💪 다음 밋업에서는 네트워킹 및 저녁 시간도 마련해 보겠습니다. 😆⏰ Session List시간세션발표자15:00 ~ 15:25LangGraph를 활용한 멀티에이전트 협업 네트워크 시스템 구축이경록 (브레인크루)15:30 ~ 15:55어시웍스를 활용한 에이전틱 AI 시스템 구축김태영 (인공지능팩토리)16:00 ~ 16:25PydanticAI를 활용한 시스템 구축 방법허정준 (Engineer)16:30 ~ 16:55에이전틱 AI가 가져올 검색의 미래백승윤 (Engineer)17:00 ~ 17:25OpenAI Swarm을 활용한 AI 협업 시스템 구축서호건 (한국원자력연구원)17:30 ~ 17:55에이전틱 서치 시스템 구축 - 높아진 Autonomy Level을 중심으로허훈 (Engineer)18:30 ~ 18:55에이전틱 AI와 생산성의 미래설지원 (Engineer)19:00 ~ 19:25Microsoft Magentic-One을 활용한 시스템 구축윤성재 (AI 컨설턴트)19:30 ~ 19:55CrewAI를 활용한 에이전틱 AI 시스템 구축이진형 (Engineer)20:00 ~ 20:25Copilot Studio를 활용한 AI 시스템 구축유현아 (IT Content Creator)20:30 ~ 20:55AutoGen을 활용한 기업을 위한 멀티에이전트 구축정원석 (AI 연구원)15:00 ~ 15:25 LangGraph를 활용한 멀티에이전트 협업 네트워크 시스템 구축 (이경록, 브레인크루)15:30 ~ 15:55 어시웍스를 활용한 에이전틱AI 시스템 구축 (김태영, 인공지능팩토리)16:00 ~ 16:25 PydanticAI를 활용한 시스템 구축 방법 (허정준, Engineer)16:30 ~ 16:55 에이전틱 AI가 가져올 검색의 미래 (백승윤, Engineer)17:00 ~ 17:25 OpenAI Swarm를 활용한 AI 협업 시스템 구축 (서호건, 한국원자력연구원)17:30 ~ 17:55 에이전틱 서치 시스템 구축 | 높아진 Autonomy Level을 중심으로 (허훈, Engineer)18:30 ~ 18:55 에이전틱 AI와 생산성의 미래 (설지원, Engineer)19:00 ~ 19:25 Microsoft Magentic-One를 활용한 시스템 구축 (윤성재, AI 컨설턴트)19:30 ~ 19:55 CrewAI를 활용한 에이전틱AI 시스템 구축 (이진형 | Engineer)20:00 ~ 20:25 Copilot Studio를 활용한 AI 시스템 구축 (유현아, IT Content Creator)20:30 ~ 20:55 AutoGen를 활용한 기업을 위한 멀티에이전트 구축 (정원석, AI 연구원)🔥 참가자들의 열정, 그 자체!📚 오후 3시부터 밤 9시까지, 쉬는 시간 없이 풀 집중 모드! 모두가 열정적으로 지식을 공유하고, 배우고, 토론한 정말 뜻깊은 시간이었습니다! 다음에는 네트워킹 시간과 저녁 시간도 추가하겠습니다.😆 📸 마지막까지 남아 체인을 상징하는 포즈로 단체 사진도 찍었습니다! 📷💪 랭체인코리아 오거나이저 팀🎤 본 행사를 사전에 기획, 준비, 운영한 랭체인코리아 오거나이저 팀(왼쪽부터 김태영, 장서연, 이지석, 유현아, 전미정)입니다! 👏 앞으로도 랭체인코리아 커뮤니티에 많은 관심과 사랑 부탁드립니다!📢 다음 밋업도 기대해 주세요! 🚀더욱 유익한 콘텐츠와 네트워킹 기회로 다시 찾아뵙겠습니다! 감사합니다! 🙌💙📢 발표자료 및 녹화영상 안내 🎥📑조만간 참가자분들에게 발표자료 및 녹화영상에 대한 안내가 나갈 예정이니 기다려주세요! ⏳📩 잊지 않고 공유해 드릴 테니 많은 기대 부탁드립니다! 🚀✨

AIFactory_PR
1

[발표자료] Copilot Studio를 활용한 에이전틱AI 시스템 구축

Copilot Studio를 활용한 에이전틱AI 시스템 구축 발표자료입니다.

현아
1

Function Calling 연쇄 호출 테스트

OpenAI의 ChatCompletion API에서 Function Calling(함수 호출) 기능을 통해 모델이 스스로 적절한 함수를 선택하고, 필요한 인자를 구성하여 호출할 수 있게 되었습니다. 기존에는 모델의 답변을 파싱하여 사용자가 직접 “필요한 정보를 추출”하곤 했지만, 이제는 모델이 명시적으로 “특정 함수”를 호출하고, 그 결과를 받아 다음 문맥에 활용할 수 있습니다.이 글에서는 a부터 z까지 총 26개의 함수가 서로 의존성을 갖는 예시를 통해, Function Calling을 어떻게 구성할 수 있는지 살펴보겠습니다. 각 함수는 이전 함수가 만들어낸 “토큰”을 입력받아 새로운 “토큰”을 생성하고, 마지막에 a_func가 최종 결과를 만들어내는 구조입니다.1. 시나리오: a_func를 호출하기 위해 z_func부터 차례대로 호출예시 상황은 다음과 같습니다.z_func: 의존성이 전혀 없는 함수. 내부적으로 "z"라는 토큰을 만듦y_func: z_token을 받아서 "y" + z_token을 리턴x_func: y_token → "x" + y_token…b_func: c_token → "b" + c_tokena_func: b_token → "a" + b_token (최종 결과)사용자는 “A 함수를 호출해”라고만 말해도, 모델은 z_func → y_func → x_func → ... → b_func → a_func 순으로 호출해야 한다는 사실을 인식하고, 중간 단계 함수들을 모두 호출할 수 있습니다.2. 전체 예시 코드아래 코드에서는:z_func ~ a_func: 파이썬 상의 실제 함수들(문자열을 이어붙이는 단순 예시)tools: OpenAI에 노출할 함수의 정의(각 함수 이름, 설명, 파라미터 스키마)toolkits: 함수 이름과 실제 파이썬 함수의 매핑openai_llm(...): ChatCompletion API를 호출하고, 모델이 함수 호출을 요청하면 실제로 파이썬 함수를 실행하여 결과를 다시 모델에게 전달(while 루프로 재시도)코드 전문<code class="language-python"># -*- coding: utf-8 -*- """ function_calling_demo.py OpenAI의 Function Calling 기능을 활용해, a_func부터 z_func까지 26개의 함수가 서로 의존성을 가지도록 구성한 예시 코드. '도구(tools)' 정의를 통해 모델이 필요할 때 각 함수를 호출하고, 함수 결과를 다시 모델에 전달하는 과정을 반복하여 최종 값을 얻는다. """ from openai import OpenAI import requests import json import yfinance as yf ######################################## # 1. OpenAI 클라이언트 초기화 ######################################## client = OpenAI( api_key="sk-p..." ) ######################################## # 2. a~z 함수 정의 # - z_func: 의존성 없는 가장 기초 # - y_func: z_token 필요 # - ... # - a_func: b_token 필요(최종) # # 실제 로직(토큰 생성 등)은 단순히 문자열을 이어붙이는 것으로 예시 구성 ######################################## def z_func(): """z_func: 의존성 없음, 결과로 'z'를 리턴""" return "z" def y_func(z_token): """y_func: z_token -> 'y' + z_token""" return "y" + z_token def x_func(y_token): """x_func: y_token -> 'x' + y_token""" return "x" + y_token def w_func(x_token): """w_func: x_token -> 'w' + x_token""" return "w" + x_token def v_func(w_token): """v_func: w_token -> 'v' + w_token""" return "v" + w_token def u_func(v_token): """u_func: v_token -> 'u' + v_token""" return "u" + v_token def t_func(u_token): """t_func: u_token -> 't' + u_token""" return "t" + u_token def s_func(t_token): """s_func: t_token -> 's' + t_token""" return "s" + t_token def r_func(s_token): """r_func: s_token -> 'r' + s_token""" return "r" + s_token def q_func(r_token): """q_func: r_token -> 'q' + r_token""" return "q" + r_token def p_func(q_token): """p_func: q_token -> 'p' + q_token""" return "p" + q_token def o_func(p_token): """o_func: p_token -> 'o' + p_token""" return "o" + p_token def n_func(o_token): """n_func: o_token -> 'n' + o_token""" return "n" + o_token def m_func(n_token): """m_func: n_token -> 'm' + n_token""" return "m" + n_token def l_func(m_token): """l_func: m_token -> 'l' + m_token""" return "l" + m_token def k_func(l_token): """k_func: l_token -> 'k' + l_token""" return "k" + l_token def j_func(k_token): """j_func: k_token -> 'j' + k_token""" return "j" + k_token def i_func(j_token): """i_func: j_token -> 'i' + j_token""" return "i" + j_token def h_func(i_token): """h_func: i_token -> 'h' + i_token""" return "h" + i_token def g_func(h_token): """g_func: h_token -> 'g' + h_token""" return "g" + h_token def f_func(g_token): """f_func: g_token -> 'f' + g_token""" return "f" + g_token def e_func(f_token): """e_func: f_token -> 'e' + f_token""" return "e" + f_token def d_func(e_token): """d_func: e_token -> 'd' + e_token""" return "d" + e_token def c_func(d_token): """c_func: d_token -> 'c' + d_token""" return "c" + d_token def b_func(c_token): """b_func: c_token -> 'b' + c_token""" return "b" + c_token def a_func(b_token): """a_func: b_token -> 'a' + b_token (최종)""" return "a" + b_token ############################################## # 3. tools 정의 (Function Calling용 스키마) # - a~z 모든 함수를 등록하고, 각 함수에 필요한 인자와 설명을 JSON Schema로 표시 ############################################## tools = [ { "type": "function", "function": { "name": "z_func", "description": ( "Z 함수: 의존성이 없는 가장 기초 함수. 결과값으로 z_token을 " "생성한다고 가정. 다른 많은 함수들이 z_token을 필요로 할 수 있음." ), "parameters": { "type": "object", "properties": { # z_func는 인자가 없음 }, "required": [] }, }, }, { "type": "function", "function": { "name": "y_func", "description": ( "Y 함수: z_token이 필요. z_func의 결과로부터 z_token을 받아서 " "y_token을 생성한다고 가정." ), "parameters": { "type": "object", "properties": { "z_token": { "type": "string", "description": "z_func 호출 결과로 얻은 토큰" } }, "required": ["z_token"] }, }, }, { "type": "function", "function": { "name": "x_func", "description": ( "X 함수: y_token이 필요. y_func의 결과로부터 y_token을 받아서 " "x_token을 생성한다고 가정." ), "parameters": { "type": "object", "properties": { "y_token": { "type": "string", "description": "y_func 호출 결과로 얻은 토큰" } }, "required": ["y_token"] }, }, }, { "type": "function", "function": { "name": "w_func", "description": "W 함수: x_token 필요, 결과로 w_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "x_token": { "type": "string", "description": "x_func 호출 결과로 얻은 토큰" } }, "required": ["x_token"] }, }, }, { "type": "function", "function": { "name": "v_func", "description": "V 함수: w_token 필요, 결과로 v_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "w_token": { "type": "string", "description": "w_func 호출 결과로 얻은 토큰" } }, "required": ["w_token"] }, }, }, { "type": "function", "function": { "name": "u_func", "description": "U 함수: v_token 필요, 결과로 u_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "v_token": { "type": "string", "description": "v_func 호출 결과로 얻은 토큰" } }, "required": ["v_token"] }, }, }, { "type": "function", "function": { "name": "t_func", "description": "T 함수: u_token 필요, 결과로 t_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "u_token": { "type": "string", "description": "u_func 호출 결과로 얻은 토큰" } }, "required": ["u_token"] }, }, }, { "type": "function", "function": { "name": "s_func", "description": "S 함수: t_token 필요, 결과로 s_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "t_token": { "type": "string", "description": "t_func 호출 결과로 얻은 토큰" } }, "required": ["t_token"] }, }, }, { "type": "function", "function": { "name": "r_func", "description": "R 함수: s_token 필요, 결과로 r_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "s_token": { "type": "string", "description": "s_func 호출 결과로 얻은 토큰" } }, "required": ["s_token"] }, }, }, { "type": "function", "function": { "name": "q_func", "description": "Q 함수: r_token 필요, 결과로 q_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "r_token": { "type": "string", "description": "r_func 호출 결과로 얻은 토큰" } }, "required": ["r_token"] }, }, }, { "type": "function", "function": { "name": "p_func", "description": "P 함수: q_token 필요, 결과로 p_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "q_token": { "type": "string", "description": "q_func 호출 결과로 얻은 토큰" } }, "required": ["q_token"] }, }, }, { "type": "function", "function": { "name": "o_func", "description": "O 함수: p_token 필요, 결과로 o_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "p_token": { "type": "string", "description": "p_func 호출 결과로 얻은 토큰" } }, "required": ["p_token"] }, }, }, { "type": "function", "function": { "name": "n_func", "description": "N 함수: o_token 필요, 결과로 n_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "o_token": { "type": "string", "description": "o_func 호출 결과로 얻은 토큰" } }, "required": ["o_token"] }, }, }, { "type": "function", "function": { "name": "m_func", "description": "M 함수: n_token 필요, 결과로 m_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "n_token": { "type": "string", "description": "n_func 호출 결과로 얻은 토큰" } }, "required": ["n_token"] }, }, }, { "type": "function", "function": { "name": "l_func", "description": "L 함수: m_token 필요, 결과로 l_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "m_token": { "type": "string", "description": "m_func 호출 결과로 얻은 토큰" } }, "required": ["m_token"] }, }, }, { "type": "function", "function": { "name": "k_func", "description": "K 함수: l_token 필요, 결과로 k_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "l_token": { "type": "string", "description": "l_func 호출 결과로 얻은 토큰" } }, "required": ["l_token"] }, }, }, { "type": "function", "function": { "name": "j_func", "description": "J 함수: k_token 필요, 결과로 j_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "k_token": { "type": "string", "description": "k_func 호출 결과로 얻은 토큰" } }, "required": ["k_token"] }, }, }, { "type": "function", "function": { "name": "i_func", "description": "I 함수: j_token 필요, 결과로 i_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "j_token": { "type": "string", "description": "j_func 호출 결과로 얻은 토큰" } }, "required": ["j_token"] }, }, }, { "type": "function", "function": { "name": "h_func", "description": "H 함수: i_token 필요, 결과로 h_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "i_token": { "type": "string", "description": "i_func 호출 결과로 얻은 토큰" } }, "required": ["i_token"] }, }, }, { "type": "function", "function": { "name": "g_func", "description": "G 함수: h_token 필요, 결과로 g_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "h_token": { "type": "string", "description": "h_func 호출 결과로 얻은 토큰" } }, "required": ["h_token"] }, }, }, { "type": "function", "function": { "name": "f_func", "description": "F 함수: g_token 필요, 결과로 f_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "g_token": { "type": "string", "description": "g_func 호출 결과로 얻은 토큰" } }, "required": ["g_token"] }, }, }, { "type": "function", "function": { "name": "e_func", "description": "E 함수: f_token 필요, 결과로 e_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "f_token": { "type": "string", "description": "f_func 호출 결과로 얻은 토큰" } }, "required": ["f_token"] }, }, }, { "type": "function", "function": { "name": "d_func", "description": "D 함수: e_token 필요, 결과로 d_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "e_token": { "type": "string", "description": "e_func 호출 결과로 얻은 토큰" } }, "required": ["e_token"] }, }, }, { "type": "function", "function": { "name": "c_func", "description": "C 함수: d_token 필요, 결과로 c_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "d_token": { "type": "string", "description": "d_func 호출 결과로 얻은 토큰" } }, "required": ["d_token"] }, }, }, { "type": "function", "function": { "name": "b_func", "description": "B 함수: c_token 필요, 결과로 b_token을 만든다고 가정.", "parameters": { "type": "object", "properties": { "c_token": { "type": "string", "description": "c_func 호출 결과로 얻은 토큰" } }, "required": ["c_token"] }, }, }, { "type": "function", "function": { "name": "a_func", "description": ( "A 함수: b_token이 필요. b_func 호출 결과로 b_token을 받고, " "최종 결과를 생성한다고 가정." ), "parameters": { "type": "object", "properties": { "b_token": { "type": "string", "description": "b_func 호출 결과로 얻은 토큰" } }, "required": ["b_token"] }, }, } ] ############################################## # 4. 실제 Python 함수(코드)와 tool name 매핑 ############################################## toolkits = { "z_func": z_func, "y_func": y_func, "x_func": x_func, "w_func": w_func, "v_func": v_func, "u_func": u_func, "t_func": t_func, "s_func": s_func, "r_func": r_func, "q_func": q_func, "p_func": p_func, "o_func": o_func, "n_func": n_func, "m_func": m_func, "l_func": l_func, "k_func": k_func, "j_func": j_func, "i_func": i_func, "h_func": h_func, "g_func": g_func, "f_func": f_func, "e_func": e_func, "d_func": d_func, "c_func": c_func, "b_func": b_func, "a_func": a_func, } ######################################## # 5. 시스템 메시지 # - 모델에게 "알아서 필요한 함수는 호출하라" 고 지시 ######################################## system_prompt = """ You are a helpful assistant. Write in Korean. You have access to the following tools. If the user asks for something that requires calling a function, call it with the correct arguments. Otherwise, respond directly in natural language. """ ######################################## # 6. 대화(챗) + 함수 호출 로직 ######################################## def openai_llm(user_input, chat_history): """ - chat_history에 대화 내용(system, user, assistant, tool 등)을 순차적으로 기록 - 모델에게 질의 후, 만약 tool_calls가 있으면 해당 함수를 실제로 호출하고, 그 결과를 tool 메시지로 추가 - 다시 모델에게 재요청을 반복하여, 함수 호출이 더 이상 없을 때 최종 답변을 반환 """ # 최초 대화에 system 메시지를 넣음 if len(chat_history) == 0: chat_history.append({"role": "system", "content": system_prompt}) # 사용자 메시지를 추가 chat_history.append({"role": "user", "content": user_input}) # 함수 호출이 없을 때까지 반복 while True: # 1) OpenAI ChatCompletion 요청 completion = client.chat.completions.create( model="gpt-4o", # 예시 모델 messages=chat_history, tools=tools ) # 모델이 생성한 assistant 메시지를 획득 assistant_msg = completion.choices[0].message # assistant_msg를 대화 기록에 추가 chat_history.append(assistant_msg) # 2) 모델이 함수 호출을 했는지 (tool_calls) 확인 if not hasattr(assistant_msg, "tool_calls") or not assistant_msg.tool_calls: # 함수 호출이 없으면 일반 답변으로 간주, while 종료 break # 3) 함수 호출이 있을 경우 -> 실제 파이썬 함수를 호출 for tool_call in assistant_msg.tool_calls: fn_name = tool_call.function.name fn_args_str = tool_call.function.arguments # 함수 인자를 JSON 디코딩 fn_args = json.loads(fn_args_str) if fn_args_str else {} print(fn_name, fn_args_str) # 디버그 출력 (어떤 함수가 어떻게 호출되는지) # 실제 함수 실행 result = toolkits[fn_name](**fn_args) # 실행 결과를 role="tool" 메시지로 추가 tool_message = { "role": "tool", "tool_call_id": tool_call.id, "content": result } chat_history.append(tool_message) # 4) tool 메시지를 추가한 뒤, while 루프를 반복하여 # 모델이 다시 한 번(또는 여러 번) 함수 호출할지 확인 # 없으면 break # 함수 호출이 없을 때(while 탈출 시), 최종적으로 assistant_msg.content 리턴 return assistant_msg.content ######################################## # 7. 실행 예시 ######################################## if __name__ == "__main__": # 첫 테스트: "A 함수를 호출해"라고 요청해보기 # 모델이 z부터 b까지 차례로 호출 후 최종적으로 a_func를 호출하는지 확인 answer = openai_llm("A 함수를 호출해", []) print("A I >", answer) # 대화 루프 예시 # - 사용자가 원하는 요청을 입력하면, 모델이 # 필요한 함수를 순차적으로 호출할 수 있음 chat_history = [] while True: user_input = input("\nUSER> ") if user_input.lower() == "quit": break ai_response = openai_llm(user_input, chat_history) print(f"A I> {ai_response}")</code>3. 동작 확인예시로, “A 함수를 호출해”라고 입력하면, 콘솔에 함수 호출 과정이 순서대로 찍히고, 최종적으로 “a_func”가 호출된 결과(문자열 "abcdefghijklmnopqrstuvwxyz" 등)가 출력됩니다. 실제로는 모델이 단계마다 z_func를 호출하여 "z" 토큰을 만들고, y_func(z_token="z")를 호출해 "yz"를 만든 뒤, x_func(y_token="yz")를 호출해 "xyz" … 이런 식으로 중간 함수 결과를 축적합니다.콘솔 로그:4. 정리 및 활용 아이디어Function Calling을 통해, 단순 “모델 출력 파싱” 과정을 자동화복잡한 함수 간 의존이 있어도, 모델이 “먼저 필요한 정보를 얻기 위한 함수 → 후속 함수” 순으로 여러 번 호출 가능실제로는 사내 API, DB, 외부 API 등을 호출하여 다양한 작업을 수행할 수 있음함수 개수가 많을수록(10~20개 이상) 모델이 올바른 함수를 찾기 어려울 수 있으므로, 함수명을 직관적으로 지어주고, 시스템 메시지나 함수 description에서 활용 맥락을 자세히 안내해주면 좋습니다.이로써, 서로 의존관계를 가지는 다수의 함수를 OpenAI Function Calling으로 유연하게 구성하는 방법을 살펴봤습니다. ReferenceOpenAI Function Calling 문서OpenAI Cookbook: How to call functions with chat models

AF 김태영
0

LangGraph #4 - Memory Chatbot

이 글에서는 LangGraph 라이브러리의 체크포인트 기능을 이용해, 사용자별로 대화 맥락을 유지할 수 있는 챗봇을 구현해보겠습니다. Anthropic Claude 모델을 활용하여 자연스럽게 대화를 이어가면서, thread_id를 통해 서로 다른 사용자의 대화를 독립적으로 관리하는 방법을 시연합니다.1. 배경: 왜 멀티턴 메모리가 필요한가?지금까지 단순 챗봇을 구성해본 분들은, 한 번의 질의-응답 이후 맥락이 사라지거나, 프로그램이 재시작되면 이전 대화 내용을 잊어버리는 문제를 종종 겪었을 것입니다.예:“내 이름이 홍길동이야” → “반갑습니다, 홍길동님”…(대화 종료 후) 다시 시작하면 홍길동이라는 사실을 잊어버림.LangGraph는 이런 문제를 해결하기 위해 **체크포인트(Checkpoint)**라는 개념을 도입했습니다. 체크포인트는 노드가 실행된 후의 상태(State)를 자동으로 저장해두고, 동일 thread_id로 그래프를 다시 호출하면 그 상태를 자동 로드하여 이어갈 수 있도록 해줍니다.2. 코드 예시다음 코드를 ch4_memory_chatbot.py라 하고, python ch4_memory_chatbot.py로 실행하면 됩니다.<code class="language-plaintext">import os # Anthropic Claude from langchain_anthropic import ChatAnthropic # LangGraph 핵심 from langgraph.graph import StateGraph, START from langgraph.graph.message import add_messages # 체크포인트 from langgraph.checkpoint.memory import MemorySaver # (DB 사용 시 SqliteSaver, PostgresSaver 등 사용 가능) from typing import Annotated from typing_extensions import TypedDict ############################################################################### # 1) 상태(State) 정의 ############################################################################### class State(TypedDict): messages: Annotated[list, add_messages] ############################################################################### # 2) 그래프 빌더 생성 ############################################################################### graph_builder = StateGraph(State) ############################################################################### # 3) LLM ############################################################################### llm = ChatAnthropic( model="claude-3-5-sonnet-20241022", anthropic_api_key=os.environ.get("ANTHROPIC_API_KEY") ) def chatbot_node(state: State): """ state["messages"]를 LLM에게 전달하고, 새 AI 응답을 반환. """ ai_resp = llm.invoke(state["messages"]) return {"messages": [ai_resp]} # 노드 등록 graph_builder.add_node("chatbot", chatbot_node) # START -> chatbot graph_builder.add_edge(START, "chatbot") ############################################################################### # 4) 체크포인터 설정 ############################################################################### memory = MemorySaver() ############################################################################### # 5) 그래프 컴파일 ############################################################################### # compile(...) 시 checkpointer 지정 graph = graph_builder.compile(checkpointer=memory) ################################################################################ # 그래프 시각화를 위한 ASCII 아트 생성 ################################################################################ # - graph.get_graph().draw_ascii()를 호출하여 그래프 구조를 ASCII 아트로 표현 # - 노드와 엣지의 연결 관계를 시각적으로 보여줌 ascii_graph = graph.get_graph().draw_ascii() print(ascii_graph) ############################################################################### # 6) 메인 함수 ############################################################################### def main(): print("==== [ch4] Memory/Checkpoint Demo ====") print("Type 'quit' or 'q' to exit.\n") # 각 유저별 thread_id를 가정 thread_id = input("Enter thread_id (e.g., 'user1'): ").strip() or "default" while True: user_input = input(f"(thread={thread_id}) You: ") if user_input.lower() in ["quit", "q"]: print("Goodbye!") break # graph 실행: # (1) input: {"messages": [("user", user_input)]} # (2) config: {"configurable": {"thread_id": thread_id}} # => LangGraph가 thread_id='...' 체크포인트 상태를 로드 & 업데이트 events = graph.stream( {"messages": [("user", user_input)]}, {"configurable": {"thread_id": thread_id}}, ) # 실행 중 생기는 event를 출력 for event in events: for node_out in event.values(): if "messages" in node_out: last_msg = node_out["messages"][-1] print("Assistant:", last_msg.content) if __name__ == "__main__": main()</code>3. 코드 흐름 분석State(TypedDict) 정의<code class="language-python">class State(TypedDict): messages: Annotated[list, add_messages]</code>챗봇 대화에는 사용자 메시지와 AI(Claude) 메시지를 순서대로 저장하는 messages 리스트가 필요합니다.add_messages를 사용하면 새 메시지를 추가할 때마다 기존 리스트에 “append” 방식으로 쌓입니다.그래프 빌더(StateGraph)graph_builder = StateGraph(State)로 그래프 설계자(Builder)를 생성합니다.노드와 엣지를 등록한 뒤 compile하여 실행 가능한 그래프 객체를 만들어냅니다.LLM 노드(chatbot_node)<code class="language-python">def chatbot_node(state: State): ai_resp = llm.invoke(state["messages"]) return {"messages": [ai_resp]}</code>state["messages"]를 Anthropic Claude에 전달해 새 AI 응답을 생성하는 노드입니다.반환되는 AI 메시지가 messages 리스트에 append되어 대화 내역이 누적됩니다.체크포인터(MemorySaver)<code class="language-python">memory = MemorySaver() graph = graph_builder.compile(checkpointer=memory)</code>이 설정 덕분에 LangGraph가 노드 실행 때마다 상태(State)를 memory에 저장합니다.만약 동일한 thread_id로 다시 그래프를 실행하면, 이전에 저장된 상태를 자동 로드해 여러 턴 대화를 이어갈 수 있습니다.메인 함수thread_id를 입력 받음: 예) user1사용자 메시지를 graph.stream(...)으로 전달할 때,로 지정하면 LangGraph가 해당 스레드의 상태를 로드/업데이트합니다.<code class="language-python">{"configurable": {"thread_id": thread_id}}</code>4. 실행 예시한 터미널에서:<code class="language-plaintext">$ python ch4_memory_chatbot.py +-----------+ | __start__ | +-----------+ * * * +---------+ | chatbot | +---------+ ==== [ch4] Memory/Checkpoint Demo ==== Type 'quit' or 'q' to exit. Enter thread_id (e.g., 'user1'): userA (thread=userA) You: 안녕 Assistant: 안녕하세요! 무엇을 도와드릴까요? (thread=userA) You: 내 이름은 길동이야 Assistant: 길동님, 만나서 반갑습니다. ... </code>또 다른 터미널에서:<code class="language-plaintext">$ python ch4_memory_chatbot.py ==== [ch4] Memory/Checkpoint Demo ==== Type 'quit' or 'q' to exit. Enter thread_id (e.g., 'user1'): userB (thread=userB) You: 안녕, 난 영희야 Assistant: 영희님, 안녕하세요!</code>코드 복사userA와 userB는 서로 다른 thread_id로 대화를 유지하므로, 서로의 대화가 섞이지 않고 독립된 맥락을 이어갑니다.만약 같은 thread_id로 접속하면, LangGraph는 “이전에 저장된 State가 있다”고 보고 과거 메시지를 이어서 참조합니다(프로세스를 종료하기 전까지).5. 확장 아이디어SqliteSaver / PostgresSaverMemorySaver는 파이썬 프로세스를 종료하면 저장된 상태가 사라집니다.SqliteSaver나 PostgresSaver를 쓰면 DB에 저장되므로, 프로그램을 재시작해도 동일 thread_id의 대화를 이어갈 수 있습니다.복수 노드(툴 등) 결합ch2, ch3처럼 툴(검색, DB 조회) 노드를 추가하면, 사용자별로 검색 내역도 messages에 누적되어 “이전에 검색했던 내용”까지 기억하는 챗봇이 됩니다.Human-in-the-loop특정 노드 실행 전/후에 interrupt_before/interrupt_after를 설정해, “사람이 승인해야 다음 단계로 진행”처럼 구현할 수도 있습니다.이때도 체크포인트가 있어야, 중간에 멈췄다가 몇 분/몇 시간 뒤에 다시 재개 가능합니다.마무리이상으로, LangGraph의 체크포인트 기능을 활용해 여러 턴 대화(멀티턴)와 사용자별(thread_id 기반) 대화 맥락 유지를 구현하는 방법을 살펴봤습니다.핵심 포인트:State에 messages 리스트를 넣어두고,compile(checkpointer=...)로 그래프 실행 결과를 저장,graph.stream(..., {"configurable": {"thread_id": "..."}})로 이전 기록을 로드.이를 통해 간단히 사용자별 맞춤형 기억을 유지할 수 있으며, 좀 더 고도화하면 DB 연동으로 서버 재시작에도 대화 이력이 남도록 만들 수 있습니다.

AF 김태영
0

LangGraph #3 - Chatbot with Tools using CustomNode

ch1에서는 LangGraph를 사용한 기본 챗봇을, ch2에서는 특정 상황에서 도구(검색 엔진)를 자동 호출하는 흐름을 살펴봤습니다. 하지만, ch2에서 우리는 LangGraph가 미리 만들어놓은 ToolNode & tools_condition 을 그대로 썼죠. 이번 ch3에서는 이러한 편의 기능을 직접 구현해봄으로써, LangGraph의 노드 정의와 조건부 라우팅(conditional_edges)을 보다 깊이 이해해보겠습니다.1. 준비 사항가상환경 & 패키지 설치<code class="language-plaintext">python -m venv .venv source .venv/bin/activate pip install -U langgraph langsmith langchain_anthropic tavily-python langchain_community</code>API Key 설정Anthropic: export ANTHROPIC_API_KEY="..."Tavily: export TAVILY_API_KEY="..."기본 개념LangGraph에서 노드(Node) 는 파이썬 함수(또는 객체의 __call__)로 구현되며,“START -> (여러 노드) -> END” 형태의 흐름을 edges로 연결한다.conditional_edges를 통해 조건부 분기를 제어할 수 있다.3. 전체 코드아래 예시는 Anthropic Claude와 TavilySearchResults를 연동한 LangGraph 챗봇으로, LLM이 “검색이 필요하다”고 판단할 때, 직접 만든 BasicToolNode가 실행되어 웹 검색을 수행합니다.<code class="language-python">import os import json # Anthropic Claude from langchain_anthropic import ChatAnthropic # LangGraph from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages # Tavily 검색 툴 (웹 검색) from langchain_community.tools.tavily_search import TavilySearchResults # typing from typing import Annotated from typing_extensions import TypedDict # langchain-core에서 ToolMessage (툴 호출 결과를 담아 LLM에 전달하기 위함) from langchain_core.messages import ToolMessage ############################################################################### # 1) 상태(State) 정의 ############################################################################### class State(TypedDict): # messages: 사용자/AI 메시지를 누적 저장 messages: Annotated[list, add_messages] ############################################################################### # 2) 그래프 빌더 생성 ############################################################################### graph_builder = StateGraph(State) ############################################################################### # 3) LLM 및 툴 초기화 ############################################################################### # - TavilySearchResults: 검색어를 넣으면 JSON 형식으로 결과 반환 search_tool = TavilySearchResults( max_results=2, tavily_api_key=os.environ.get("TAVILY_API_KEY") # 환경변수에서 가져오기 ) # - Anthropic Claude llm = ChatAnthropic( model="claude-3-5-sonnet-20240620", anthropic_api_key=os.environ.get("ANTHROPIC_API_KEY") ) # - LLM에 툴 목록을 "bind"하여, # LLM이 tool_calls(JSON) 형태로 특정 툴을 호출할 수 있음 llm_with_tools = llm.bind_tools([search_tool]) ############################################################################### # 4) 노드: chatbot ############################################################################### def chatbot_node(state: State): """ 1) state["messages"]를 LLM에게 전달 2) LLM이 필요 시 tool_calls를 생성 (search_tool 등) 3) 새 메시지를 반환 -> LangGraph가 append """ ai_resp = llm_with_tools.invoke(state["messages"]) return {"messages": [ai_resp]} ############################################################################### # 5) 노드: BasicToolNode (직접 구현) ############################################################################### # - LangGraph가 기본 제공하는 ToolNode가 아니라, # LLM이 호출하겠다고 선언한 tool_calls를 직접 처리하는 로직 class BasicToolNode: """ LLM의 마지막 메시지에 tool_calls가 있으면, 그에 따라 실제 툴을 실행하고 ToolMessage를 생성한다. """ def __init__(self, tools: list): # tools_by_name = {툴_이름: 툴_인스턴스} self.tools_by_name = {t.name: t for t in tools} def __call__(self, inputs: dict): # inputs에는 "messages" 리스트가 들어있음 if messages := inputs.get("messages", []): last_msg = messages[-1] # 가장 최근 AI 메시지 else: raise ValueError("No messages found in input.") outputs = [] # AI 메시지에 tool_calls가 있는지 확인 if hasattr(last_msg, "tool_calls"): for call_info in last_msg.tool_calls: tool_name = call_info["name"] args = call_info["args"] # 툴 이름에 맞춰 실제 invoke if tool_name in self.tools_by_name: result = self.tools_by_name[tool_name].invoke(args) # 검색 결과(등등)를 ToolMessage 형태로 담아 반환 # -> chatbot 노드에서 이어받아 최종 답변에 활용 outputs.append( ToolMessage( content=json.dumps(result), name=tool_name, tool_call_id=call_info["id"], ) ) return {"messages": outputs} ############################################################################### # 6) 노드 등록 ############################################################################### graph_builder.add_node("chatbot", chatbot_node) tool_node = BasicToolNode([search_tool]) graph_builder.add_node("tools", tool_node) ############################################################################### # 7) 조건부 라우팅 ############################################################################### # - chatbot 노드가 실행된 후, LLM이 도구를 호출했는지 여부를 판단해 # "tools" 노드로 갈지, "END"로 갈지 결정 def route_tools(state: State): """ chatbot 노드가 끝난 직후 실행되는 함수 - state["messages"][-1] 에 tool_calls가 있으면 'tools' - 없으면 'END' """ if messages := state.get("messages", []): last_msg = messages[-1] # tool_calls가 있고, 갯수가 > 0이면 'tools' if hasattr(last_msg, "tool_calls") and last_msg.tool_calls: return "tools" # 그렇지 않으면 'END' return END # - add_conditional_edges("chatbot", route_tools, {"tools":"tools", END:END}) graph_builder.add_conditional_edges( "chatbot", route_tools, { "tools": "tools", END: END } ) # - tools -> chatbot: 툴 실행 후 다시 chatbot 노드로 돌아가서 최종 답변을 완성 graph_builder.add_edge("tools", "chatbot") # - START -> chatbot graph_builder.add_edge(START, "chatbot") ############################################################################### # 8) 그래프 컴파일 ############################################################################### graph = graph_builder.compile() ################################################################################ # 그래프 시각화를 위한 ASCII 아트 생성 ################################################################################ # - graph.get_graph().draw_ascii()를 호출하여 그래프 구조를 ASCII 아트로 표현 # - 노드와 엣지의 연결 관계를 시각적으로 보여줌 ascii_graph = graph.get_graph().draw_ascii() print(ascii_graph) ############################################################################### # 9) 메인 함수 ############################################################################### def main(): print("==== [ch3] Custom BasicToolNode Demo ====") print("Type 'quit' or 'q' to exit.\n") while True: user_input = input("User: ") if user_input.lower() in ["quit", "q", "exit"]: print("Goodbye!") break # 그래프를 단계별로 실행 # "messages": [("user", user_input)] => 대화 목록에 새 사용자 메시지 추가 events = graph.stream({"messages": [("user", user_input)]}) # 실행 중 발생하는 모든 노드의 업데이트를 받아 메시지가 생성되면 출력 for event in events: for node_output in event.values(): if "messages" in node_output: last_msg = node_output["messages"][-1] # AIMessage 혹은 ToolMessage print("Assistant:", last_msg.content) if __name__ == "__main__": main()</code>4. 코드 해설chatbot_nodestate["messages"]를 LLM(Claude)에 전달해 새 응답을 생성.Claude가 “검색이 필요하다”고 판단하면 응답에 tool_calls를 담아 돌려준다.BasicToolNode (직접 구현)LangGraph의 빌트인 ToolNode와 유사한 역할을 하지만, 커스텀 로직이 필요할 경우 이처럼 직접 짤 수 있다.마지막 AI 메시지(messages[-1])에 tool_calls가 있으면, 해당 툴을 invoke(args)로 실행.그 결과를 ToolMessage로 만들어 대화에 추가.한 번 검색을 수행하면, 다음 턴에 다시 chatbot_node로 돌아와 최종 답변이 완성되는 구조.조건부 라우팅 (route_tools)chatbot 노드가 끝난 뒤 실행되는 함수로,메시지에 tool_calls가 있으면 "tools", 없으면 "END"로 분기.이후 "tools" -> "chatbot"으로 돌아와 LLM이 새로운 정보를 활용할 수 있게 된다.메인 함수사용자 입력 -> graph.stream(...) -> 순차적으로 노드가 실행되며 메시지를 추가 -> 결과 출력사용자가 “quit”를 입력하기 전까지 반복.5. 실행 예시<code class="language-python">$ python ch3_chatbot_with_tools_using_customnode.py +-----------+ | __start__ | +-----------+ * * * +---------+ | chatbot | +---------+ . . .. .. . . +-------+ +---------+ | tools | | __end__ | +-------+ +---------+ ==== [ch3] Custom BasicToolNode Demo ==== Type 'quit' or 'q' to exit. User: 안녕 Claude Assistant: 안녕하세요! 어떻게 도와드릴까요? User: LangGraph가 뭐야? Assistant: [{'text': "Let me look that up for you...", 'type': 'text'}, {'id': 'toolu_01A...', 'input': {'query': 'LangGraph'}, ...}] Assistant: [{"url": "https://github.com/langchain-ai/langgraph", "content": "LangGraph is a library for ..."}] Assistant: LangGraph는 ....</code>Claude가 “검색해야겠다”고 판단하면, tool_calls JSON이 AI 메시지에 들어 있음 → BasicToolNode가 search_tool을 실제로 호출 → 그 결과를 ToolMessage로 만들어 대화에 추가 → 다시 chatbot_node에서 최종 요약/답변을 준다.6. add_conditional_edges 좀 더 살펴보기노드(Node)가 완료된 뒤, 현재 상태(State)를 분석하여 다음에 어디로 갈지 분기(조건부 라우팅) 하고 싶을 때 사용합니다. 즉, “조건에 따라 서로 다른 노드로 이동”하는 흐름을 간단히 정의할 수 있습니다.일반적인 add_edge("A", "B")는 “A 후에 무조건 B”로 연결되지만,add_conditional_edges("A", condition_fn, {...})는 “A 후에 condition_fn의 결과값에 따라 여러 갈래”로 분기할 수 있습니다.함수 문법<code class="language-python">StateGraph.add_conditional_edges( from_node: str, condition: Callable[[Any], str | list[str]], mapping: dict[str, str] = {}, ... ) -> None</code>from_node: str어떤 노드가 끝난 뒤 이 조건부 로직을 적용할지 지정.예: "chatbot" → chatbot 노드가 실행을 마치면 condition 함수를 호출하여 분기 결정.condition: Callable[[Any], str | list[str]]실제 분기 로직이 들어 있는 함수(“조건 함수”).그래프의 현재 State(예: TypedDict)를 입력으로 받아, 다음으로 이동할 노드 이름(문자열)을 반환.하나의 문자열을 반환하면 “단일 분기”, 문자열 리스트를 반환하면 “여러 노드로 병렬 분기”도 가능.예시:<code class="language-python">def route_tools(state: State) -> str: last_msg = state["messages"][-1] if hasattr(last_msg, "tool_calls") and last_msg.tool_calls: return "tools" return "END"</code>mapping: dict[str, str]condition 함수가 반환한 문자열(또는 문자열 중 하나)을 실제 노드 이름 혹은 특수 키(END)에 매핑.예: { "tools": "tools", "end": END }condition이 "tools"를 반환하면 실제로 tools 노드로 이동."end"를 반환하면 그래프 종료(END).만약 condition이 "my_tools" 같은 임의 문자열을 반환하고, mapping에 {"my_tools": "tools"} 라고 작성하면, 실제로는 "tools" 노드로 이동시키는 식으로 커스터마이징 가능.보통은 "tools" → "tools", "END" → END 처럼 간단하게 1:1 매핑하는 경우가 많습니다.리턴(반환) 값add_conditional_edges 자체는 그래프에 조건부 엣지를 추가하고 None을 반환합니다.이후 그래프가 from_node를 마친 시점에 내부적으로 condition(state)를 호출해, 반환값을 mapping으로 해석하여 다음 노드를 결정하게 됩니다.7. 마무리 및 확장직접 구현한 ToolNode를 통해 LangGraph에서 다양한 모듈(예: 검색, DB 조회, 사내 API 호출 등)을 자유롭게 연결할 수 있습니다.함수형으로 만들 수도 있고, 이번처럼 클래스(__call__)로 만들어 노드 로직을 더 체계적으로 관리할 수도 있습니다.조건부 라우팅 역시 직접 route_tools 함수를 짜보면, LangGraph가 제공하는 편의 함수(tools_condition)의 내부 동작을 파악하는 데 도움이 됩니다.이상으로, ch3: LangGraph에서 직접 만든 ToolNode로 검색 툴을 연동해보는 방법을 소개해드렸습니다!

AF 김태영
0

LangGraph #2 - Chatbot with Tools

우리는 ch1에서 LangGraph의 StateGraph를 만들고, 간단한 노드(chatbot)와 엣지(START->chatbot->END)를 연결해, “사용자 입력 -> LLM 응답”의 기초적인 챗봇을 완성했습니다. 그 결과, Claude가 이미 알고 있는 지식 범위 내에서는 문제없이 대화를 이어갈 수 있었죠. 하지만 LLM이 미처 학습하지 못했거나 최신 정보를 요구하는 상황에서는 응답이 부정확해질 수 있었습니다. 이를 해결하기 위해 검색 엔진 등의 외부 도구(tool) 를 연결해 필요한 데이터를 실시간으로 가져오는 방식을 고려해볼 수 있습니다. 이번 ch2에서는 LangGraph에 툴 노드(ToolNode) 를 추가해, LLM이 필요시 스스로 검색 툴을 사용할 수 있도록 만들고, 조건부 분기(conditional edges)를 적용해 LLM이 검색을 원하는 경우와 원치 않는 경우를 구분하여 처리합니다. 이를 통해, 사용자 질문에 대해 LLM이 필요 시 웹 검색을 수행하고, 그 결과를 바탕으로 대답을 보강할 수 있게 됩니다.1. 사전 준비 사항가상환경 활성화<code class="language-plaintext">python -m venv .venv source .venv/bin/activate</code>필요 라이브러리 설치<code class="language-plaintext">pip install -U langgraph langsmith langchain_anthropic tavily-python langchain_community</code>환경변수 설정Anthropic API 키: export ANTHROPIC_API_KEY="..."Tavily API 키: export TAVILY_API_KEY="..."(Windows PowerShell: $env:ANTHROPIC_API_KEY="..." 식)2. 코드 전체 (ch2_chatbot_with_tools.py)아래 코드를 chatbot_with_tools.py로 저장한 뒤, python chatbot_with_tools.py로 실행해보세요.<code class="language-plaintext">import os # Anthropic Claude 연결 from langchain_anthropic import ChatAnthropic # LangGraph 핵심 구성요소 # - StateGraph: 그래프 정의 # - START, END: 시작/종료 지점 # - add_messages: 새로운 메시지를 State에 append하는 편의함수 from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages # 웹 검색 툴 (Tavily) from langchain_community.tools.tavily_search import TavilySearchResults # 미리 만들어진 'ToolNode'와 'tools_condition' (LangGraph 제공) # - ToolNode: 여러 툴(도구) 실행을 자동 처리 # - tools_condition: "LLM이 툴을 호출했는지" 보고 다음 노드를 결정 from langgraph.prebuilt import ToolNode, tools_condition # 타입 정의 from typing import Annotated from typing_extensions import TypedDict ################################################################################ # 1) State(상태) 정의 ################################################################################ # - messages: 사용자/AI 메시지를 저장해두는 리스트 # - add_messages: 새 메시지를 append class State(TypedDict): messages: Annotated[list, add_messages] ################################################################################ # 2) 그래프 빌더 생성 ################################################################################ # - 우리가 만든 State 구조를 기반으로 동작하는 StateGraph # - 노드와 엣지를 등록한 후, compile() 하면 실행 가능해짐 graph_builder = StateGraph(State) ################################################################################ # 3) LLM + 툴 생성 ################################################################################ # (A) Tavily 웹 검색 툴 search_tool = TavilySearchResults( max_results=2, # 검색 결과 최대 개수 tavily_api_key=os.environ.get("TAVILY_API_KEY") # 환경변수에서 가져오기 ) # (B) Anthropic Claude llm = ChatAnthropic( model="claude-3-5-sonnet-20241022", # 원하시는 모델 버전으로 수정 가능 anthropic_api_key=os.environ.get("ANTHROPIC_API_KEY") ) # (C) LLM + 툴 바인딩 # - LLM이 JSON 포맷을 통해 툴을 "호출"할 수 있게 설정 llm_with_tools = llm.bind_tools([search_tool]) ################################################################################ # 4) 노드(Node) 정의 ################################################################################ # (1) chatbot 노드 # - state["messages"]를 보고 LLM이 답변 # - 필요하면 (tool_calls)를 포함하여, 툴을 호출하도록 지시 def chatbot_node(state: State): ai_response = llm_with_tools.invoke(state["messages"]) return { "messages": [ai_response] } # (2) tools 노드 # - LLM 메시지에 툴 호출 정보(tool_calls)가 있으면 # 실제 검색 툴을 실행하고, 그 결과를 messages에 append # -> LangGraph에는 이미 'ToolNode'라는 편의 클래스가 있으므로 직접 구현 필요 없음 # 이번에는 prebuilt된 ToolNode를 사용해보겠습니다. tool_node = ToolNode(tools=[search_tool]) ################################################################################ # 5) 그래프 빌더에 노드 등록 ################################################################################ # - "chatbot" 노드 -> chatbot_node(함수) graph_builder.add_node("chatbot", chatbot_node) # - "tools" 노드 -> tool_node(객체) # => tool_node(...) 실행 시 LLM이 요청한 툴들을 병렬/직렬 등으로 실행 가능 graph_builder.add_node("tools", tool_node) ################################################################################ # 6) 조건부 엣지(conditional_edges) 설정 ################################################################################ # - LangGraph의 핵심: "조건부 엣지"로 다음 노드를 동적으로 결정 # - tools_condition: # => "LLM이 툴을 호출했으면 tools 노드로, 아니면 END로" 라우팅 # - chatbot 노드가 실행된 후, tools_condition로 분기 # (예: "search_tool" 호출 요청이 있으면 'tools'로 이동 / 없으면 'END') graph_builder.add_conditional_edges( "chatbot", tools_condition, # condition 함수 { "tools": "tools", # condition이 "tools"라 반환하면, 실제로 "tools" 노드로 이동 END: END # condition이 END라 반환하면 그래프 종료 } ) ################################################################################ # 7) 추가 엣지 설정 ################################################################################ # - "tools" -> "chatbot" : 툴 실행 후 다시 LLM에 돌아와 응답을 마무리 # - START -> "chatbot" : 시작하면 곧바로 챗봇 노드부터 실행 graph_builder.add_edge("tools", "chatbot") graph_builder.add_edge(START, "chatbot") ################################################################################ # 8) 컴파일 ################################################################################ # - 이렇게 해서 완성된 노드/엣지 구조를 실제로 "실행할 수 있는" 그래프로 변환 graph = graph_builder.compile() ################################################################################ # 그래프 시각화를 위한 ASCII 아트 생성 ################################################################################ # - graph.get_graph().draw_ascii()를 호출하여 그래프 구조를 ASCII 아트로 표현 # - 노드와 엣지의 연결 관계를 시각적으로 보여줌 ascii_graph = graph.get_graph().draw_ascii() print(ascii_graph) ################################################################################ # 9) 메인 함수 ################################################################################ def main(): print("==== [ch2] LangGraph + Tools (Conditional) Demo ====") print("Type 'quit' or 'q' to exit.\n") while True: user_input = input("User: ") if user_input.lower() in ["quit", "q", "exit"]: print("Goodbye!") break # 그래프 실행 # - 입력 형태: {"messages": [("user", user_input)]} # - chatbot 노드 -> tools_condition -> (tools or end) -> ... # - 툴 실행이 발생하면 "tools" 노드가 검색 수행, 결과를 messages에 저장 # - 이후 다시 chatbot 노드에서 최종 답변 events = graph.stream({"messages": [("user", user_input)]}) # 실행 중 발생하는 event(상태 업데이트)마다 새 메시지가 있다면 출력 for event in events: for node_output in event.values(): if "messages" in node_output: # 가장 마지막 메시지(새로운 답변) last_msg = node_output["messages"][-1] # AIMessage의 .content 속성 출력 print("Assistant:", last_msg.content) if __name__ == "__main__": main()</code>3. 주요 흐름 설명chatbot 노드가 사용자 메시지를 보고 Claude에게 질의Claude가 “외부 검색이 필요하다”고 판단하면, tool_calls에 search_tool을 호출하는 JSON을 담아 반환조건부 엣지 (tools_condition)LLM 응답에 툴 호출이 있으면 "tools" 노드로 이동, 없으면 END로 종료tools 노드실제 TavilySearchResults를 호출해 검색 결과(JSON)를 messages에 추가이후 다시 "chatbot" 노드로 돌아가, 검색 결과를 이용해 최종 답변 생성메인 루프사용자 입력 -> 그래프 stream -> (필요 시 검색) -> 최종 답변 출력“quit” 입력 시 종료4. 실행 예시 <code class="language-plaintext">$ python ch2_chatbot_with_tools.py +-----------+ | __start__ | +-----------+ * * * +---------+ | chatbot | +---------+ . . .. .. . . +-------+ +---------+ | tools | | __end__ | +-------+ +---------+ ==== [ch2] LangGraph + Tools (Conditional) Demo ==== Type 'quit' or 'q' to exit. User: LangGraph는 뭐야? Assistant: (Claude가 답변 중...) Assistant: ... (검색 필요 판단) tool_calls -> search_tool Assistant: ... (검색 결과) ... Assistant: LangGraph는 ~~~ 입니다!</code>Claude가 학습된 지식만으로 답할 수 있으면 툴을 안 쓰고 바로 끝(END)추가 정보가 필요하면 tool_calls를 통해 search_tool을 실행하고, 검색 결과를 메시지로 받아와 더 풍부한 답변을 구성합니다.이상으로, LangGraph + Anthropic Claude + TavilySearchResults를 이용한 도구(검색) 활용 챗봇 예시(ch2)를 살펴봤습니다. 소스코드는 간단하지만 add_conditional_edges에 대해 생소하시다면 완벽히 이해가 되지 않을 수 있습니다. 이 부분에는 다음 챕터에서 살펴보겠습니다.

AF 김태영
0

LangGraph #1 - Chatbot

최근 LLM(Large Language Model) 기반 애플리케이션이 폭발적으로 증가함에 따라, LangChain 계열 라이브러리를 활용해 챗봇을 구축하는 사례도 점차 늘어나고 있습니다. 그중 LangGraph는 다중 노드(다중 에이전트) 워크플로우를 직관적으로 만들 수 있도록 돕는 프레임워크로, 상태(State)를 쉽게 관리하고 제어 흐름을 유연하게 구성해줍니다.이번 글에서는 LangGraph와 Anthropic Claude를 간단히 연동해, 터미널에서 동작하는 챗봇 예제를 만들어보겠습니다.1. 사전 준비Python 가상환경<code class="language-plaintext">python -m venv .venv source .venv/bin/activate</code>필요 라이브러리 설치<code class="language-plaintext">pip install langgraph langsmith langchain_anthropic grandalf</code>Anthropic API Key 발급Anthropic Console에서 API Key를 생성아래와 같이 환경변수 설정(예: Linux/Mac):<code class="language-plaintext">export ANTHROPIC_API_KEY="여러분의_키"</code>이 과정을 거치면 준비는 끝났습니다.2. 코드 구조 개요LangGraph는 StateGraph라는 객체에 각 노드(함수)와 엣지(실행 흐름)를 등록하고, compile()을 통해 실제 실행 가능한 그래프(CompiledGraph)를 생성합니다.Anthropic Claude는 langchain_anthropic.ChatAnthropic 클래스로 LLM 객체를 만들고, 여기에 .invoke(messages) 메서드를 사용해 대화를 주고받습니다.3. 전체 코드아래 ch1_chatbot.py 코드를 작성한 후, python ch1_chatbot.py로 실행하면 됩니다.<code class="language-python">import os # LangChain + Anthropic 연동을 위한 클래스 from langchain_anthropic import ChatAnthropic # LangGraph 기본 구성요소 (StateGraph, START, END, add_messages 등) from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages # 타입 어노테이션 from typing import Annotated from typing_extensions import TypedDict ################################################################################ # 1) State(상태) 정의 ################################################################################ # - LangGraph에서는 "상태(State)"가 매우 중요합니다. # - 챗봇이라면, 이전까지 오간 모든 메시지를 'messages' 리스트에 저장할 수 있습니다. # - 아래는 그런 목적을 가진 State를 정의합니다. # - 'add_messages'를 통해, 새 메시지를 덧붙이는 형태로 유지(append)할 것입니다. class State(TypedDict): messages: Annotated[list, add_messages] ################################################################################ # 2) 그래프 빌더(StateGraph) 생성 ################################################################################ # - LangGraph의 핵심: "그래프(Graph)"라는 개념. # - 그래프는 여러 "노드(Node)"들이 서로 연결(Edge)되어 있는 형태를 말합니다. # - StateGraph(...) 생성 시, 우리가 어떤 'State' 구조를 쓸지 지정해야 합니다. # - 추후 노드를 등록하고, 엣지(edge)로 어떤 순서로 실행할지 짜면 "워크플로우"가 완성됩니다. graph_builder = StateGraph(State) ################################################################################ # 3) LLM(Anthropic Claude) 객체 생성 ################################################################################ # - LangChain의 ChatAnthropic 클래스를 이용해 Anthropic Claude 모델과 연결합니다. # - model: "claude-3-5-sonnet-20241022" 등 원하는 버전명으로 지정 가능 # - anthropic_api_key: Anthropic 계정에서 발급받은 API 키를 환경변수로 설정 후 가져오기 llm = ChatAnthropic( model="claude-3-5-sonnet-20241022", anthropic_api_key=os.environ.get("ANTHROPIC_API_KEY") ) ################################################################################ # 4) 노드(Node) 정의: chatbot 함수 ################################################################################ # - "노드(Node)"란, 그래프 내에서 특정 기능(로직)을 담당하는 '단계(step)'를 의미합니다. # - 여기서는 'chatbot' 노드가, "LLM에게 메시지를 던지고 응답을 받는 역할"을 합니다. # - LangGraph가 노드를 실행할 때, 현재 상태(State)를 함수 인자로 넣어주고 # 함수가 반환한 dict를 통해 state가 업데이트됩니다. def chatbot(state: State): """ chatbot 노드 함수: 1) state["messages"] 내 기존 메시지(사용자 발화 등)를 LLM에 전달 2) LLM이 준 새 AI 응답을 'messages' 리스트에 추가한다. """ # LLM.invoke(...) -> state["messages"]를 토대로 AI가 답변(메시지 객체)을 생성 ai_resp = llm.invoke(state["messages"]) # 반환: {"messages": [새로운 메시지 객체]} # -> LangGraph가 add_messages 방식으로 기존 리스트에 덧붙임 return { "messages": [ai_resp] } ################################################################################ # 5) 그래프 빌더에 "노드" 등록 ################################################################################ # - 아래에서 graph_builder.add_node("chatbot", chatbot)를 호출: # => "chatbot"이란 이름의 노드(Node)를 그래프에 추가 # => 실제 로직은 chatbot(...) 함수로 실행 # - 노드 이름(첫 번째 인자) = "chatbot" # - 노드 함수(두 번째 인자) = 위에서 정의한 chatbot 함수 graph_builder.add_node("chatbot", chatbot) ################################################################################ # 6) 그래프(Workflow) 내 "엣지(Edge)" 정의 ################################################################################ # - 그래프 = 노드 + 엣지(노드와 노드를 연결) # - LangGraph가 "시작(START)" 노드로부터 어디로 가야 하는지, 끝(END)은 어디인지 정의. # - 여기서는 단순히, # START -> "chatbot" -> END # 라는 흐름을 만든다. # - 즉, 그래프를 실행할 때: # (1) START 노드로부터 시작 # (2) "chatbot" 노드를 실행 (chatbot 함수가 동작) # (3) "chatbot" 노드 완료되면 END로 가서 종료 graph_builder.add_edge(START, "chatbot") graph_builder.add_edge("chatbot", END) ################################################################################ # 7) 그래프를 "컴파일(compile)"하여 사용 가능하게 만듦 ################################################################################ # - graph_builder.compile()을 호출하면, 우리가 지금까지 정의한 노드와 엣지를 바탕으로 # 실제로 실행 가능한 'CompiledGraph' 객체가 생성됩니다. # - compile()을 하지 않으면, 아직은 그래프가 "설계도 상태"입니다. # - compile() 결과물인 graph는 .stream() 또는 .invoke()를 통해 실행할 수 있습니다. graph = graph_builder.compile() ################################################################################ # 그래프 시각화를 위한 ASCII 아트 생성 ################################################################################ # - graph.get_graph().draw_ascii()를 호출하여 그래프 구조를 ASCII 아트로 표현 # - 노드와 엣지의 연결 관계를 시각적으로 보여줌 # - START -> chatbot -> END 형태의 단순한 흐름이 표현됨 ascii_graph = graph.get_graph().draw_ascii() print(ascii_graph) ################################################################################ # 8) 간단한 메인 함수(main) ################################################################################ # - 아래 함수는 콘솔용 대화 루프를 제공합니다. # - 사용자가 입력을 하면, LangGraph의 graph.stream(...)으로 메시지를 주고 # AI 응답을 받아 출력하는 식입니다. # - 'quit', 'exit', 'q' 등을 입력하면 대화를 종료. def main(): while True: # 사용자 입력 받음 user_input = input("User: ") # 특정 단어 입력 시 종료 if user_input.lower() in ["quit", "exit", "q"]: print("Goodbye!") break # (A) graph.stream({"messages": [("user", user_input)]}) # => LangGraph에 "messages" 키로 [('user', user_input)] 튜플을 넘김 # => State 에는 [('user', '...')] 형태가 메시지로 추가됨 # # (B) for event in graph.stream(...): # => 그래프 실행 과정에서 발생하는 "상태 업데이트" 이벤트들을 순차적으로 받음 # => chatbot 노드가 실행되면 AI의 응답 메시지를 생성하여 event.values()에 포함 # # (C) event.values() 안의 "messages"를 찾아, 가장 마지막 메시지를 출력 (AI 답변) for event in graph.stream({"messages": [("user", user_input)]}): # event = {"(노드이름)": {"messages": [...]} ...} 형태 등 # event.values() = 각 노드 실행 결과(딕셔너리)들의 값 for value in event.values(): # value["messages"] -> 이번 단계에서 추가된 메시지 리스트 # [-1] => 가장 마지막 메시지(새로 생성된 AI 메시지) print("Assistant:", value["messages"][-1].content) ################################################################################ # 9) 실행 엔트리포인트 ################################################################################ # - 아래 if 문은 "이 파일을 python 으로 직접 실행했을 때"만 main() 함수를 호출. # - 이 파일이 다른 모듈에서 import될 경우 main()은 자동으로 실행되지 않는다. if __name__ == "__main__": main()</code>실행 예시 <code class="language-python">$ python ch1_chatbot.py +-----------+ | __start__ | +-----------+ * * * +---------+ | chatbot | +---------+ * * * +---------+ | __end__ | +---------+ User: 안녕 Assistant: 안녕하세요! 무엇을 도와드릴까요? User: LangGraph가 뭐야? Assistant: LangGraph는 ... ...</code>User: 라고 입력하면 Anthropic Claude에게 메시지를 전달하고,Assistant: Claude가 생성한 응답을 출력해줍니다.quit, exit, q 등을 입력하면 프로그램을 종료합니다.4. 정리 및 확장 아이디어이 예시는 가장 기본적인 흐름인 START -> chatbot -> END만 사용했습니다.LangGraph의 강점은 다양한 노드(Node)를 연결해 여러 단계(Workflow)로 확장할 수 있다는 점입니다.예: “챗봇 노드 -> 검색 노드 -> 요약 노드 -> 챗봇 노드” 등메모리 체크포인트, Human-in-the-loop, ToolNode 등을 추가하면 훨씬 강력한 다중 단계 챗봇/에이전트가 만들어집니다.langchain_community.tools 등 다양한 툴을 연동해 검색, DB 조회, API 호출 등을 자유자재로 수행시킬 수 있습니다.이상으로 LangGraph와 Anthropic Claude를 연동해 간단한 터미널 챗봇을 만드는 방법을 살펴봤습니다. 더 자세한 내용은 LangGraph 공식 문서나 LangChain의 다양한 레퍼런스를 참고해보시기 바랍니다. 

AF 김태영
0

NativeRAG부터 AdvancedRAG 톺아보기 발표자료 공유

안녕하세요! 20240626 랭체인밋업Q2에서 발표한 백혜림입니다!이번 랭체인밋업 컨셉에 맞게 RAG를 처음접하시는 분들을 위해 발표를 준비했습니다! 기본적인 RAG부터 Advanced RAG로 나아가기 위한 여러기법에 대해 소개해드렸습니다!정답인 방법은 없으니 여러 기법을 조합하시면서 데이터에 맞는 최적의 성능을 내는 방법을 찾으셨으면 좋겠습니다!늦은시간까지 발표들어주셔서 감사합니다!ps) 발표자료는 아래 링크에서 확인하실 수 있습니다!https://speakerdeck.com/hyerimbaek/langchainkr-2024q2-native-rag-to-advanced-rag-topabogi 

리미에오
2

LangGraph 발표자료 공유 드립니다.

안녕하세요? 두 번째 발표를 맡은 테디노트의 이경록(Teddy)입니다. 먼저, 귀중한 자리에 초청해 주신 랭체인 코리아 운영진 및 관계자 여러분께 감사의 말씀을 드립니다.그리고, 참여해 주신 150여 명의 참석자 여러분께도 감사인사를 드립니다.바쁘신 시간을 내어 주셔서 참여하시기 때문에 더욱 정성스럽게 발표와 자료를 준비했습니다.귀한 발걸음이 헛되지 않도록 도움이 될 만한 정보로 준비했습니다. 이번 주제는 “LangGraph” 입니다.“LangGraph”를 이미 사용해 보신 분이 계신지 모르겠습니다. 아직 라이브러리가 출시된 지 얼마 되지 않았고, 관련 정보를 찾기 어려운 것이 사실입니다.해외에서는 LangGraph에 대한 앞으로의 기대감과 극찬이 끊이지 않습니다. 그만큼 복잡한 RAG 설계에 있어 꽤 유용한 도구입니다.다만, 예제가 다소 어렵게 되어 있어 친절한 가이드가 없으면 시도를 망설이시는 분들이 많습니다.6.26 랭체인 Q2 밋업 이후에는 바로 활용해 보실 수 있도록 쉬운 예제와 설명을 준비하였습니다.자료를 사전에 공유드리오니, 한 번 보시고 오시면 이해에 도움이 될 것입니다. 감사합니다.

테디노트
7

네이버 클로바의 주요 기능

네이버 클로바(Clova)는 네이버(Naver)와 라인(Line)이 공동으로 개발한 인공지능(AI) 플랫폼으로, 사용자에게 다양한 AI 기반 서비스와 기능을 제공하는 것을 목표로 하고 있습니다. 클로바는 'Cloud Virtual Assistant'의 약자로, 네이버의 검색 기술과 라인의 메신저 기능을 결합하여 사용자의 생활을 더욱 편리하고 스마트하게 만들어줍니다.클로바의 주요 기능음성 인식 및 음성 합성 클로바는 고도화된 음성 인식 기술을 통해 사용자의 음성을 정확하게 인식합니다. 이를 통해 사용자는 음성 명령으로 다양한 작업을 수행할 수 있으며, 텍스트를 자연스러운 음성으로 변환하는 음성 합성 기능도 제공합니다. 이러한 기술은 스마트 스피커, 모바일 앱 등 다양한 디바이스에서 활용됩니다.자연어 처리 클로바의 자연어 처리(NLP) 기술은 사용자의 질문을 이해하고 적절한 답변을 제공할 수 있게 합니다. 이는 검색, 대화형 서비스, 고객 지원 등에 활용되며, 사용자와의 자연스러운 상호작용을 가능하게 합니다.이미지 및 비디오 분석 클로바는 이미지와 비디오를 분석하여 객체 인식, 얼굴 인식, 장면 분석 등을 수행할 수 있습니다. 이는 사진 관리, 보안, 미디어 분석 등 다양한 분야에서 유용하게 사용됩니다.추천 시스템 클로바는 사용자의 취향과 행동을 분석하여 개인화된 추천을 제공합니다. 이는 뉴스, 쇼핑, 음악 등 다양한 콘텐츠에서 사용자에게 맞춤형 제안을 하는 데 도움이 됩니다.클로바의 적용 사례클로바 스피커 클로바 스피커는 음성 명령을 통해 음악 재생, 일정 관리, 날씨 정보 제공 등 다양한 기능을 수행하는 스마트 스피커입니다. 사용자는 간단한 음성 명령만으로도 손쉽게 다양한 정보를 얻을 수 있습니다.클로바 앱 클로바 앱은 스마트폰에서 사용할 수 있는 AI 비서로, 음성 명령을 통해 메모 작성, 전화 걸기, 메시지 보내기 등의 작업을 수행할 수 있습니다. 또한, 클로바 램프 등 다양한 IoT 기기와 연동되어 스마트 홈을 구현하는 데 기여합니다.네이버 서비스 네이버의 검색, 쇼핑, 뉴스 등 다양한 서비스에 클로바의 AI 기술이 적용되어 사용자에게 더욱 편리하고 유용한 기능을 제공합니다. 예를 들어, 네이버 검색에서 사용자는 음성으로 검색어를 입력하거나, 이미지 검색을 통해 원하는 정보를 쉽게 찾을 수 있습니다.

미송
0

Faster Segment Anything (MobileSAM)

Motivation: For the ViT-based image encoder, the official release includes three models with different parameter sizes: ViT-H (632M), ViT-L (307M), and ViT-B (86M), as shown in the following table.Although ViT-H can achieve the best performance, it has large parameters, which makes it hard to deploy at the edge side. How to strike a balance between model size and performance, achieving a significant reduction in model parameters compared to ViT-H while maintaining performance comparable to official ViT-H?Coupled & Semi-coupled Distillation: A straightforward way to realize the project goal is to follow the official pipeline to retrain a new SAM with a smaller image encoder. As stated in Kirillov et al. [2023], training a SAM with a ViT-H image encoder requires 68 hours on 256 A100 GPUs.Replacing the ViT-H with ViT-L or ViT-B reduces the required GPUs to 128, which is still a non-trivial burden for many researchers in the community. So the authors adopt an even smaller image encoder which we will talk about later. From Semi-coupled to Decoupled Distillation: To alleviate the optimization issue of coupled distillation, a way is to optimize the image encoder with a copied and frozen mask decoder.The optimization of the image encoder is still not fully decoupled from the mask decoder.Since the choice of a prompt is random, it makes the mask decoder variable and thus increases the optimization difficulty.Therefore, the authors propose to distill the small image encoder directly from the ViT-H in the original SAM without resorting to the combined decoder, which is termed decoupled distillation (Figure 3). Another advantage of the decoupled distillation is that the generated image encoding from the student image encoder can be sufficiently close to that of the original teacher encoder, which renders finetuning on the combined decoder in the second stage optional.It is expected that finetuning the mask decoder on the frozen lightweight image encoder or jointly finetuning them together might further improve the performance. Preliminary Evaluation: The authors conduct a preliminary investigation to compare coupled distillation and decoupled distillation.The mask generated by ViT-H is the ground-truth.For the coupled distillation, the authors adopt the SAM with ViT-B provided in the original SAM Kirillov et al. [2023].It was trained on SA-1B (11M images) on 128 GPUs (1 sample per GPU) for 180k iterations.By contrast, in the decoupled distillation setup, the authors train the model on 2 GPUs (two samples per GPU).The authors used 0.1% samples of SA-1B dataset (11k) images for 55k iterations.For performance evaluation, they compute the mIoU. Experimental Setup: The authors adopt ViT-Tiny for the proof of concept to demonstrate the effectiveness of our proposed decoupled distillation for training a lightweight MobileSAM. The parameters and inference speed of MobileSAM are summarized in the following table. Training and Evaluation Details: The authors train the lightweight encoder with 1% of the SA-1B dataset Kirillov et al. [2023] for 8 epochs on a single GPU.With a single GPU, the authors obtain our MobileSAM in less than a day.The results in Table 4 show that, under the same number of iterations, increasing the batch size increases the model performance.Similarly, under the same batch size, the performance also benefits from more iterations as well as more epochs.Note that all the experiments are conducted on a single GPU. Increasing the number of GPUs to allow a larger batch size or further increasing the iterations can further improve the performance.Results: Comparisons between SAM, FastSAM, and MobileSAM are demonstrated below:

Sumit K. Dam
0

법률 조언 챗봇 서비스

지능형 법률 조언 챗봇서비스 개요지능형 법률 조언 챗봇은 사용자가 법률 문제에 대한 기본적인 조언을 쉽게 받을 수 있도록 돕는 AI 기반의 도구입니다. 이 챗봇은 법률 문서와 사례 기록, 규제 정보를 학습하여 사용자에게 맞춤형 법률 정보를 제공합니다. 이 서비스는 주로 기업, 개인, 중소기업을 대상으로 하며, 법률 상담 비용을 줄이고 접근성을 높이는 데 중점을 둡니다.주요 기능법률 정보 제공일반 법률 지식: 사용자에게 일반적인 법률 용어와 개념을 설명합니다.법률 문서 이해: 계약서, 조항, 정책 등의 법률 문서를 쉽게 이해할 수 있도록 해석하고 요약합니다.법률 상담법률 질문 답변: 사용자가 입력한 법률 관련 질문에 대해 구체적이고 맞춤형 답변을 제공합니다. 예를 들어, 고용법, 상법, 지적 재산권 등에 관한 질문을 처리할 수 있습니다.사례 기반 조언: 과거 사례를 바탕으로 유사한 상황에서의 법적 결과를 예측하고 조언합니다.규제 준수 확인규제 정보 업데이트: 최신 법률 및 규제 정보를 데이터베이스에 업데이트하여 사용자에게 최신 정보를 제공합니다.규제 준수 체크리스트: 사용자가 특정 법률이나 규제를 준수하고 있는지 확인할 수 있도록 체크리스트를 제공합니다. 예를 들어, 개인정보 보호법(GDPR) 준수 여부를 평가할 수 있습니다.법률 문서 생성문서 템플릿 제공: 사용자 입력을 기반으로 표준 법률 문서 템플릿을 제공합니다. 예를 들어, 비밀유지 계약(NDA), 고용 계약서 등을 생성할 수 있습니다.맞춤형 문서 작성: 사용자가 제공한 정보를 바탕으로 맞춤형 법률 문서를 작성합니다.  지능형 법률 조언 챗봇은 법률 정보와 기술을 결합하여 보다 접근성 높고 비용 효율적인 법률 서비스를 제공할 수 있습니다. 이를 통해 법률에 대한 지식이 거의 없는 일반인도 법률 지식에 쉽게 접근할 있도록 하여 법률적 문제 해결에 큰 도움을 줄 수 있습니다.

ㅁㅇ
0

NAVER 클로바 스튜디오 사용 방법

주요 메뉴 구성1> 플레이 그라운드 : 파라미터를 조절해 결과값의 세부 사항을 설정할 수 있는 메뉴 (프롬프트를 활용해 가장 기본적인 질문/답변을 원하는 형태로 출력 조율한 값을 기반으로 API 생성 가능)2> 튜닝 : 기업 맞춤형 데이터로 모델을 학습 (자신만의 정보나 특화 모델을 구축하여 AI 제작 )3> 익스플로러 : AI 제작 작업에 활용할 도구 (임베딩 API 및 데이터 확장, 토근 계산기, 요약 등 제공)4> 스킬 트레이너 : 모델 외부 서비스 API와 연결 (특화 지식을 모델에 학습시켜 최신 정보를 반영한 답변 제공)위에 사항들은 ChatGPT에서 제공하는 GPTs를 통해 나만의 챗봇 만들기에서 사용했던 기능들과 유사함을 느꼈습니다.  다만 ChatGPT에서도 이를 기업용으로 사용하려면 좀 더 개발자적인 지식이나 스킬이 필요했는데 네이버에서 제공하는 클로바 스튜디오는 이를 좀 더 친숙하게 설계한 느낌이 듭니다. 실제 성능에 대해서는 좀 더 확인이 필요하겠습니다 주요 기능플레이 그라운드에 실제 내용을 입력해서 전체 구조를 확인해봤습니다. 크게 총 5가지 파트로 구성되어 있습니다.1> 파라미터(좌측 세로) : 텍스트 생성을 위해 토큰 값, 엔진, Temperature 조정 등 2> 우측 최상단 : 토큰 수 계산, 공유, 테스트앱(API ) 등 수행 3> 우측 하단 : 제목 입력, 시스템(사전에 AI 모델에 지시 입력값), 사용자(질문), 어시스턴트(AI에서 답변 받은 값)  파라미터하나씩 살펴보면 상단에서 모드는 일반 모드, 챗 모드를 제공하고 그에 대응하는 엔진을 제공합니다. 엔진은 성능에 따라 나뉘고 그에 따라 토큰에 대한 비용이 설정될 것으로 보입니다. ChatGPT 3.5, 4.0과 같은 엔진 개념으로 보입니다.Top P와 K가 조금 생소했는데, Top P는 0~1로 설정이 되며 누적 확률 값에 대한 설정인데, P 값으로 설정한 누적 확률 값에 포함되지 않는 토큰은 결과값에서 제외된다고 합니다. 즉, Top P가 0.8이라면 상위 80% 확률에 포함된 토큰에서만 결과값이 생성됩니다.Top K는 0~128 사이로 설정이 되는데 다양한 후보 중 확률 값이 가장 높은 K중 하나를 선택하게 하는 값이며 일반적으로 0으로 둡니다.위에 2개 값은 결국 하단의 Temperature 기능과 연결될 것으로 보입니다.생성형AI 모델은 기본적으로 정답을 찾는 것이 아니라 수 많은 데이터를 학습하여 가장 유사도가 높은 데이터 패턴에 따라 텍스트, 이미지, 영상 데이터 등을 생성하는 모델입니다. 즉, Temperature는 0~1로 설정이 되어서 문장의 다양성을 조절하는 값인데 다양성을 조정하면서도 Top P, K를 통해 유사도가 높은 데이터 패턴의 값들을 커스텀해 나가기 위한 설정 기능으로 보입니다.맥시멈 토큰은 AI가 생성하는 결과값의 최대치 입니다. 최대 4096토큰까지 생성이 됩니다.Repetition penalty는 0~10까지 설정되며 AI가 답변을 생성할 때 동일 토큰에 감점 요소를 부여하는 값으로 값이 낮으면 같은 결과를 반복 생성할 확률이 높습니다.마지막으로 Stop sequences는 결과값 생성 시 출력을 중단할 때 사용되며 예를 들어 ‘사자’를 입력해두면 결과값에 ‘사자’라는 단어가 나오면 그 전까지만 출력이 됩니다. 아마도 폭력적이거나 선정적인 내용, 보안에 관련된 사항 등이 언급될 때 사용될 것으로 보입니다.

augi_cos
1

네이버 클로바 클라우드의 음성 인식 기능 및 활용

네이버 클로바 클라우드는 음성 인식 기술을 API 형태로 제공하여, 개발자가 손쉽게 자신의 애플리케이션에 음성 인식 기능을 추가할 수 있게 해줍니다. 이를 통해 음성 명령을 이해하고 처리하는 애플리케이션을 개발할 수 있습니다. 클로바 클라우드의 음성 인식 API 사용 방법네이버 클라우드 플랫폼 가입 및 로그인: 네이버 클라우드 플랫폼에 가입한 후 로그인합니다.프로젝트 생성: 클라우드 콘솔에서 새로운 프로젝트를 생성합니다.음성 인식 API 활성화: 클로바 음성 인식 API를 활성화합니다.API 키 발급: API를 사용하기 위해 필요한 키를 발급받습니다.API 호출: 발급받은 키를 사용하여 애플리케이션에서 음성 인식 API를 호출합니다. 예제 코드를 참고하여 자신의 코드에 적용할 수 있습니다. 클로바 스튜디오는 비개발자도 쉽게 사용할 수 있는 직관적인 인터페이스를 제공하여, 음성 인식 기능을 활용한 AI 모델을 쉽게 개발하고 배포할 수 있습니다.클로바 스튜디오 사용 방법클로바 스튜디오 접속: 네이버 클로바 스튜디오 웹사이트에 접속합니다.프로젝트 생성: 새로운 프로젝트를 생성합니다.음성 데이터 업로드: 음성 인식 모델 학습에 필요한 음성 데이터를 업로드합니다.모델 학습: 업로드한 데이터를 기반으로 AI 모델을 학습시킵니다.모델 배포: 학습된 모델을 배포하여 실제 애플리케이션에 적용합니다. 

kiiae
0

LLM을 통한 생성형 AI 서비스 개발

대규모 언어 모델(LLM, Large Language Model)을 통한 생성형 AI 서비스 개발은 현대 인공지능 기술의 중요한 진전 중 하나로, 다양한 산업 분야에서 혁신적인 응용 프로그램을 가능하게 하고 있습니다. LLM은 방대한 양의 텍스트 데이터를 학습하여 자연어 이해와 생성 능력을 갖춘 모델로, 이러한 모델을 활용하면 매우 다양한 생성형 AI 서비스를 구현할 수 있습니다.LLM의 특징과 강점LLM의 주요 특징 중 하나는 문맥을 이해하고 일관성 있는 텍스트를 생성할 수 있는 능력입니다. 이는 단순한 패턴 인식에 그치지 않고, 텍스트의 의미와 뉘앙스를 이해하여 더욱 자연스러운 언어 생성이 가능하게 합니다. GPT-3, BERT, T5와 같은 LLM들은 이미 많은 연구와 실험을 통해 그 성능을 입증받았습니다.생성형 AI 서비스의 다양한 응용 분야콘텐츠 생성: LLM을 활용하면 자동으로 기사, 블로그 포스트, 제품 설명 등을 생성할 수 있습니다. 이는 콘텐츠 제작에 드는 시간과 비용을 절감할 수 있으며, 특히 다량의 콘텐츠가 필요한 마케팅과 출판 산업에서 유용합니다.고객 서비스: 챗봇과 가상 비서와 같은 고객 서비스 애플리케이션에 LLM을 적용하면, 고객의 질문에 대한 더 자연스럽고 정확한 응답을 제공할 수 있습니다. 이는 고객 만족도를 높이고, 기업의 서비스 효율성을 향상시킬 수 있습니다.번역 및 언어 지원: LLM은 고품질의 번역 서비스를 제공할 수 있으며, 다양한 언어에 대한 이해도를 바탕으로 글로벌 커뮤니케이션을 지원합니다. 이는 다국적 기업이나 언어 장벽을 넘어선 협업이 필요한 상황에서 큰 도움이 됩니다.교육 및 학습 도구: 개인 맞춤형 학습 경험을 제공하는 교육용 AI 도구에 LLM을 활용하면, 학생들의 질문에 실시간으로 답변하거나, 학습 자료를 생성할 수 있습니다. 이는 교육의 질을 향상시키고 학습 효율성을 높입니다.LLM을 활용한 서비스 개발의 과제LLM을 통한 생성형 AI 서비스 개발에는 몇 가지 과제가 있습니다. 먼저, 대규모 모델을 학습하고 운영하는 데는 막대한 계산 자원과 비용이 필요합니다. 또한, 생성된 텍스트의 정확성과 신뢰성을 보장하기 위해 지속적인 모니터링과 조정이 필요합니다. 마지막으로, 데이터 프라이버시와 윤리적 문제도 중요한 고려사항입니다.결론LLM을 통한 생성형 AI 서비스 개발은 다양한 산업에 걸쳐 혁신적인 솔루션을 제공할 수 있는 잠재력을 가지고 있습니다. 콘텐츠 생성, 고객 서비스, 번역, 교육 등 여러 분야에서 LLM의 활용은 이미 현실화되고 있으며, 앞으로도 더욱 발전할 것입니다. 이러한 기술적 진보는 기업의 운영 효율성을 높이고, 사용자 경험을 향상시키며, 궁극적으로는 더 나은 사회를 만드는 데 기여할 것입니다.

M000NNY
1

네이버 클로바 스튜디오와 네이버 웹툰

 클로바 스튜디오란?초 대규모 AI 하이퍼 클로바를 기반으로 한 No Code AI튜닝으로 AI에 개성을 불어넣음.이를 이용하여 현재 네이버 웹툰에서는 생성형 AI 하이퍼클로바X를 기반으로 하는 AI 챗봇, 캐릭터 챗을 서비스 중이다.메세지 30건은 1500원, 100건은 5000원, 300건은 1만 5000원에 판매 중이다.AI를 이용하여 수익성을 올릴 새로운 콘텐츠이다 

발가락
0

네이버 클로바 OCR 모델 사용해보기!

안녕하세요! LangChain KR x NAVER Cloud 생성형 AI 서비스 프로젝트 기간이 얼마 남지 않았습니다.진행하시는 분들 모두 끝까지 화이팅하시길 바랍니다! 서비스 개발에 도움이 되었으면 하는 마음으로, CLOVA OCR 서비스를 사용하는 방법에 대해 공유하고자 합니다!NAVER Clova OCR 서비스 신청하기 먼저, 콘솔에 들어가 CLOVA OCR 서비스로 들어가줍니다.  일반/템플릿 버전으로 도메인을 생성해주고, 도메인명을 아무렇게나 만들어줍니다.  도메인이 잘 생성되었는데, 이제 API Gateway와 연동을 해야합니다.그전에! 먼저 API Gateway를 검색해서, 사용신청이 되어있는지 확인해주세요.API Gateway 사용신청이 되어있다면, 이제 CLOVA OCR에서 API Gatewayt 연동 버튼을 클릭해줍니다.위 화면에서 Secret Key를 생성하고, APIGW Invoke URL도 확인할 수 있습니다!만약 이 화면이 나오지 않고 API Gateway 자동연결 버튼이 나온다면, 자동연결 버튼을 눌러 API Gateway와 연동해주시면 되겠습니다. Google Colab에서 사용해보기<code class="language-plaintext">import time import pandas as pd import cv2 import json import matplotlib.pyplot as plt import shutil import os import random from PIL import Image import requests import uuid import time import json ############################ Edit! secret_key = 'Secret Key' api_url = 'APIGW Invoke URL' image_file = 'Image path' ############################ # Setting up the request JSON request_json = { 'images': [ { 'format': 'jpg', 'name': 'demo' } ], 'requestId': str(uuid.uuid4()), 'version': 'V2', 'timestamp': int(round(time.time() * 1000)) } payload = {'message': json.dumps(request_json).encode('UTF-8')} files = [('file', open(image_file,'rb'))] headers = {'X-OCR-SECRET': secret_key} # Make the OCR request response = requests.request("POST", api_url, headers=headers, data=payload, files=files) # Load the original image for visualization image = cv2.imread(image_file) highlighted_image = image.copy() # OCR 응답 처리 if response.status_code == 200: ocr_results = json.loads(response.text) all_texts = [] # 모든 텍스트를 저장할 리스트 for image_result in ocr_results['images']: for field in image_result['fields']: text = field['inferText'] all_texts.append(text) # 텍스트 추가 # 텍스트 주변에 빨간 사각형 그리기 bounding_box = field['boundingPoly']['vertices'] start_point = (int(bounding_box[0]['x']), int(bounding_box[0]['y'])) end_point = (int(bounding_box[2]['x']), int(bounding_box[2]['y'])) cv2.rectangle(highlighted_image, start_point, end_point, (0, 0, 255), 2) # 모든 텍스트를 띄어쓰기로 연결하여 출력 full_text = ' '.join(all_texts) print(full_text) else: print(f"OCR 결과를 받아오지 못했습니다. 상태 코드: {response.status_code}") # Display the original and highlighted images side by side fig, axs = plt.subplots(1, 2, figsize=(15, 10)) axs[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) axs[0].set_title('Original Image') axs[0].axis('off') axs[1].imshow(cv2.cvtColor(highlighted_image, cv2.COLOR_BGR2RGB)) axs[1].set_title('Highlighted Image') axs[1].axis('off') plt.show()</code> output<code class="language-plaintext">제품명 한우 소불고기 전골 식품유형 간편조리세트(가열하여 섭취하는 냉동식품) 소비기한 제품 별도 표기일까지 품목보고번호 202003630271059 소스[양조간장(탈지대두/오국산), 설탕, 양파(국산), 마늘, 청주], 소고기(설도, 한우/국산), 숙면[밀가루 원재료명 (밀/호주산), 전분가공품{감자전분(독일산 99 %, 국산 1 %)}, 면류첨가알칼리제(정제수, 탄산나트륨, 탄산수소나트륨), 정제소금], 팽이버섯, 양파, 대파 대두, 밀, 쇠고기 함유 제조원 (주)프레시지/경기도 용인시 처인구 이동읍 삼배울로 23 보관방법 -18°C 이하 냉동보관 반품 및 교환 구입처 및 판매원 내포장재질 PE 고객상담전화 1833-5836 </code> CLOVA OCR은 한국기업인 NAVER에서 제공하는 서비스라 그런지, AWS나 GCP에 비해 한글을 잘 찾아주는 것 같습니다.바운딩 박스를 봐도, 곂치는부분 없이 깔끔합니다. 사용하실 때는, 위 코드에서 secret_key, ,api_url, image_file 를 수정하면 됩니다! 이 글이 도움이 되셨으면 좋겠습니다.감사합니다!

cocudeny
0

네이버 CLOVA Studio 사례

네이버 클로바 스튜디오 사례 1. AI CareCallCLOVA Contact Center에서 제공하는 서비스에는 AiCall, HappyCall, CareCall이 있다.먼저 AiCall은 소상공인부터 기업 고객센터까지 전화를 통한 문의 응대 및 예약 등을 진행할 수 있는 대화형 AI 서비스입니다. 콜센터, 고객센터 둥에 적합한 서비스이다.다음으로, HappyCall은 보험, 증권, 리서치 등의 업종에서 전화를 통한 고객 만족도 조사 및 불완전 판매 모니터링 업무를 수행할 수 있는 AI 서비스이다. 은행, 보험 회사 등에 적합한 서비스이다.마지막으로, CareCall은 일상적인 주제로 자유롭게 대화를 나누며 사용자의 건강 상태를 확인하는 AI 전화 돌봄 서비스이다. 주위 사람들의 시선이 자주 닿기 힘든 1인 가구, 독거노인 대상으로 탁월한 서비스이다.사용해보면 사투리도 인식한다. 정구지라고 말해도 표준어로 부추임을 인지한다. 따라서 경기권에 거주하지 않는 사용자도 편하게 쓸 수 있다.또한 농담도 가능하다. 따라서 사용자들과 친밀한 대화가 가능하다.행정복지센터 같은 곳에서 매일 독거노인 가구를 방문하기 힘드니 CLOVA CareCall로 인건비를 아끼고,대화에서 발생할 수 있는 감정 소모도 없는 훌륭한 복지 서비스가 될 수 있을 것이다. 2.  네이버 CLOVA Note네이버 CLOVA Note는 AI 기술을 활용한 음성 기록 관리 서비스이다.회의, 강의, 상담, 인터뷰 등 녹음이 필요한 모든 상황에 편리하게 이용이 가능하다. 특히 대화 내용을 집중해서 듣거나 직접 참여해야 할 때 유용하다.녹음한 내용이 텍스트로 변환되고 AI 기술이 핵심 내용만 요약해 주기 때문에 요점을 한눈에 파악하기 쉽고 필요한 구간만 찾아서 바로 들어볼 수도 있다. 노트 생성 모바일 앱 또는 PC에서 녹음을 시작하거나 저장된 음성 파일을 업로드해서 노트를 생성할 수 있다. 만약 업로드할 파일이 준비되지 않았거나 녹음을 시작하기 어려운 경우라면, 새 노트를 먼저 준비할 수 있다. 새 노트에 제목, 참석자, 주제 등을 미리 메모해놓으면 실제 녹음할 때 중요한 내용을 놓치지 않을 수 있다.  노트 편집 텍스트로 변환된 음성 기록과 직접 작성한 메모, AI가 자동으로 정리해주는 요약, 주요 주제, 다음 할 일까지 모두 수정할 수 있다. 뿐만 아니라, 음성 기록에서 강조할 내용이 있다면 길게 눌러서 하이라이트 표시하거나 메모 또는 북마크를 추가하는 것도 가능하다.  생성 노트 다운로드 / 공유 녹음한 음성 파일, 텍스트로 변환된 음성 기록, 메모까지 모두 파일로 다운로드할 수 있다. 다양한 파일 형식을 지원하기 때문에 원하는 포맷을 선택할 수 있다. 또한, 생성된 노트를 링크로 공유할 수 있다. 공유 링크를 통하면 편집한 내용까지 바로 확인할 수 있어 매우 간편하다.  노트 생성 시 사용 시간 차감? 클로바노트는 매월 기본 제공되는 시간만큼 무료로 사용가능 기본 제공 시간은 매월 갱신일까지 사용 가능하며, 사용 시간은 노트를 만들 때 녹음 또는 업로드할 파일의 길이에 따라 차감된다. 예를 들어, 5분짜리 노트를 만들면 5분의 사용 시간이 차감된다. 기본 제공 시간은 변경될 수 있으며, 남은 사용 시간은 이월되지 않고 갱신일에 자동 소멸된다.

wxxhe
0

랭체인코리아 밋업 2024 Q2 참가 신청페이지

안녕하세요~~ 랭체인코리아 오거나이저 유현아입니다. 지난 Q1에 이어서 밋업을 꾸려보았습니다.이번 Q2는 귀여운 컨셉에 맞춰 랭체인 입문자도 함께할 수 있는 난이도로 준비해봤습니다. 개요💠일시 : 2024년 6월 26일(수) 오후 7시 ~ 오후 9시반💠모집인원(선착순) : 정원 100명 (오버북 150명)💠1차신청(100명) : 2024년 6월 10일(월) 오후 1시 💠2차신청(50명) : 2024년 6월 17일(월) 오후 1시💠장소 : 한빛미디어 B동 리더스홀                (서울 서대문구 연희로2길 62)  💠주관 : 랭체인코리아 (LangChain KR)💠공동 주최 : 한빛앤, 인공지능팩토리💠후원 :  한빛미디어 프로그램시간 구분 주제  연사 비고19:00 ~ 19:20인사 및 등록 김태영, 유현아 19:20 ~ 19:50발표1Native RAG부터 Advanced RAG 톺아보기백혜림 19:50 ~ 20:20발표2초보자도 할 수 있는 고급RAG : 다중 에이전트와 LangGraph 제작테디노트(이경록) 20:20 ~ 20:30휴식   20:30 ~ 21:00발표3LCEL 치트시트김태영 21:00 ~ 21:30 이벤트 및 마무리   * 아래 프로그램은 현장 상황에 따라 변경이 될 수 있습니다. 양해 부탁드립니다.‘추후공개’ 부분은 현재 연사님들과 조율 중에 있어서, 조만간 공개드리겠습니다.  랭체인코리아 오거나이저본 행사를 도울 오거나이저분들입니다.💠김태영 “기술 발전이 빠른 LLM 기술을 함께 공부하고 공유하며 성장해요.” 💠유현아 “AI 기술의 긍정적인 가능성에 대한 깊은 관심으로 IT 커뮤니티의 운영진으로 활동하고 있습니다.” 💠장서연 “화려한 기술 뒤에 있는 사람이 제 주요 관심사입니다. 이번 밋업에 오시는 분들께서 어떠한 생각과 의지로 AI 기술을 발전시키고 활용하고 계신지, 그 자세한 이야기를 들을 생각에 벌써부터 신이 나네요!” 💠전미정 “쉽게 딥러닝 기술을 시작하고 도입할 수 있길 응원하며 기술을 공유하고 있습니다” 💠이지석 “다양한 사람들과 소통을 하며 기술을 공유하여 같이 성장하고 싶습니다~” 많은 관심 부탁드립니다.

현아
6

네이버가 제공하고 있는 생성형 AI 서비스 조사

현재 네이버에서 제공하고 있는 생성형 AI를 이용한 서비스들을 조사해보고자 합니다.https://clova.ai/hyperclova 위 링크에서 현재 제공하고 있는 서비스들을 전반적으로 볼 수 있습니다.하나씩 살펴보면 다음과 같습니다.AI를 이용한 상품 상세 설명 페이지 만들기 가비아CNS는 쇼핑몰 창업, 마켓 통합관리, 해외 진출, 광고·마케팅, 홈페이지 제작까지 커머스 인프라와 서비스를 제공하는 커머스 전문 기업입니다. 가비아CNS에서 제공하는 서비스 중 하나는 네이버의 멀티모달 모델인 하이퍼클로바를 사용해 고객들이 맞춤형으로 상세 페이지를 만들 수 있게 도와주는 툴을 제공하는 서비스입니다. 이 서비스를 사용하면 자신의 상품을 쿠팡, 컬리 등에 등록하고 싶지만 상세 페이지를 제작할 기술이 없는 고객들이 비교적 저렴한 비용으로 상세 페이지를 만들 수 있을 것 같습니다. 레터비 : 생성형 AI를 이용한 자기소개서 생성 서비스 디피랩에서 제공하는 생성형 AI를 이용한 자기소개서 작성 서비스에 하이퍼클로바가 사용되었습니다. 자기소개서 작성은 모든 사람들에게 쉽지 않은 일입니다. chatGPT 등 여러 글로벌 기업의 거대 챗봇은 훌륭한 작문 실력을 자랑하지만, 사람들을 감동시킬 만한 특이하고 특별한 글을 쓰는 것에 특화되어 있지는 않습니다. 그리고, 한국어를 잘하지만 메인 언어는 아니죠. 그런 측면에서, 현 시점 한국어를 가장 많이 학습한 거대 생성형 AI 모델인 하이퍼클로바를 사용한 서비스가 자기소개서 작성에는 가장 도움이 될 것 같습니다. 이외에도 많은 서비스들이 있습니다. 본 공모전을 통해 새로운 서비스들이 많이 개발되었으면 좋겠습니다. 감사합니다.  

쌀국수먹고싶다
0

CLOVA AI SERVICES

네이버 CLOVA (Cloud Virtual Assistant) AI Service는 네이버가 개발한 인공지능 기반의 다양한 서비스를 제공하는 플랫폼입니다. CLOVA는 다양한 AI 기술을 활용하여 사용자에게 유용한 기능을 제공하며, 주요 서비스는 다음과 같습니다:CLOVA Voice: 음성 인식 및 합성 기술을 기반으로 한 서비스로, 음성을 텍스트로 변환하거나 텍스트를 자연스러운 음성으로 변환하는 기능을 제공합니다.CLOVA OCR: Optical Character Recognition 기술을 이용하여 이미지나 문서에 포함된 텍스트를 인식하고 추출하는 서비스입니다. 이를 통해 스캔한 문서나 사진에서 텍스트 정보를 쉽게 얻을 수 있습니다.CLOVA Chatbot: 자연어 처리(NLP) 기술을 바탕으로 사용자의 질문에 대답하거나 특정 작업을 수행하는 챗봇을 개발할 수 있는 플랫폼입니다.CLOVA Face: 얼굴 인식 기술을 이용한 서비스로, 얼굴 인식 및 분석을 통해 식별된 얼굴에서 성별, 나이, 감정, 표정 등 복잡하고 다양한 특징 정보를 제공합니다.CLOVA Speech: 사람의 음성 신호의 파형을 분석하여 사람의 음성을 텍스트로 변환하는 기술입니다.CLOVA Translation: 다국어 번역 서비스를 제공하여 텍스트나 음성을 다른 언어로 번역하는 기능을 지원합니다. 이를 통해 글로벌 커뮤니케이션을 쉽게 할 수 있습니다.이 외에도 CLOVA AI Service는 네이버의 강력한 인공지능 기술을 바탕으로 다양한 산업 분야에서 활용될 수 있으며, 사용자는 이를 통해 보다 편리하고 효율적인 서비스를 경험할 수 있습니다. 네이버는 지속적으로 CLOVA의 기능을 확장하고 개선하여 더 많은 사용자에게 최적의 AI 솔루션을 제공하고 있습니다.

whalee
0

CLOVA의 의의

 GPT 를 비롯해서 다양한 LLM Backbone 모델이 발전했지만, 한국어 데이터를 기반으로 만들어진 LLM 은 아직 개발되지 않았습니다.비록 CLOVA 도 한국어 LLM 모델이 아닌 Backbone 모델을 활용했지만, 한국에서 한국어 데이터를 사용했다는 점에서 의의가 있는 것 같습니다.CLOVA 는 한국 문화를 잘 이해하는 데이터를 기반으로 네이버와 연계하여 확장성, 연결성, 최적화를 잘 구현하고 있습니다. 그렇기에 한국에서 LLM 을 활용하는 데 있어서 CLOVA 는 좋은 선택지가 될 것 같습니다.한편, sLLM 의 대표격인 Llama 와 비교해서 한국어에 한해서는 우수성을 갖습니다. Llama 는 GPT 와 같은 거대 LLM 을 적은 파라미터로 finetuning 하여, 학교나 작은 기업에서 까지 연구에 활용할 수 있도록 기여한 연구 중 하나입니다. GPT 와 같은 거대 LLM 대비 적은 파라미터로 Inference 및 Training 을 할 수 있는 것입니다. 하지만 한국어 데이터는 극소수이기 때문에 한국에 잘 동작하지 못한다는 단점이 있고, 이에 비해 CLOVA 는 한국어 데이터를 활용했기 때문에 보다 한국어에 큰 강점을 가집니다.결론적으로 한국어, 특히 한국어를 활용하는 서비스에 있어서 CLOVA 는 매우 매력적인 선택지가 될 것 같습니다.

Brighteast
0

랭체인코리아 밋업 2024Q2 안내

안녕하세요, 유현아입니다! 랭체인코리아 밋업 2024 Q2 소식 전달드립니다. 이번 밋업은 한빛앤과 함께합니다 :) 큐트한 컨셉에 맞춰 랭체인 입문자도 즐길 수 있는 밋업으로 준비했습니다. 6월 26일(수)에 직접 실습도 할 수 있는 세션과 다양한 이벤트로 인사드리겠습니다.개요모집인원(선착순) : 정원 100명 (오버북 150명)1차신청(100명) : 차주 공개2차신청(50명) : 차주 공개일시 : 2024년 6월 26일(수) 오후 7시 ~ 오후 9시반장소 : 한빛미디어(서울 서대문구 연희로2길 62) B동 리더스홀주관 : 랭체인코리아 (LangChain KR)공동 주최 : 한빛앤, 인공지능팩토리 프로그램시간 구분 주제  연사 비고19:00 ~ 19:20인사 및 등록 김태영, 유현아 19:20 ~ 19:50발표1LCEL 치트시트김태영 19:50 ~ 20:20발표2추후공개  20:20 ~ 20:30휴식   20:30 ~ 21:00발표3추후공개  21:00 ~ 21:30 이벤트 및 마무리   "추후공개" 부분은 현재 연사님들과 조율 중에 있어서, 조만간 공개드리겠습니다. 관련 주제로 사전질문이나 의견이 있으시면 댓글남겨주세요~ 많은 관심 부탁드려요~

현아
0