본문 바로가기
AI 빅데이터/AI 동향

[LangChain] VertexAI의 LLM으로 Web검색 연동하기

by 마고커 2023. 8. 24.


대체로 보유하고 있는 데이터베이스를 검색하여 Hallucination을 줄이는 예제가 많은데, LangChain은 Web 검색을 통해서도 대답을 할 수 있도록 구성되었다. 본 포스팅에서는 뉴욕타임즈에서 기사를 검색해 대답하는 형태의 간단한 예제를 구현해 본다.

 

from langchain.retrievers.web_research import WebResearchRetriever
from langchain.vectorstores import Chroma
from langchain.embeddings import VertexAIEmbeddings
from langchain.chat_models.vertexai import ChatVertexAI
from langchain.utilities import GoogleSearchAPIWrapper

LangChain Library를 import 한다. 주의할 점은 web_research는 최신 버전에서만 지원되는 것 같다. 해당 라이브러리가 없다고 에러를 일으키면 pip install --upgrade langchain을 통해 최신 버전으로 업데이트 해 준다.

 

import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "너의_gcp_서비스_계정에서_받아온.json"

 

(현재까지 돈이 안드는) VertexAI의 PaLM-2를 통해 langchain을 연동할 것이므로 Google Cloud Platform 서비스 계정 credentials를 가져온다. 가져오는 방법은 GCP 콘솔에서 IAM > 서비스 계정에서 VertexAI 서비스를 지원하는 서비스 계정을 선택하고 키를 추가하면 된다. 키를 추가하면 json 파일이 다운로드 되는데 적절한 위치로 옮겨준다.

 

 

# Vectorstore
vectorstore = Chroma(embedding_function=VertexAIEmbeddings(),persist_directory="./chroma_db_oai")

# LLM
llm = ChatVertexAI(temperature=0)

 

검색된 내용을 저장할 벡터DB와 Chatting 모델을 할당한다.

 

# from https://developers.google.com/custom-search/v1/introduction?apix=true&hl=ko
os.environ["GOOGLE_CSE_ID"] = "xxxxxx"
os.environ["GOOGLE_API_KEY"] = "yyyyy"
search = GoogleSearchAPIWrapper()

 

구글 검색으로 사이트를 검색해야 하는데 환경 변수에, 'GOOGLE_CSE_ID'와 'GOOGLE_API_KEY'에 해당하는 값을 넣어주면 된다. 해당 값들은 주석처리된 사이트에서 얻을 수 있다.

 

 

Programmable Search Engine이라는 페이지에 '프로그래밍 검색엔진(무료버전)'을 선택하면 검색 대상 사이트를 추가할 수 있다. 여기서는 nytimes 사이트 아래에서 검색을 수행하도록 설정했다.

 

 

CSE_ID는 위페이지와 같은 페이지 내에 '검색엔진ID'라는 항목으로 되어 있고, API_KEY는 'Programmable Search Engine'페이지에의 '키가져오기'라는 항목을 통해서 가져올 수 있다. 이제 환경 설정은 거의 끝났다. 겁나 간단.

 

web_research_retriever = WebResearchRetriever.from_llm(
    vectorstore=vectorstore,
    llm=llm, 
    search=search, 
)

 

web 검색할 retriever를 설정한 vector database, chatting model, programmable search engine과 함께 생성한다. 

 

# jupyter에서 실행할 때만 수행. App에서 순차처리할 때는 주석처리
# import nest_asyncio
# nest_asyncio.apply()

# 찾는 과정을 logging. 필요 없으면 off
import logging
logging.basicConfig()
logging.getLogger("langchain.retrievers.web_research").setLevel(logging.INFO)

 

위의 코드는 반드시 필요한 것은 아닌데, 로깅과 jupyter 실행 목적으로 작성한다는 정도로만 이해하면 된다. jupyter에서 실행할 때 주석처리한 부분을 열어주지 않으면 에러 발생.

 

from langchain.chains import RetrievalQAWithSourcesChain

def find_news(question):
    user_input = question
    qa_chain = RetrievalQAWithSourcesChain.from_chain_type(llm,retriever=web_research_retriever)
    result = qa_chain({"question": user_input})
    return result['answer']

 

실제 검색을 수행하는 함수를 작성한다. find_news의 파라미터에 질문을 넣으면 답을 가져올 수 있도록 설정되었다. 여기까지 하고 find_news 함수를 실행해도 좋은데, streamlit으로 간단한 UI까지 만들어본다.

 

import streamlit as st

st.subheader('Ask for latest news in newyork times')
question = st.text_input("", value="who races in 2024 presidence election?", key="msg")

st.write(find_news(question))

 

뉴욕타임즈에서 2024년 대통령선거 후보자를 묻는 것을 default로 하여 페이지를 생성하도록 했다. 터미널에서 'streamlit run 작성한파이썬파일.py'를 실행하면 브라우저에서 실행한 화면을 보게된다.

 

 

제대로 대답했는 지는 설정했던 로깅 덕분에 터미널에서 확인할 수 있다.

 

INFO:langchain.retrievers.web_research:Generating questions for Google Search ...
INFO:langchain.retrievers.web_research:Questions for Google Search (raw): 
    {'question': 'who races in 2024 presidence election?', 
    'text': LineList(lines=['1. Who is running for president in 2024?\n', 
    '2. What are the 2024 presidential election candidates?\n'])}
INFO:langchain.retrievers.web_research:Questions for Google Search: 
    ['1. Who is running for president in 2024?\n', 
    '2. What are the 2024 presidential election candidates?\n']
INFO:langchain.retrievers.web_research:Searching for relevant urls...
INFO:langchain.retrievers.web_research:Searching for relevant urls...
INFO:langchain.retrievers.web_research:Search results: [{'title': 
    'Who Are the 2024 Presidential Election Candidates? - The New ...', 'link': 
    'https://www.nytimes.com/interactive/2023/us/politics/presidential-candidates-2024.html', 
    'snippet': '3 days ago ... Ryan Binkley is the president of a mergers and acquisitions
    firm and the pastor of a Texas church. He has never held or run for elected office\xa0...'}]
INFO:langchain.retrievers.web_research:Searching for relevant urls...
INFO:langchain.retrievers.web_research:Search results: 
    [{'title': 'Who Are the 2024 Presidential Election Candidates? - The New ...', 
    'link': 'https://www.nytimes.com/interactive/2023/us/politics/presidential-candidates-2024.html', 'snippet': '3 days ago ... Francis Suarez has cast himself as a fresh Republican face who can appeal to young people, to urban residents and — as the son of Cuban\xa0...'}]
INFO:langchain.retrievers.web_research:New URLs to load: 
    ['https://www.nytimes.com/interactive/2023/us/politics/presidential-candidates-2024.html']
INFO:langchain.retrievers.web_research:Indexing new urls...
Fetching pages: 100%|#############################| 1/1 [00:00<00:00, 11.80it/s]
INFO:langchain.retrievers.web_research:Grabbing most relevant splits from urls..

 

척 봐도 답이 있을 것 같은 "https://www.nytimes.com/interactive/2023/us/politics/presidential-candidates-2024.html"에서 실제로 해당 내용이 있는 지 확인해 본다.

 

 

정답은 물론 (보이지 않는) 하단의 텍스트에서 가져왔겠지만, 누가봐도 해당 페이지에 답이 있어 보인다. 이제 질문을 바꿔서 (불과 어제 일어났던) 북한의 위성발사에 대한 남한의 생각을 물어보았다. 영어 실력이 형편 없어도 잘 대답해준다.

 

한국 뉴스에서 보도된 것처럼 남한은 북한의 위성발사가 실패라고 생각하고 있으며, 정찰 위성으로써 군사적 용도가 전혀 없다고 생각하고 있다라고 말해 준다. 아 그런데 어제 뉴스가 아니라 7월 뉴스다! 7월에도 위성발사를 했었지! 어쨌듯 잘 찾아서 대답해준다.

 



댓글