스위스 로봇 기업 RIVR은 영국 택배 기업 에브리와 파트너십을 맺고 로봇개를 택배 배송 현장에 투입한다고 발표했습니다. 로봇개는 택배 기사가 여러 집을 방문해야 하는 번거로움을 줄여줍니다. 택배 트럭에서 약 90m까지 이동하여 집까지 물품을 배송할 수 있기 때문입니다. 에브리는 로봇개 도입으로 택배 기사의 신체적 부담을 줄이고 택배 처리량을 늘릴 수 있을 것으로 기대하고 있습니다.
이 기술은 택배 산업의 효율성을 크게 향상시킬 수 있을 뿐만 아니라, 택배 기사의 업무 환경 개선에도 기여할 수 있을 것 같습니다. 로봇개가 더 많은 역할을 수행하게 되면, 택배 기사는 더욱 중요한 업무에 집중할 수 있게 될 것입니다.
오픈AI, 새 추론 AI모델 ‘o3’ 출시…“이미지 보고 생각 첫 모델”
OpenAI가 이미지 분석 및 해석이 가능한 새로운 AI 모델 ‘o3’를 출시했습니다.
‘o3’ 모델은 이전 모델보다 수학, 코딩, 추론, 과학 및 시각적 이해 능력 테스트에서 더 뛰어난 성능을 보입니다. 이 모델은 화이트보드, 그림, 차트 등 다양한 이미지를 분석할 수 있으며, 이미지 품질이 낮더라도 분석이 가능합니다.
이미지 분석 외에도 브라우저 내에서 직접 Python 코드를 실행하고 최신 이벤트에 대한 웹 검색을 수행할 수 있습니다.
OpenAI는 AI 기반 코딩 도구 회사인 Windsurf를 약 30억 달러(4조2510억원)에 인수하기 위해 협상 중인 것으로 알려졌습니다.
‘o3’ 모델의 이미지 분석 능력은 다양한 분야에서 활용될 수 있을 것으로 보입니다. 예를 들어, 의료 영상 분석, 자율 주행, 로봇 공학 등에 적용될 수 있습니다. OpenAI가 Windsurf를 인수하려는 것은 AI 기반 코딩 도구 시장에 진출하려는 의도로 해석됩니다. 이는 OpenAI가 AI 기술을 다양한 분야로 확장하려는 전략의 일환으로 보입니다.
[단독] 신규채용 대신 AI로 카카오의 인사 혁신
카카오는 코딩 등 인공지능(AI)으로 대체 가능한 직무에 대해 신규 채용을 제한하는 것을 고려하고 있다는 보도가 있었습니다. 이는 AI가 업무 생산성을 높이는 것을 넘어, 인력 자체를 대체하는 현상이 현실화되고 있음을 보여줍니다.
채용 플랫폼 분석 결과, 국내 IT 개발 직무 신규 채용 공고 수가 매년 감소하고 있으며, 신입 채용 비중이 매우 낮은 수준입니다.
판교의 한 IT 기업 CTO는 AI 기술 발전으로 인해 고용 안정성이 흔들리는 직군이 늘어날 것이라고 전망했습니다. 하지만 카카오는 신규 채용 제한 관련 가이드라인은 없으며, 관련 공지를 진행한 적도 없다고 공식적으로 밝혔습니다.
AI 기술의 발전은 기업의 채용 방식에 큰 영향을 미치고 있으며, 특히 AI로 대체 가능한 직무의 신규 채용은 더욱 줄어들 것으로 예상됩니다. 이는 신입 개발자들에게는 더욱 치열한 경쟁 환경을 의미하며, AI 시대에 필요한 역량을 갖추는 것이 중요해졌습니다. 기업들은 AI 도입을 통해 효율성을 높이는 동시에, 인력 구조 변화에 대한 고민이 필요합니다.
AI 시대의 또 다른 과제 ‘데이터 자신감 격차’··· IT 리더가 관리해야 할 이유
IT 임원을 포함한 최고 경영진은 조직의 데이터가 AI에 최적화되었다고 믿지만, 현업 IT 부서장들은 중요한 의사 결정에 부실한 데이터가 사용된다고 보고 있습니다. 이러한 인식 차이는 AI 모델 학습 및 데이터 기반 이니셔티브 진행 시 심각한 문제를 야기할 수 있습니다.
최고 경영진은 데이터 품질을 요약 보고서 형태로 접하는 반면, 현업 부서장들은 실제 시스템의 문제점을 직접 경험하기 때문에 이러한 차이가 발생합니다.
데이터 품질 문제의 원인은 분산된 IT 인프라, 단기적 성과 중심의 접근 방식, AI로의 급격한 전환 등 다양합니다.
기업은 데이터 전략의 균형을 맞추고, 투명성을 높이며, 데이터 문제를 지적할 수 있는 인력을 고용해야 합니다.
인식 차이의 위험성: 최고 경영진과 현업 부서장 간의 데이터 품질에 대한 인식 차이는 AI 프로젝트의 실패로 이어질 수 있습니다. 경영진은 현장의 문제를 간과하기 쉽고, 이는 잘못된 의사 결정으로 이어질 수 있습니다.
데이터 관리의 중요성: AI 도입에 앞서 데이터 관리 전략을 재정비해야 합니다. 단순히 AI 기술 도입에만 집중할 것이 아니라, 데이터의 품질과 접근성, 보안 등을 고려한 종합적인 전략이 필요합니다.
투명성과 소통의 필요성: 조직 전체에 걸쳐 데이터 관련 정보의 투명성을 높이고, 경영진과 현업 부서장 간의 소통을 강화해야 합니다. 이를 통해 데이터 문제에 대한 공동의 이해를 도출하고 해결책을 모색할 수 있습니다.
비판적 시각의 중요성: 프로젝트 초기 단계에서 데이터 문제점을 지적할 수 있는 인력을 확보하는 것이 중요합니다. 이는 프로젝트의 실패 위험을 줄이고, 장기적으로 비용을 절감하는 데 도움이 됩니다.
단계적 접근 방식: AI 프로젝트를 추진할 때, 한 번에 모든 것을 해결하려 하기보다는 ‘기어가기, 걷기, 달리기’와 같은 단계적 접근 방식을 취하는 것이 효과적입니다. 조직의 데이터 성숙도를 파악하고, 점진적으로 개선해 나가야 합니다.
골치아픈 AI 코딩 오류…MIT, 정확·효율 잡는 해법 제시
MIT 연구팀에서 개발한 인공지능 거대언어모델(LLM)의 코딩 정확성 향상 기술에 대한 내용입니다.
MIT 연구팀은 ‘순차 몬테카를로(SMC)’ 알고리즘을 개발하여 AI 코딩 시 문법 오류나 오작동을 줄이고 정확도를 높였습니다.
SMC 방식은 코드 생성 과정에서 여러 후보 코드 조각을 생성하고, 각 조각의 문법 및 의미 적합도에 따라 가중치를 부여하여 가능성이 낮은 조각을 제거하고 유망한 조각에 집중합니다.
실험 결과, SMC 방식은 기존 방식보다 적은 계산량으로도 높은 정확도를 보였으며, 특히 중소형 오픈소스 모델이 대형 상용 모델을 능가하는 결과를 보였습니다.
중소형 오픈소스 모델이 대형 상용 모델을 능가하는 결과는 AI 기술의 발전 방향에 시사하는 바가 큽니다. 앞으로 이 기술이 더욱 발전하여 비전문가도 자연어 설명만으로 복잡한 작업을 쉽게 수행할 수 있는 시대가 열릴 것으로 기대됩니다.
MS, CPU에서 실행하는 초고효율 AI 모델 ‘비트넷’ 출시
마이크로소프트(MS) 연구진이 개발한 초고효율 AI 모델 ‘비트넷(BitNet)’에 대한 내용을 요약하고 있습니다.
비트넷은 모델 가중치를 1비트 또는 낮은 비트로 압축하여 CPU와 같은 경량 하드웨어에서도 실행 가능하도록 설계된 AI 모델입니다.
MS는 20억 매개변수의 오픈 소스 모델 ‘비트넷 b1.58 2B4T’를 공개했으며, 이 모델은 애플 ‘M2’ 칩과 같은 CPU에서도 실행 가능하다는 특징이 있습니다.
비트넷 b1.58은 -1, 0, 1의 세 가지 값으로 양자화하여 극한의 최적화를 추구하며, 이를 통해 적은 메모리와 연산량으로 모델 실행이 가능합니다.
3300만 권의 책에 해당하는 약 4조 개의 토큰으로 훈련되었으며, 비슷한 크기의 기존 모델보다 성능이 뛰어나다고 합니다.
같은 크기의 다른 모델보다 최대 2배 빠르게 작동하며, 메모리 사용량도 적지만, MS의 전용 프레임워크(bitnet.cpp)를 사용할 때만 CPU에서 실행 가능하다는 단점이 있습니다.
비트넷은 AI 모델의 효율성을 극대화하여 더 다양한 환경에서 AI를 활용할 수 있는 가능성을 제시합니다. 특히, CPU에서도 실행 가능한 점은 AI 기술의 접근성을 높이는 데 기여할 것으로 보입니다. 다만, MS의 전용 프레임워크에서만 CPU 실행이 가능하다는 점은 향후 개선해야 할 부분입니다.
구글, 첫 하이브리드 추론 모델 ‘제미나이 2.5 플래시’ 공개…”가성비 가장 뛰어나”
구글이 처음으로 선보인 하이브리드 추론 모델인 ‘제미나이 2.5 플래시’에 대한 내용입니다.
제미나이 2.5 플래시는 추론 능력과 비용 효율성을 모두 갖춘 모델로, 복잡한 작업을 처리하면서도 많은 사용자가 접근할 수 있도록 설계되었습니다.
개발자들은 ‘사고 예산’을 설정하여 모델의 성능, 속도, 비용 간의 균형을 조절할 수 있습니다.
사고 예산이 높을수록 응답 품질은 향상되지만 속도는 느려지고 비용은 증가합니다.
벤치마크 테스트에서 제미나이 2.5 플래시는 향상된 추론 능력을 보여주었지만, OpenAI의 o3 모델에는 미치지 못했습니다.
이 모델은 ‘가성비’가 가장 좋은 모델로 소개되었으며, AI 모델 시장에서 다양한 요구를 충족시키려는 구글의 전략을 보여줍니다.
오픈AI, 새 추론 AI모델 ‘o3’ 출시…“이미지 보고 생각 첫 모델”
기업 현장에서 빠르게 확산되고 있는 생성형 AI 도구 10가지를 소개하고, 각 도구의 강점과 한계를 분석합니다. 2024년 전 세계 생성형 AI 시장 규모는 250억 달러를 넘어섰으며, 2033년에는 8,030억 달러에 이를 것으로 전망될 정도로 성장세가 가파릅니다.
챗GPT: 자연어 이해 및 생성 능력이 뛰어나 고객 응대, 보고서 작성 등에 활용되지만, 정확성이 일정하지 않고 감정 이해가 부족합니다.
마이크로소프트 코파일럿: MS 365 앱과 통합되어 생산성을 높이지만, 요약 시 핵심 내용을 놓치거나 브랜드 가이드라인에 부합하지 않을 수 있습니다.
구글 제미나이: 텍스트 외 이미지, 오디오, 비디오 처리 능력이 뛰어나지만, 구글 워크스페이스 환경에서만 활용도가 높고 정확성 문제가 발생할 수 있습니다.
메타AI: 페이스북, 인스타그램 등 메타 플랫폼과의 높은 접근성이 장점이지만, 개인정보 보호 문제가 고려되어야 합니다.
달리 3: 텍스트 기반 이미지 생성 도구로 챗GPT와 통합 기능이 강점이지만, 생성된 이미지가 AI 작품이라는 점이 쉽게 드러납니다.
런웨이ML: 텍스트, 이미지, 영상을 활용한 콘텐츠 제작 모델이지만, 일부 고급 기능은 학습이 어렵고 시스템 자원을 많이 요구합니다.
스테이블 디퓨전: 고해상도 이미지 생성 및 영상 제작이 가능하며, 경쟁 도구 대비 연산 요구량이 적습니다.
미드저니: 자연어 프롬프트 기반 이미지 생성 도구로, 생성된 이미지는 상업적으로 사용 가능하나 저작권 등록이 불가능합니다.
퍼플렉시티: AI 기반 검색 엔진으로, 웹과 내부 문서를 동시에 검색하는 기능을 제공합니다.
클로드: 윤리적 기준을 갖춘 AI 챗봇으로, 명확한 답변을 제공하지만 설명이 다소 장황한 경향이 있습니다.
생성형 AI의 광범위한 활용: 챗봇, 이미지 생성, 영상 제작, 검색 엔진 등 다양한 분야에서 생성형 AI 도구가 활용되고 있으며, 기업 생산성 향상에 기여할 수 있습니다.
도구별 특성 및 한계: 각 도구는 강점과 한계를 가지고 있으므로, 기업은 업무 특성에 맞는 도구를 선택하고, 결과물의 정확성을 검토해야 합니다.
보안 및 윤리적 고려: 개인정보 보호, 저작권 문제 등 보안 및 윤리적 측면을 충분히 고려해야 하며, AI 사용에 대한 가이드라인 마련이 필요합니다.
지속적인 투자 및 확장: 많은 기업들이 생성형 AI에 투자를 늘리고 있지만, 실제 프로젝트 확장에는 어려움을 겪고 있습니다. 이는 도구 수준과 활용 여건을 고려한 점진적인 접근이 필요함을 시사합니다.
오픈AI, 기술적 한계 왔나…’o3′ 등 최신 추론 AI 모델 ‘환각’ 더 심해져
오픈AI의 최신 AI 모델 ‘o3’와 ‘o4-미니’가 이전 모델보다 환각 현상이 심해져 기술적 한계를 보이고 있습니다.
테크크런치 등 주요 외신에 따르면 오픈AI는 사람에 대한 모델의 지식 정확도를 측정하는 사내 벤치마크인 퍼슨(Person) QA에서 ‘o3’가 33%의 질문에 대해 환각을 일으킨다는 사실을 발견했다. 이는 각각 16%와 14.8%를 기록한 오픈AI의 이전 추론 모델인 ‘o1’과 ‘o3-미니’ 대비 2배 이상 높은 것이다.
모델 신뢰성 문제: 환각 현상은 AI 모델의 신뢰성에 큰 영향을 미칠 수 있습니다. 특히, 정확성이 중요한 분야에서는 AI 활용에 신중해야 할 필요가 있습니다.
오픈AI의 과제: 오픈AI가 이번 환각 문제의 원인을 파악하고 해결하는 것은 매우 중요합니다. 이는 AI 기술 발전의 중요한 과제 중 하나입니다.
AI 기술 발전 방향: 이번 사례는 AI 기술 발전에 있어 정확성과 신뢰성 확보가 얼마나 중요한지를 보여줍니다.
앞으로 AI 기술은 단순히 성능 향상뿐만 아니라 신뢰성을 높이는 방향으로 발전해야 할 것입니다.
구글, 양자컴퓨터로 AI 판 뒤집는다…”5년 내 실용화 자신”
구글이 생성형 인공지능(AI) 개발을 가속화하기 위해 양자 컴퓨터 기술에 투자하고 있다는 내용을 담고 있습니다.
구글은 캘리포니아에 구글 양자 AI 연구소를 설립했으며, 최신 양자 칩 ‘윌로우’를 포함한 양자 컴퓨터 프로세서를 개발해 왔습니다.
구글은 AI 서비스 강화와 양자 시장 선도를 목표로 하고 있으며, 양자 기술을 활용하여 AI 학습 데이터 부족 문제와 같은 현재 AI의 한계를 극복하고자 합니다.
양자 컴퓨터는 새롭고 독특한 데이터를 생성할 수 있어 다양한 분야에 응용될 가능성이 있습니다. 구글 양자 컴퓨팅과 AI의 시너지 효과를 보여주는 대표적인 예는 단백질 구조 연구를 지원하고 노벨상을 수상한 AI 모델 ‘알파폴드’입니다.
구글은 앞으로 약 5년 안에 양자 컴퓨터 기반의 획기적이고 실용적인 응용 분야가 개발될 것으로 기대하고 있습니다.
구글의 이러한 투자는 AI 기술의 미래를 위한 중요한 발걸음으로 보입니다. 양자 컴퓨팅 기술이 AI의 한계를 극복하고 새로운 가능성을 열어줄 수 있을 것이라 기대됩니다.
AI가 30초 만에 미세 불량 감지… “4無 드림 팩토리”
LG이노텍이 대한민국 구미에 건설한 차세대 반도체 기판인 FC-BGA (플립 칩 볼 그리드 어레이) 생산 시설인 ‘드림 팩토리’에 대해 설명합니다.
이 공장은 AI, 딥러닝, 로봇, 디지털 트윈과 같은 첨단 기술을 활용하여 생산 공정을 자동화하고 인적 개입을 최소화합니다.
이 시설은 인력 투입, 결함, 고장 및 안전 사고를 없애는 “4무(無)” 첨단 공장을 목표로 합니다.
AI는 방대한 생산 데이터(매일 100GB)를 분석하여 30초 이내에 결함을 예측하고 감지하는 데 중요한 역할을 수행하여 리드 타임과 인력을 크게 줄입니다.
LG이노텍은 2030년까지 시장이 두 배로 성장할 것으로 예상되는 FC-BGA 시장에서 기존의 일본 및 대만 기업들과 경쟁하는 것을 목표로 합니다.
회사는 2026년 PC CPU 시장을 목표로 하고 그 직후 서버 시장을 목표로 하여 2030년까지 FC-BGA 사업을 조 단위 규모로 확장할 계획입니다.
LG이노텍의 드림 팩토리는 첨단 기술을 활용하여 생산 효율성을 극대화하고 품질을 향상시키려는 노력을 보여줍니다. 특히 AI를 활용한 결함 감지 시스템은 생산 과정에서 발생할 수 있는 문제를 신속하게 해결하여 제품의 신뢰성을 높이는 데 기여할 것으로 보입니다.
AI와 데이터를 활용한 환자 흐름 개선 사례
인공지능과 데이터가 병원의 환자 흐름 개선에 어떻게 활용되고 있는지, 특히 한림대학교 성심병원의 사례를 중심으로 설명합니다.
한림대학교 성심병원은 예약부터 치료 후 관리까지 전반적인 과정을 효율화하기 위해 인공지능 기반 시스템을 도입했습니다.
인공지능을 활용하여 MRI 검사 시간을 예측함으로써 대기 시간을 줄이고 검사 건수를 늘렸습니다. 데이터 분석을 통해 환자 이동 패턴을 분석하고 인력 배치를 최적화하여 환자 중심의 효율적인 환경을 구축하고자 합니다.
실시간 환자 흐름 모니터링 및 관리를 위한 디지털 트윈 시스템 구축 등 인공지능 및 데이터 기반 시스템을 지속적으로 발전시킬 계획입니다.
인공지능과 데이터 분석은 병원 운영 효율성을 극대화하고 환자 만족도를 높이는 데 중요한 역할을 할 수 있습니다. 특히, MRI 검사 시간 예측과 같이 구체적인 문제 해결에 인공지능을 적용함으로써 가시적인 성과를 얻을 수 있습니다. 디지털 트윈 시스템과 같은 첨단 기술을 통해 병원 운영을 더욱 스마트하게 관리하고 환자에게 더 나은 의료 서비스를 제공할 수 있을 것으로 기대됩니다.
CommaSeparatedListOutputParser는 LangChain 프레임워크에서 제공하는 강력한 출력 파서 중 하나로, 언어 모델(LLM)의 텍스트 응답을 쉼표(,)로 구분된 리스트 형태로 변환하는 데 사용됩니다. 이를 통해 언어 모델이 생성한 비구조화된 텍스트 데이터를 구조화된 리스트 형태로 가공하여, 후속 작업에서 보다 쉽게 활용할 수 있도록 돕습니다. 예를 들어, “인기 있는 한국 음식 5가지” 또는 “대한민국 관광 명소 5곳”과 같은 질문에 대해 쉼표로 구분된 텍스트 응답을 받아 이를 Python 리스트로 변환할 수 있습니다.
이 파서는 특히 데이터 가공, API 응답 처리, 또는 데이터 분석과 같은 작업에서 유용합니다.
주요 기능
쉼표로 구분된 텍스트를 리스트로 변환: 언어 모델이 쉼표로 항목을 구분한 텍스트를 반환하면, 이를 Python 리스트로 자동 변환합니다.
데이터 가독성 향상: 비구조화된 텍스트를 구조화된 형태로 변환하여 코드 내에서 쉽게 다룰 수 있도록 합니다.
다양한 작업에 활용 가능: 리스트 형태의 데이터가 필요한 데이터베이스 입력, UI 표시, 또는 후속 처리 작업에 적합합니다.
사용 예제
CommaSeparatedListOutputParser를 활용하여 EXAone 3.5 모델을 기반으로 LangChain에서 “대한민국 관광 명소 5곳”을 요청하고, 결과를 리스트로 변환하는 과정을 살펴보겠습니다. 아래는 이를 구현한 코드와 실행 결과입니다.
예제 1: 기본 호출
from langchain_core.output_parsers import CommaSeparatedListOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
# 콤마로 구분된 리스트 출력 파서 초기화
output_parser = CommaSeparatedListOutputParser()
# 출력 형식 지침 가져오기
format_instructions = output_parser.get_format_instructions()
# 프롬프트 템플릿 설정
prompt = PromptTemplate(
template="다음 주제에 대해 5가지 항목을 한국어로 나열해주세요.\n{subject}\n{format_instructions}",
input_variables=["subject"],
partial_variables={"format_instructions": format_instructions + "\n답변은 반드시 한국어로 작성해주세요."},
)
# EXAone 3.5 모델 초기화
llm_model = ChatOllama(model="exaone3.5")
# 프롬프트, 모델, 출력 파서를 연결하여 체인 생성
chain = prompt | llm_model | output_parser
# "대한민국 관광 명소"에 대한 체인 호출
result = chain.invoke({"subject": "대한민국 관광 명소"})
print(result)
PydanticOutputParser는 LangChain 프레임워크에서 제공하는 강력한 출력 파서로, 대형 언어 모델(LLM)의 텍스트 출력을 구조화된 Python 객체로 변환하는 데 사용됩니다. 이 파서는 Pydantic 라이브러리를 기반으로 동작하며, 사전에 정의된 데이터 스키마에 따라 LLM의 출력을 검증하고 매핑하여 개발자가 원하는 형식으로 데이터를 쉽게 활용할 수 있도록 돕습니다. 특히, 복잡한 텍스트 데이터를 JSON, 리스트, 또는 사용자 정의 클래스의 인스턴스로 변환하는 데 유용합니다.
주요 특징 및 기능
구조화된 데이터 변환 PydanticOutputParser는 LLM의 비구조화된 텍스트 출력을 JSON 객체, 리스트, 혹은 Pydantic 모델 기반의 사용자 정의 객체로 변환합니다. 이를 통해 데이터를 체계적으로 관리하고, 후속 처리나 분석 작업을 간소화할 수 있습니다.
Croatia 데이터 모델 정의** Pydantic의 BaseModel 클래스를 사용하여 출력 데이터의 스키마를 정의합니다. 이 스키마에는 필드 이름, 데이터 타입, 필수 여부 등이 포함되며, 이를 통해 LLM의 출력이 기대한 형식을 충족하는지 검증합니다. 잘못된 데이터가 입력될 경우, Pydantic이 자동으로 오류를 감지하여 안정적인 데이터 처리를 보장합니다.
자동 매핑 및 검증 정의된 스키마에 따라 LLM의 출력을 자동으로 매핑하고, 데이터의 유효성을 검증합니다. 예를 들어, 특정 필드가 문자열이어야 하거나 필수값이 누락되지 않도록 강제할 수 있습니다. 이 과정은 수작업으로 데이터를 처리하는 번거로움을 줄여줍니다.
유연한 출력 형식 지정 PydanticOutputParser는 get_format_instructions() 메서드를 통해 LLM이 따라야 할 출력 형식 지침을 제공합니다. 이 지침은 JSON 스키마 형태로 제공되며, LLM이 구조화된 출력을 생성하도록 유도합니다.
PydanticOutputParser는 두 가지 주요 메서드를 통해 동작합니다:
get_format_instructions() 이 메서드는 LLM이 출력해야 할 데이터의 형식과 구조를 설명하는 지침을 문자열 형태로 반환합니다. 예를 들어, JSON 스키마를 기반으로 필드 이름, 타입, 설명 등을 명시하여 LLM이 해당 형식에 맞는 출력을 생성하도록 안내합니다. 이 지침은 프롬프트에 포함되어 LLM의 출력 형식을 제어하는 데 중요한 역할을 합니다.
parse() LLM이 생성한 텍스트 출력을 입력받아 이를 사전에 정의된 Pydantic 모델로 파싱합니다. 이 과정에서 출력이 스키마를 준수하는지 검증하고, 유효한 경우 해당 모델의 인스턴스로 변환합니다. 만약 출력이 스키마와 맞지 않으면, Pydantic이 오류를 발생시켜 문제를 즉시 파악할 수 있습니다.
예제: 이메일 내용 파싱
아래는 PydanticOutputParser를 사용하여 이메일 내용을 파싱하는 예제입니다. 이 예제에서는 이메일의 주요 정보를 추출하여 구조화된 형식으로 변환합니다.
이메일 본문
From: 김철수 (chulsoo.kim@bikecorporation.me)To: 이은채 (eunchae@teddyinternational.me)Subject: “ZENESIS” 자전거 유통 협력 및 미팅 일정 제안 안녕하세요, 이은채 대리님,저는 바이크코퍼레이션의 김철수 상무입니다. 최근 보도자료를 통해 귀사의 신규 자전거 “ZENESIS”에 대해 알게 되었습니다. 바이크코퍼레이션은 자전거 제조 및 유통 분야에서 혁신과 품질을 선도하는 기업으로, 이 분야에서의 장기적인 경험과 전문성을 가지고 있습니다.ZENESIS 모델에 대한 상세한 브로슈어를 요청드립니다. 특히 기술 사양, 배터리 성능, 그리고 디자인 측면에 대한 정보가 필요합니다. 이를 통해 저희가 제안할 유통 전략과 마케팅 계획을 보다 구체화할 수 있을 것입니다.또한, 협력 가능성을 더 깊이 논의하기 위해 다음 주 화요일(1월 15일) 오전 10시에 미팅을 제안합니다. 귀사 사무실에서 만나 이야기를 나눌 수 있을까요? 감사합니다. 김철수상무이사바이크코퍼레이션
출력 파서 없이 처리한 경우:
먼저, 출력 파서를 사용하지 않고 이메일 내용을 요약하는 코드를 살펴보겠습니다.
from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
llm_model = ChatOllama(model="exaone3.5", temperature=0)
prompt = PromptTemplate.from_template(
"다음의 이메일 내용 중 중요한 내용을 추출해 주세요.\n\n{email_conversation}"
)
chain = prompt | llm_model
response = chain.invoke({"email_conversation": email_conversation})
print(response.content)
주요 목적: “ZENESIS” 자전거 모델에 대한 정보 요청 (브로슈어, 특히 기술 사양, 배터리 성능, 디자인) 자전거 유통 협력 가능성 논의를 위한 미팅 제안
미팅 제안: 날짜: 1월 15일 화요일 시간: 오전 10시 장소: 테디인터내셔널 사무실
이러한 내용들이 협력 및 미팅 계획의 핵심입니다.
이 결과는 텍스트 형식으로 요약된 내용이지만, 구조화된 데이터로 활용하기에는 추가 처리가 필요합니다. 이를 해결하기 위해 PydanticOutputParser를 사용해 보겠습니다.
PydanticOutputParser를 사용한 구조화된 출력:
다음은 PydanticOutputParser를 활용하여 이메일의 주요 정보를 구조화된 객체로 변환하는 예제입니다.
from langchain_ollama import ChatOllama
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
from pydantic import BaseModel, Field
# Pydantic 모델 정의
class EmailSummary(BaseModel):
from_person: str = Field(description="메일을 보낸 사람의 이름")
from_email: str = Field(description="메일을 보낸 사람의 이메일 주소")
to_person: str = Field(description="메일을 받는 사람의 이름")
to_email: str = Field(description="메일을 받는 사람의 이메일 주소")
subject: str = Field(description="메일 제목")
summary: str = Field(description="메일 본문을 요약한 텍스트")
date: str = Field(description="메일 본문에 언급된 미팅 날짜와 시간")
# PydanticOutputParser 생성
parser = PydanticOutputParser(pydantic_object=EmailSummary)
# 프롬프트 정의
prompt = PromptTemplate.from_template("""
You are an assistant to make JSON format.
Please do not answer your opinion by adding ```.
Do not use quotes in strings within JSON.
QUESTION:
{question}
EMAIL CONVERSATION:
{email_conversation}
FORMAT:
Do not use quotes in strings within JSON.\n
{format}
""")
# 프롬프트에 포맷 지침 추가
prompt = prompt.partial(format=parser.get_format_instructions())
# LLM 모델 설정
llm_model = ChatOllama(model="exaone3.5", temperature=0)
# 체인 구성
chain = prompt | llm_model
# 체인 실행
result = chain.invoke({
"email_conversation": email_conversation,
"question": "이메일 내용 중 주요 내용을 추출해 주세요.",
})
# 결과 파싱
structured_output = parser.parse(result.content)
print(structured_output)
from_person=’김철수’ from_email=’chulsoo.kim@bikecorporation.me’ to_person=’이은채’ to_email=’eunchae@teddyinternational.me’ subject=’ZENESIS 자전거 유통 협력 및 미팅 일정 제안’ summary=’김철수 상무는 이은채 대리에게 바이크코퍼레이션의 자전거 제조 및 유통 전문성을 강조하며, ZENESIS 모델의 브로슈어 요청과 함께 기술 사양, 배터리 성능, 디자인 정보를 요청했습니다. 또한, 협력 가능성을 논의하기 위해 1월 15일 화요일 오전 10시에 미팅을 제안했습니다.’ date=’1월 15일 화요일 오전 10시’
이 결과는 EmailSummary 클래스의 인스턴스로 반환되며, 각 필드가 명확하게 구조화되어 있어 데이터베이스 저장, API 응답, 또는 추가 처리에 바로 활용할 수 있습니다.
출력 파서를 체인에 통합:
PydanticOutputParser를 체인에 직접 포함시켜 LLM의 출력을 바로 Pydantic 객체로 변환할 수 있습니다.
# 체인 구성 (파서 포함)
chain = prompt | llm_model | parser
# 체인 실행
response = chain.invoke({
"email_conversation": email_conversation,
"question": "이메일 내용 중 주요 내용을 추출해 주세요.",
})
print(response)
from_person=’김철수’ from_email=’chulsoo.kim@bikecorporation.me’ to_person=’이은채’ to_email=’eunchae@teddyinternational.me’ subject=’ZENESIS 자전거 유통 협력 및 미팅 일정 제안’ summary=’김철수 상무는 이은채 대리에게 바이크코퍼레이션의 자전거 제조 및 유통 전문성을 강조하며, ZENESIS 모델의 브로슈어 요청과 함께 기술 사양, 배터리 성능, 디자인 정보를 요청했습니다. 또한, 협력 가능성을 논의하기 위해 1월 15일 화요일 오전 10시에 미팅을 제안했습니다.’ date=’1월 15일 화요일 오전 10시’
이 방식은 별도의 파싱 단계를 생략하고, 체인 실행 결과로 바로 Pydantic 객체를 얻을 수 있어 더욱 간결합니다.
with_structured_output() 활용
LangChain의 with_structured_output() 메서드는 LLM의 출력을 구조화된 형식으로 반환하는 간편한 방법입니다. 이 메서드는 JSON 스키마 또는 Pydantic 모델을 입력으로 받아, LLM의 출력을 해당 형식으로 자동 변환합니다. 단, exaone3.5 모델은 구조화된 출력용 도구 호출 기능을 지원하지 않으므로, 이 예제에서는 llama3.2 모델을 사용합니다.
예제: with_structured_output() 사용
from langchain_ollama import ChatOllama
from pydantic import BaseModel, Field
# Pydantic 모델 정의
class EmailSummary(BaseModel):
from_person: str = Field(description="메일을 보낸 사람의 이름")
from_email: str = Field(description="메일을 보낸 사람의 이메일 주소")
to_person: str = Field(description="메일을 받는 사람의 이름")
to_email: str = Field(description="메일을 받는 사람의 이메일 주소")
subject: str = Field(description="메일 제목")
summary: str = Field(description="메일 본문을 요약한 텍스트")
date: str = Field(description="메일 본문에 언급된 미팅 날짜와 시간")
# LLM 모델 설정
llm_model_with_structured = ChatOllama(model="llama3.2", format="json").with_structured_output(EmailSummary)
# 실행
response = llm_model_with_structured.invoke(email_conversation)
print(response)
from_person=’kim, chulsoo.kim@bikecorporation.me’ from_email=’chulsoo.kim@bikecorporation.me’ to_person=’Lee Eun Chae, eunchae@teddyinternational.me’ to_email=’eunchae@teddyinternational.me’ subject=’ZENESIS 자전거 유통 협력 및 미팅 일정 제안’ summary=’바이크코퍼레이션의 김철수 상무가 이은채 대리님에게 ZENESIS 모델에 대한 브로슈어를 요청하여 discussion을 위한 미팅 연장을 제안합니다.’ date=’2023-01-15 10:00:00′
with_structured_output()의 장점
간편성: 프롬프트나 출력 파서를 별도로 설정할 필요 없이, 모델에 스키마를 전달하면 자동으로 구조화된 출력을 생성합니다.
통합성: LangChain의 다른 기능과 쉽게 결합하여 복잡한 워크플로우를 구성할 수 있습니다.
자동화: 스키마 포맷팅과 출력 파싱 과정을 자동으로 처리하여 개발자의 작업 부담을 줄입니다.
주의사항
모델 지원 여부 with_structured_output()은 도구 호출(tool calling)을 지원하는 모델에서만 동작합니다. exaone3.5는 이 기능을 지원하지 않으므로, 대체 모델(예: llama3.2)을 사용해야 합니다.
정확한 스키마 정의 Pydantic 모델의 Field에 포함된 description은 LLM이 데이터를 올바르게 추출하는 데 중요한 역할을 합니다. 따라서 설명은 명확하고 구체적이어야 합니다.
프롬프트 최적화 PydanticOutputParser를 사용할 때는 get_format_instructions()를 통해 제공되는 지침을 프롬프트에 포함해야 하며, 프롬프트의 질문과 지침이 LLM의 출력에 직접적인 영향을 미칩니다.
PydanticOutputParser와 with_structured_output()은 LangChain에서 LLM의 출력을 구조화된 데이터로 변환하는 데 매우 유용한 도구입니다. PydanticOutputParser는 프롬프트와 파서를 통해 세밀한 제어가 가능하며, with_structured_output()은 간단하고 자동화된 방식으로 구조화된 출력을 제공합니다. 이를 활용하면 이메일 파싱, 데이터 추출, API 응답 생성 등 다양한 작업을 효율적으로 수행할 수 있습니다. 특히, Pydantic의 강력한 데이터 검증 기능을 통해 안정적이고 신뢰할 수 있는 데이터 처리가 가능하다는 점에서 큰 장점을 가집니다.
LangChain 프레임워크에서 **출력 파서(Output Parser)**는 언어 모델(LLM)의 출력을 구조화하고, 더 유용한 형태로 변환하는 핵심적인 역할을 담당합니다. 언어 모델은 텍스트를 생성하는 데 탁월하지만, 그 출력은 종종 자유로운 형태의 텍스트로 나타나며, 이를 바로 애플리케이션에서 사용하기에는 적합하지 않을 수 있습니다. 출력 파서는 이러한 자유 형식의 텍스트를 JSON, 리스트, 딕셔너리와 같은 구조화된 데이터로 변환하여 개발자가 데이터를 쉽게 처리하고 활용할 수 있도록 돕습니다. 특히, EXAOne 3.5와 같은 고성능 언어 모델을 Ollama 기반의 LangChain 환경에서 사용할 때, 출력 파서는 애플리케이션의 효율성과 정확성을 크게 향상시킵니다.
이 챕터에서는 출력 파서의 역할, 주요 특징, 이점, 그리고 실제 사용 사례를 통해 출력 파서가 어떻게 LangChain 기반 애플리케이션 개발에 기여하는지 자세히 살펴보겠습니다.
출력파서의 역할:
출력 파서는 언어 모델의 출력을 받아 이를 더 적합한 형식으로 변환하는 도구입니다. 언어 모델은 일반적으로 텍스트를 생성하지만, 이 텍스트는 때로는 비정형적이거나 애플리케이션에서 바로 사용하기 어려운 형태일 수 있습니다. 출력 파서는 이러한 문제를 해결하며, 다음과 같은 역할을 수행합니다:
구조화된 데이터 생성: 자유 형식의 텍스트를 JSON, 리스트, 딕셔너리 등의 구조화된 데이터로 변환합니다. 이를 통해 데이터를 체계적으로 저장하거나 후속 처리에 활용할 수 있습니다.
출력 형식 표준화: 언어 모델의 출력은 일관되지 않을 수 있습니다. 출력 파서는 출력 형식을 표준화하여 일관된 데이터를 제공합니다.
복잡한 데이터 처리: 이메일, 문서, 대화 로그 등에서 특정 정보를 추출하거나 재구성하는 데 유용합니다.
애플리케이션 통합: 출력 파서를 통해 변환된 데이터는 데이터베이스 저장, API 호출, 또는 UI 표시 등 다양한 애플리케이션 작업에 바로 사용될 수 있습니다.
주요 특징:
LangChain은 다양한 출력 파서를 제공하며, 이들은 다음과 같은 주요 특징을 갖습니다:
다양성: LangChain은 JSON, CSV, 리스트, Pydantic 객체 등 다양한 출력 형식을 지원하는 파서를 제공합니다. 개발자는 애플리케이션의 요구사항에 맞는 파서를 선택할 수 있습니다.
스트리밍 지원: 대규모 데이터 처리나 실시간 애플리케이션에서 유용하도록, 많은 출력 파서가 스트리밍을 지원합니다. 이를 통해 데이터를 점진적으로 처리할 수 있습니다.
확장성: 간단한 텍스트 파싱부터 복잡한 데이터 구조로의 변환까지, 출력 파서는 확장 가능한 인터페이스를 제공합니다. 이를 통해 개발자는 최소한의 코드로 복잡한 작업을 수행할 수 있습니다.
사용자 정의 가능: LangChain은 사용자 정의 출력 파서를 만들 수 있는 유연한 API를 제공하여, 특정 요구사항에 맞춘 파싱 로직을 구현할 수 있습니다.
출력 파서를 사용하면 다음과 같은 이점을 얻을 수 있습니다:
구조화: 언어 모델의 자유 형식 텍스트를 체계적인 데이터 구조로 변환하여, 데이터를 더 쉽게 분석하고 활용할 수 있습니다.
일관성: 출력 형식을 일관되게 유지함으로써, 후속 처리 과정에서 오류를 줄이고 예측 가능한 결과를 얻을 수 있습니다.
유연성: JSON, 리스트, 딕셔너리, Pydantic 객체 등 다양한 출력 형식으로 변환할 수 있어, 다양한 애플리케이션 시나리오에 적응 가능합니다.
효율성: 출력 파서를 사용하면 수작업으로 데이터를 처리할 필요가 없어 개발 시간이 단축되고, 코드의 유지보수가 쉬워집니다.
출력 파서의 활용 가능성을 보여주기 위해, 두 가지 예제를 통해 출력 파서가 어떻게 사용되는지 살펴보겠습니다.
예제 1: 이메일 내용에서 중요 정보 추출
다음은 바이크코퍼레이션의 김철수 상무가 테디인터내셔널의 이은채 대리에게 보낸 이메일의 내용입니다. 이 이메일에서 중요한 정보를 추출하여 구조화된 형태로 변환하는 과정을 살펴보겠습니다.
원본 이메일 텍스트:
발신자: 김철수 (chulsoo.kim@bikecorporation.me)수신자: 이은채 (eunchae@teddyinternational.me)제목: “ZENESIS” 자전거 유통 협력 및 미팅 일정 제안 안녕하세요, 이은채 대리님, 저는 바이크코퍼레이션의 김철수 상무입니다. 저희 회사의 신규 자전거 모델 “ZENESIS”의 유통 협력을 논의하고자 연락드렸습니다. ZENESIS 모델의 상세한 브로슈어(기술 사양, 배터리 성능, 디자인 정보 포함)를 요청드립니다. 또한, 협력 논의를 위해 다음 주 화요일(1월 15일) 오전 10시에 귀사 사무실에서 미팅을 제안드립니다. 편리한 일정인지 확인 부탁드립니다. 감사합니다.김철수, 상무이사바이크코퍼레이션
출력 파서 없이 처리했을 때: 언어 모델이 이 텍스트를 처리하면, 단순히 요약된 텍스트나 비정형적인 결과를 반환할 가능성이 높습니다. 예를 들어:
김철수가 이은채에게 ZENESIS 자전거 브로슈어를 요청하고, 1월 15일 미팅을 제안함.
이런 출력은 정보를 체계적으로 활용하기 어렵습니다.
출력 파서를 사용했을 때: LangChain의 구조화된 출력 파서(예: PydanticOutputParser 또는 JsonOutputParser)를 사용하면, 다음과 같은 구조화된 데이터를 얻을 수 있습니다:
{ “sender”: { “name”: “김철수”, “email”: “chulsoo.kim@bikecorporation.me”, “title”: “상무이사”, “company”: “바이크코퍼레이션” }, “recipient”: { “name”: “이은채”, “email”: “eunchae@teddyinternational.me” }, “subject”: “\”ZENESIS\” 자전거 유통 협력 및 미팅 일정 제안”, “requests”: [ “ZENESIS 모델의 상세한 브로슈어 요청 (기술 사양, 배터리 성능, 디자인 정보 포함)” ], “meeting”: { “date”: “1월 15일”, “time”: “오전 10시”, “location”: “귀사 사무실” } }
이와 같이 출력 파서를 사용하면, 이메일의 주요 정보를 체계적으로 추출하여 데이터베이스에 저장하거나, 일정 관리 시스템에 통합하는 등의 작업을 쉽게 수행할 수 있습니다.
예제 2: JSON 형식의 요약 생성
이번에는 언어 모델이 생성한 텍스트를 JSON 형식으로 요약하는 사례를 살펴보겠습니다. 예를 들어, 언어 모델이 위 이메일 내용을 요약한 결과가 다음과 같다고 가정합니다:
언어 모델 출력:
바이크코퍼레이션의 김철수 상무가 테디인터내셔널의 이은채 대리에게 신규 자전거 “ZENESIS” 모델에 대한 브로슈어와 기술 사양, 배터리 성능, 디자인 정보를 요청했습니다. 또한, 1월 15일 오전 10시에 협력 논의를 위한 미팅을 제안했습니다.
출력 파서 적용 결과: LangChain의 JsonOutputParser를 사용하여 위 텍스트를 다음과 같은 JSON 형식으로 변환할 수 있습니다:
{ “person”: “김철수”, “email”: “chulsoo.kim@bikecorporation.me”, “recipient”: “이은채”, “recipient_email”: “eunchae@teddyinternational.me”, “subject”: “\”ZENESIS\” 자전거 유통 협력 및 미팅 일정 제안”, “summary”: “바이크코퍼레이션의 김철수 상무가 회사의 이은채 대리에게 신규 자전거 ‘ZENESIS’ 모델에 대한 브로슈어 요청과 기술 사양, 배터리 성능, 디자인 정보 요청. 또한, 협력 논의를 위해 1월 15일 오전 10시에 미팅 제안.”, “date”: “1월 15일 오전 10시”, “location”: “귀사 사무실” }
이 JSON 출력은 API 응답, 데이터베이스 입력, 또는 다른 시스템과의 통합에 바로 사용될 수 있습니다.
LangChain에서 출력 파서를 사용하는 기본적인 흐름은 다음과 같습니다:
출력 파서 선택: LangChain에서 제공하는 출력 파서 중 애플리케이션 요구사항에 맞는 파서를 선택합니다. 예를 들어, JSON 출력이 필요하다면 JsonOutputParser를, Pydantic 객체가 필요하다면 PydanticOutputParser를 사용할 수 있습니다.
프롬프트 설계: 언어 모델에 출력 파서가 기대하는 형식으로 출력을 생성하도록 프롬프트를 설계합니다. 예를 들어, JSON 형식을 요청하는 지침을 포함할 수 있습니다.
출력 파싱: 언어 모델의 출력을 출력 파서에 전달하여 구조화된 데이터를 얻습니다.
결과 활용: 파싱된 데이터를 애플리케이션의 후속 작업(데이터베이스 저장, API 호출 등)에 활용합니다.
LangChain의 출력 파서는 언어 모델의 출력을 구조화하고, 애플리케이션에서 바로 사용할 수 있는 형태로 변환하는 강력한 도구입니다. 출력 파서는 데이터 처리의 효율성과 정확성을 크게 향상시킵니다. 다양한 출력 형식 지원, 스트리밍 기능, 확장 가능한 인터페이스 등의 특징을 통해 개발자는 복잡한 데이터 처리 작업을 간소화할 수 있습니다.
다이나믹 퓨샷 프롬프트(Dynamic Few-Shot Prompting)는 대규모 언어 모델(LLM)을 활용하여 특정 작업에 최적화된 응답을 생성하기 위한 고급 프롬프트 엔지니어링 기법입니다. 이 기법은 정적인 프롬프트와 달리, 작업의 맥락이나 입력 데이터에 따라 동적으로 예제를 선택하거나 생성하여 모델의 성능을 향상시킵니다
다이나믹 퓨샷 프롬프트의 개념
퓨샷 러닝(Few-Shot Learning)은 모델이 소수의 예제를 통해 새로운 작업을 학습하도록 유도하는 방법입니다. 다이나믹 퓨샷 프롬프트는 이러한 예제를 고정적으로 제공하는 대신, 입력 데이터의 특성, 작업 유형, 또는 사용자 요구사항에 따라 예제를 동적으로 선택하거나 생성합니다. 이는 모델이 더 관련성 높은 맥락을 이해하고, 작업에 최적화된 출력을 생성하도록 돕습니다.
주요 특징
맥락 적응성: 입력 데이터에 따라 가장 적합한 예제를 선택하거나 생성.
효율성: 불필요한 예제를 배제하여 프롬프트의 길이를 최적화.
확장성: 다양한 작업과 도메인에 적용 가능.
성능 최적화: 모델의 응답 품질을 개선하고, 오답 가능성을 줄임.
다이나믹 퓨샷 프롬프트를 설계할 때 고려해야 할 주요 원칙은 다음과 같습니다:
예제 관련성: 선택된 예제는 입력 데이터와 작업의 맥락에 밀접하게 관련되어야 합니다. 예를 들어, 감정 분석 작업에서는 입력 문장의 감정 톤과 유사한 예제를 선택하는 것이 중요합니다.
다양성: 예제는 작업의 다양한 측면을 커버해야 하며, 편향된 결과를 방지하기 위해 균형 잡힌 데이터셋에서 추출되어야 합니다.
최적화된 예제 수: 너무 많은 예제는 토큰 제한을 초과하거나 모델을 혼란스럽게 할 수 있습니다. 일반적으로 3~5개의 예제가 적절합니다.
동적 생성: 예제를 실시간으로 생성하거나 데이터베이스에서 검색하여 프롬프트에 통합.
명확한 지시사항: 프롬프트는 작업의 목표와 기대되는 출력 형식을 명확히 정의해야 합니다.
다음은 감정 분석 작업을 위한 다이나믹 퓨샷 프롬프트 구현 예제입니다.
사용자가 입력한 문장의 감정을 긍정, 부정, 중립으로 분류하는 작업을 수행한다고 가정합니다. 다이나믹 퓨샷 프롬프트는 입력 문장의 특성(예: 키워드, 문장 길이)에 따라 적합한 예제를 선택합니다.
from langchain.prompts import PromptTemplate
from langchain_ollama import OllamaLLM
from langchain.chains import LLMChain
import random
llm = OllamaLLM(model="exaone3.5")
example_db = [
{"text": "이 영화 정말 재미있었어요!", "label": "긍정"},
{"text": "서비스가 너무 느려서 짜증났습니다.", "label": "부정"},
{"text": "제품은 괜찮은데 배송이 좀 늦었네요.", "label": "중립"},
{"text": "최고의 경험이었어요!", "label": "긍정"},
{"text": "별로였어요, 기대 이하였습니다.", "label": "부정"}
]
def select_dynamic_examples(input_text, num_examples=3):
keywords = input_text.split()
scored_examples = []
for example in example_db:
score = sum(1 for word in keywords if word in example["text"])
scored_examples.append((score, example))
scored_examples.sort(key=lambda x: x[0], reverse=True)
selected = [ex[1] for ex in scored_examples[:num_examples]]
return selected
prompt_template = PromptTemplate(
input_variables=["examples", "input_text"],
template="""
다음 예시들을 참고하여 새로운 입력을 분류하세요:
{examples}
새로운 입력: {input_text}
분류 결과:"""
)
def format_examples(examples):
formatted = ""
for ex in examples:
formatted += f"입력: {ex['text']}\n출력: {ex['label']}\n\n"
return formatted
chain = prompt_template | llm
# 테스트
input_text = "이 레스토랑 음식이 정말 맛있었어요!"
dynamic_examples = select_dynamic_examples(input_text)
formatted_examples = format_examples(dynamic_examples)
# 수정된 부분: 단일 딕셔너리 입력으로 변경
result = chain.invoke({"examples": formatted_examples, "input_text": input_text})
print(f"입력: {input_text}")
print(f"출력: {result.strip()}")
입력: 이 레스토랑 음식이 정말 맛있었어요! 출력: 분류 결과: 긍정
이와 같은 예시에서는 example의 수가 적기 때문에 비용적으로 부담되지 않지만 수가 커진다면 부담이 될 수 있습니다. 이럴 때 dynamic few shot prompting을 사용하면 부담을 줄일 수 있습니다.
코드 설명
모델 초기화: Ollama를 통해 EXAONE 3.5 모델을 로드합니다.
예제 선택: select_dynamic_examples 함수는 입력 문장의 키워드를 분석하여 가장 관련성 높은 예제를 선택합니다. 실제 구현에서는 텍스트 임베딩(예: Sentence-BERT)을 사용하여 더 정교한 유사성 계산을 수행할 수 있습니다.
프롬프트 템플릿: LangChain의 PromptTemplate을 사용하여 동적으로 예제를 삽입할 수 있는 프롬프트를 정의합니다.
체인 실행: LLMChain을 통해 프롬프트와 모델을 연결하고, 입력 문장에 대한 감정 분석 결과를 생성합니다.
다이나믹 퓨샷 프롬프트는 감정 분석 외에도 다양한 작업에 적용될 수 있습니다. 예를 들어:
질문 답변: 사용자의 질문과 유사한 질문-답변 쌍을 동적으로 선택.
텍스트 생성: 특정 스타일(예: 공식 문서, 캐주얼 대화)에 맞는 예제를 선택하여 생성된 텍스트의 톤을 조정.
코드 생성: 입력된 코드 스니펫과 유사한 예제를 제공하여 더 정확한 코드 완성을 유도.
고급 구현 팁
임베딩 기반 예제 선택: LangChain의 벡터 스토어(Vector Store)를 활용하여 입력과 예제 간의 코사인 유사도를 계산.
예제 생성: EXAONE 3.5 자체를 사용하여 입력에 맞는 예제를 생성한 후 프롬프트에 통합.
프롬프트 최적화: LangChain의 PromptSelector를 활용하여 작업 유형별로 최적의 프롬프트 템플릿을 선택.
다이나믹 퓨샷 프롬프트는 언어 모델의 성능을 극대화하는 강력한 도구입니다. 동적으로 선택된 예제는 모델이 작업 맥락을 더 잘 이해하도록 돕고, 다양한 도메인에서 높은 품질의 출력을 보장합니다.
Example Selector는 특정 작업에 적합한 예제를 동적으로 선택하여 프롬프트에 포함시키는 데 사용됩니다. 특히, 유사도 검색 기반 Example Selector는 입력 쿼리와 저장된 예제 간의 의미적 유사성을 평가하여 가장 관련성 높은 예제를 선택합니다. 그러나 유사도 검색 과정에서 발생할 수 있는 문제들—예를 들어, 부정확한 임베딩, 검색 결과의 낮은 품질, 또는 계산 비용 문제—는 모델 성능에 직접적인 영향을 미칩니다. 이 챕터에서는 유사도 검색 문제를 해결하는 방법에 대해 다룹니다.
유사도 검색의 핵심 개념
유사도 검색은 입력 쿼리와 예제 데이터를 임베딩 벡터로 변환한 뒤, 코사인 유사도(Cosine Similarity)와 같은 메트릭을 사용하여 가장 유사한 예제를 선택하는 과정입니다. EXAONE 3.5와 같은 모델은 고품질의 텍스트 임베딩을 생성할 수 있는 강력한 언어 모델로, LangChain의 SemanticSimilarityExampleSelector와 통합하여 효율적인 예제 선택을 지원합니다. 하지만 다음과 같은 문제들이 발생할 수 있습니다:
임베딩 품질 문제: 입력 쿼리나 예제 데이터의 의미가 부정확하게 표현될 경우.
벡터 저장소 검색 효율성: 대규모 데이터셋에서 검색 속도가 느려지는 문제.
컨텍스트 불일치: 선택된 예제가 작업 컨텍스트와 맞지 않는 경우.
이러한 문제들을 다음과 같은 방법으로 해결해볼 수 있습니다.
1) 고품질 임베딩 생성
LLM 모델은 다국어 지원과 고차원 임베딩 생성 능력이 뛰어나지만, 입력 데이터의 전처리가 중요합니다. 아래는 임베딩 품질을 개선하기 위한 방법입니다:
텍스트 정규화: 입력 쿼리와 예제 데이터를 정규화하여 불필요한 노이즈(예: 특수 문자, 불용어)를 제거합니다.
도메인 특화 fine-tuning: LLM 모델을 특정 도메인 데이터로 미세 조정하여 임베딩의 도메인 적합성을 높입니다. 예를 들어, 법률 관련 작업이라면 법률 문서로 fine-tuning을 진행합니다.
배치 처리 최적화: Ollama의 API를 활용하여 대량의 예제 데이터를 한 번에 임베딩 처리함으로써 계산 효율성을 높입니다.
2) 벡터 저장소 최적화
LangChain에서 벡터 저장소는 유사도 검색의 핵심 구성 요소입니다. Ollama 기반 환경에서는 로컬 벡터 저장소(예: FAISS)와 LLM 모델의 임베딩을 결합하여 효율적인 검색을 구현할 수 있습니다. 최적화 방법은 다음과 같습니다:
인덱싱 전략: FAISS의 HNSW(Hierarchical Navigable Small World) 인덱스를 사용하여 검색 속도를 높입니다.
차원 축소: PCA(Principal Component Analysis) 또는 UMAP을 활용하여 임베딩 차원을 축소함으로써 검색 속도를 개선하고 메모리 사용량을 줄입니다.
캐싱: 자주 사용되는 쿼리의 검색 결과를 캐싱하여 반복적인 계산을 방지합니다.
3) 컨텍스트 일치도 향상
유사도 검색 결과가 작업 컨텍스트와 맞지 않는 경우, 선택된 예제가 프롬프트에 부정적인 영향을 미칠 수 있습니다. 이를 해결하기 위한 방법은 다음과 같습니다:
메타데이터 필터링: 예제 데이터에 태그나 카테고리와 같은 메타데이터를 추가하여 검색 범위를 좁힙니다. 예를 들어, “질문 유형”이나 “도메인”별로 예제를 분류합니다.
하이브리드 검색: 키워드 기반 검색과 유사도 검색을 결합하여 의미적 유사성과 키워드 일치를 모두 고려합니다.
예제 다양성 관리: 너무 유사한 예제만 선택되지 않도록, 선택된 예제 간의 다양성을 보장하는 알고리즘(예: Maximal Marginal Relevance, MMR)을 적용합니다.
4) 계산 비용 절감
Ollama 기반 로컬 환경에서는 계산 리소스가 제한적일 수 있습니다. 이를 해결하기 위해:
모델 경량화: 경량화된 LLM 모델버전을 사용하거나, 양자화(Quantization)된 모델을 사용합니다.
비동기 처리: LangChain의 비동기 API(async/await)를 활용하여 병렬 처리를 구현합니다.
샘플링: 전체 예제 데이터셋 대신, 작업에 적합한 샘플 데이터만 사용하여 검색 부담을 줄입니다.
아래는 FAISS와 EXAONE 3.5를 사용하여 SemanticSimilarityExampleSelector를 구현하는 예제 코드입니다.
from langchain.prompts import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import FAISS
from langchain_ollama import OllamaEmbeddings
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
# 예제 데이터
examples = [
{"input": "프로그래밍에서 함수란 무엇인가?", "output": "함수는 특정 작업을 수행하는 코드 블록으로..."},
{"input": "법률 문서에서 계약 해지 조건은 무엇인가?", "output": "계약 해지 조건은 계약서에 명시된 조항에 따라 다르며..."},
{"input": "이 공의 색깔은 무엇인가요?", "output": "발간색입니다."},
{"input": "집에서 회사까지 얼마나 걸리나요?", "output": "1시간 정도..."},
]
# EXAONE 3.5 임베딩 설정 (Ollama 기반)
embeddings = OllamaEmbeddings(model="exaone3.5")
# FAISS 벡터 저장소 생성 (메타데이터 수정)
vectorstore = FAISS.from_texts(
texts=[example["input"] for example in examples],
embedding=embeddings,
metadatas=examples # 전체 예제 객체를 메타데이터로 저장
)
# Example Selector 설정
example_selector = SemanticSimilarityExampleSelector(
vectorstore=vectorstore,
k=1,
)
# 프롬프트 템플릿 정의
example_prompt = PromptTemplate(
input_variables=["input", "output"],
template="입력: {input}\n출력: {output}\n"
)
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
prefix="다음은 질문과 답변 예제입니다:",
suffix="입력: {user_input}\n출력:",
input_variables=["user_input"]
)
# 테스트
user_input = "계약 해지 절차는 어떻게 되나요?"
formatted_prompt = prompt.format(user_input=user_input)
print(formatted_prompt)
다음은 질문과 답변 예제입니다:
입력: 법률 문서에서 계약 해지 조건은 무엇인가? 출력: 계약 해지 조건은 계약서에 명시된 조항에 따라 다르며…
입력: 계약 해지 절차는 어떻게 되나요? 출력:
구현 후에는 다음과 같은 방법으로 성능을 평가하고 개선할 수 있습니다:
정확도 평가: 선택된 예제가 작업 결과에 미치는 영향을 정량적으로 측정합니다. 예를 들어, 생성된 답변의 BLEU 점수나 사용자 피드백을 활용합니다.
A/B 테스트: 서로 다른 임베딩 모델이나 검색 알고리즘을 비교하여 최적의 조합을 찾습니다.
로그 분석: Ollama의 로그를 분석하여 병목 지점을 식별하고 최적화합니다.
유사도 검색 문제를 해결하려면 임베딩 품질, 벡터 저장소 효율성, 컨텍스트 일치도, 그리고 계산 비용을 종합적으로 고려해야 합니다. 고품질 임베딩 생성, 벡터 저장소 최적화, 하이브리드 검색, 그리고 비동기 처리와 같은 전략을 통해 Example Selector의 성능을 극대화할 수 있습니다.
FewShotChatMessagePromptTemplate는 소수의 예제를 제공하여 모델이 특정 작업에 적합한 응답을 생성하도록 유도하는 데 유용합니다.
LangChain의 프롬프트 템플릿 중 하나로, 대화 형식의 입력과 출력 예제를 제공하여 모델이 맥락을 이해하고 유사한 패턴의 응답을 생성하도록 돕습니다. 이는 소수 샷 학습(Few-Shot Learning)을 구현하는 데 이상적이며, 모델이 새로운 작업을 빠르게 학습하도록 유도합니다.
주요 특징:
대화 형식 지원: 사용자와 모델 간의 대화 흐름을 반영한 프롬프트 설계 가능.
예제 기반 학습: 소수의 입력-출력 쌍을 제공하여 모델의 응답 품질 향상.
유연한 템플릿: 다양한 작업에 맞게 커스터마이징 가능.
일반적으로 다음과 같은 구성 요소로 이루어집니다:
예제(Examples): 모델이 참고할 입력-출력 쌍.
프롬프트 템플릿(Prompt Template): 대화 형식의 메시지 구조를 정의.
포맷팅 로직(Formatting Logic): 입력 데이터를 템플릿에 맞게 변환.
다음 코드는 FewShotChatMessagePromptTemplate를 사용한 감정 분류 예제 코드입니다.
from langchain.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
from langchain_ollama import ChatOllama
# EXAONE 3.5 모델 초기화
llm = ChatOllama(model="exaone3.5")
# 예제 데이터: 고객 문의와 감정 레이블
examples = [
{
"input": "제품이 너무 빨리 배송되어서 놀랐어요! 정말 만족합니다.",
"output": "긍정"
},
{
"input": "배송이 늦어서 아쉬웠습니다. 다음엔 개선 부탁드려요.",
"output": "부정"
},
{
"input": "고객 서비스가 정말 친절해서 기분이 좋았어요!",
"output": "긍정"
}
]
# 예제 프롬프트 템플릿 정의
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"),
("ai", "{output}")
])
# FewShotChatMessagePromptTemplate 설정
few_shot_prompt = FewShotChatMessagePromptTemplate(
examples=examples,
example_prompt=example_prompt
)
# 최종 프롬프트 템플릿
final_prompt = ChatPromptTemplate.from_messages([
("system", "당신은 고객 문의의 감정을 긍정 또는 부정으로 분류하는 전문가입니다. 다음 예제를 참고하여 응답하세요."),
few_shot_prompt,
("human", "{input}")
])
# 체인 구성
chain = final_prompt | llm
# 테스트 입력
test_input = "제품 품질이 기대 이상이었어요! 다음에도 구매할게요."
response = chain.invoke({"input": test_input})
print(f"입력: {test_input}")
print(f"출력: {response.content}")
입력: 제품 품질이 기대 이상이었어요! 다음에도 구매할게요. 출력: 긍정
코드 설명:
모델 초기화: ChatOllama를 사용하여 EXAONE3.5 모델을 로드합니다.
예제 정의: 고객 문의와 해당 감정(긍정/부정)을 쌍으로 제공합니다.
예제 프롬프트: ChatPromptTemplate을 사용하여 입력과 출력을 대화 형식으로 정의합니다.
FewShot 프롬프트: FewShotChatMessagePromptTemplate로 예제를 묶어 모델에 전달합니다.
최종 프롬프트: 시스템 메시지와 FewShot 프롬프트를 결합하여 최종 프롬프트를 생성합니다.
체인 실행: 입력 데이터를 프롬프트에 적용하고 모델을 호출하여 결과를 얻습니다.
다음은 고급 활용으로 FewShotChatMessagePromptTemplate는 단순한 텍스트 분류뿐만 아니라 다양한 작업에 활용될 수 있습니다. 예를 들어:
질문 답변: 특정 도메인의 질문에 대한 답변 형식을 학습.
텍스트 생성: 특정 스타일의 글쓰기(예: 공식 문서, 캐주얼 대화)를 유도.
작업 자동화: 고객 문의에 대한 자동 응답 템플릿 생성.
고급 예제는 고객 문의에 대한 자동 응답이며, 고객 문의에 대한 자동 응답 템플릿을 생성하는 예제를 살펴보겠습니다.
from langchain.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
from langchain_ollama import ChatOllama
# 모델 초기화
llm = ChatOllama(model="exaone3.5")
# 예제 데이터
examples = [
{
"input": "배송 상태를 알려주세요.",
"output": "안녕하세요! 배송 상태를 확인하려면 주문 번호를 말씀해 주세요."
},
{
"input": "제품이 언제 도착하나요?",
"output": "안녕하세요! 주문하신 제품의 예상 도착 날짜를 확인하려면 주문 번호를 알려주시면 빠르게 확인해드리겠습니다."
}
]
# 예제 프롬프트
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"),
("ai", "{output}")
])
# FewShot 프롬프트
few_shot_prompt = FewShotChatMessagePromptTemplate(
examples=examples,
example_prompt=example_prompt
)
# 최종 프롬프트
final_prompt = ChatPromptTemplate.from_messages([
("system", "당신은 고객 문의에 친절하게 응답하는 챗봇입니다. 예제를 참고하여 자연스럽게 답변하세요."),
few_shot_prompt,
("human", "{input}")
])
# 체인 구성
chain = final_prompt | llm
# 테스트
test_input = "주문한 물건이 언제 올까요?"
response = chain.invoke({"input": test_input})
print(f"입력: {test_input}")
print(f"출력: {response.content}")
입력: 주문한 물건이 언제 올까요? 출력: 주문 번호를 알려주시면 정확한 배송 예정일을 확인해 드릴 수 있습니다. 혹시 아직 주문 번호를 확인하지 못하셨다면, 주문 확인 이메일이나 주문 내역을 확인하시면 쉽게 찾으실 수 있을 거예요. 주문 번호를 알려주시겠어요?
FewShotChatMessagePromptTemplate는 LangChain에서 소수 샷 학습을 구현하는 데 매우 효과적인 도구입니다. 이를 다양한 실제 시나리오에 쉽게 적용할 수 있습니다.