-
뉴스 기사 탐색 챗봇 만들기BOOK 2024. 8. 24. 17:37
"한빛미디어 서평단 <나는리뷰어다> 활동을 위해서 책을 제공 받아 작성된 서평입니다."
기술 키워드
자연어
자연어(Natural language)는 사람들이 사용하는 언어를 이르는 표현
자연어를 컴퓨터가 이해하고 처리할 수 있도록 하는 기술
언어 모델
언어 모델(Language model)은 단어나 문장, 문단 단위로 자연어 데이터를 입력받은 후, 다음에 올 단어나 문자열을 예측하는 모델
초거대 언어 모델
초거대 언어 모델(LLM: Large Language Model)은 일반적인 언어 모델보다 훨씬 큰 규모의 언어 모델
LLM은 일반적인 언어 모델에 비해 훨씬 많은 파라미터와 방데한 데이터를 학습한 모델, 일반화 성능이 뛰어남
GPT 시리즈, Gemini
프롬프트, 프롬프트 엔지니어링
프롬프트(prompt)는 언어 모델에게 특정 작업을 수행하도록 지시하는 입력 문장, 질문
자연어 처리 모델의 성능은 프롬프트의 형식이나 표현 방식에 따라 크게 달라질 수 있다.
프롬프트 엔지니어링(prompt engineering)은 이러한 특성을 활용하여 특정 작업이나 응답에 대해 원하는 결과를 얻기 위햇 프롬프트를 조절하는 기법
업스트림 테스크, 다운스트림 테스크
머신러닝에서 업스트림 테스크(upstream task)는 사전 학습 모델이 기본적인 기능을 학습하기 위한 초기 단계의 작업
이 단계에서 일반적인 패턴과 표현을 학습
예를 들어 언어 모델의 업스트림 테스크는 특정 단어가 주어졌을 때 다음 단어를 예측하는 작업
다운스트림 테스크(downstram task)는 업스트림 테스트에서 학습한 사전 학습 모델을 사용하여 실제로 해결하고자 하는 응용 분야의 작업. 일반적으로 특정 도메인 또는 응용 분야에 더 집중. 특정 문제를 해결하기 위해 모델을 미세 조정(fine-tuning)을 하기도 함
뉴스 기사 탐색 챗봇 애플리케이션
1. 채팅 형식으로 뉴스 기사 정보를 요청할 채팅 UI 필요. 사용자는 필요한 뉴스 기사를 질문 형태로 챗봇에 입력
2~3. 챗봇은 입력받은 메시지를 언어 모델로 분석 -> 어떤 기사가 필요할지 판단 -> 이 정보를 바탕으로 뉴스 정보 탐색기로부터 뉴스를 받아옴
4. 받아온 뉴스 정보는 그대로 제공하지 않고 언어 모델을 활용해 가공하여 채팅 UI에 자연스러운 채팅 형태로 제공
동시에 뉴스 기사 리스트 UI에 뉴스 정보 목록을 업데이트.
5~6. 사용자가 특정 기사를 선택하면 웹 스크래퍼가 기사의 원문을 스크래핑한 후, 언어모델로 전달
7. 언어 모델이 만든 영어 기사 요약문과 한글 기사 요약문을 저장할 텍스트 UI를 구현
애플리케이션 구현하기
챗봇 UI 구현하기
with gr.Blocks() as app: gr.Markdown("# 뉴스 기사 탐색 챗봇") gr.Markdown( """ ## Chat 얻고 싶은 정보에 대해 질문해보세요. """ ) chatbot = gr.Chatbot(label="Chat History") prompt = gr.Textbox(label="Input prompt") clear = gr.ClearButton([prompt, chatbot]) app.launch(inline=False, share=True) app.close()
GPT API로 기본적인 챗봇 구현하기
def respond(prompt: str, chat_history: List[str]) -> Tuple[str, List[str]]: messages = [{"role": "user", "content": prompt}] res = client.chat.completions.create(model=model, messages=messages) answer = res.choices[0].message.content chat_history.append((prompt, answer)) return "", chat_history with gr.Blocks() as app: gr.Markdown("# 뉴스 기사 탐색 챗봇") gr.Markdown( """ ## Chat 얻고 싶은 정보에 대해 질문해보세요. """ ) chatbot = gr.Chatbot(label="Chat History") prompt = gr.Textbox(label="Input prompt") clear = gr.ClearButton([prompt, chatbot]) prompt.submit(respond, [prompt, chatbot], [prompt, chatbot]) app.launch(inline=False, share=True) app.close()
News API를 활용해 뉴스 기사 정보 가져오기
headers = {"x-api-key": os.environ["NEWS_API_KEY"]} params = { "sources": "cnn", "language": "en", "q": "Tesla", "sortBy": "publishedAt" } # Fetch from newsapi.org response = requests.get(endpoint, params=params, headers=headers) data = response.json() data["articles"][0] class NewsApiClient: def __init__(self): self.news_api_key = os.environ["NEWS_API_KEY"] self.max_num_articles = 5 def get_articles( self, query: str = None, from_date: str = None, to_date: str = None, sort_by: str = None, ) -> str: """Retrieve articles from newsapi.org (API key required)""" endpoint = "https://newsapi.org/v2/everything" headers = {"x-api-key": self.news_api_key} params = { "sortBy": "publishedAt", "sources": "cnn", "language": "en", } if query is not None: params["q"] = query if from_date is not None: params["from"] = from_date if to_date is not None: params["to"] = to_date if sort_by is not None: params["sortBy"] = sort_by # Fetch from newsapi.org # reference: https://newsapi.org/docs/endpoints/top-headlines response = requests.get(endpoint, params=params, headers=headers) data = response.json() if data["status"] == "ok": print( f"Processing {data['totalResults']} articles from newsapi.org. " + f"Max number is {self.max_num_articles}." ) return json.dumps( data["articles"][: min(self.max_num_articles, len(data["articles"]))] ) else: print("Request failed with message:", data["message"]) return "No articles found" news_api_client = NewsApiClient() news_api_client.get_articles(query="Tesla")
함수 호출 기능을 활용한 뉴스 기사 탐색 챗봇 만들기
signature_get_articles = { "name": "get_articles", "description": "Get news articles", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Freeform keywords or a phrase to search for.", }, "from_date": { "type": "string", "description": "A date and optional time for the oldest article allowed. This should be in ISO 8601 format", }, "to_date": { "type": "string", "description": "A date and optional time for the newest article allowed. This should be in ISO 8601 format", }, "sort_by": { "type": "string", "description": "The order to sort the articles in", "enum": ["relevancy", "popularity", "publishedAt"], }, }, "required": [], }, } class GPTClient: def __init__(self): self.client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) self.model = "gpt-3.5-turbo" def get_args_for_function_call( self, messages: List[Dict[str, str]], function_signatures: List[Dict[str, Any]] ) -> str: """ If there is information for function in messages, get argument from messages. Otherwise get simple GPT response. """ response = self.client.chat.completions.create( model=self.model, messages=messages, functions=function_signatures, ) return response.choices[0].message def request_with_function_call( self, messages: List[Dict[str, str]], function: Callable, function_call_resp, prompt: str = "", ) -> str: function_name = function_call_resp.function_call.name if prompt: messages.append({"role": "system", "content": prompt}) # Run external function kwargs = json.loads(function_call_resp.function_call.arguments) function_result = function(**kwargs) # Append message messages.append(function_call_resp) messages.append( {"role": "function", "name": function_name, "content": function_result} ) # GPT inference include function result res = self.client.chat.completions.create( model=self.model, messages=messages, ) return res.choices[0].message.content.strip() gpt_client = GPTClient() def respond(prompt: str, chat_history: List[str]) -> Tuple[str, List[str]]: # Get args from prompt messages = [{"role": "user", "content": prompt}] args_resp = gpt_client.get_args_for_function_call(messages, [signature_get_articles]) # call functions requested by the model answer = args_resp.content title_list = [] if args_resp.function_call: # GPT inference again with calling external function get_articles_prompt = """ You are an assistant that provides news and headlines to user requests. Always try to get the articles using the available function calls. Write the arguments to your function at the top of your answer. Please output something like this: Number. [Title](Article Link)\n - Description: description\n - Publish Date: publish date\n """ answer = gpt_client.request_with_function_call( messages=messages, function=news_api_client.get_articles, function_call_resp=args_resp, prompt=get_articles_prompt, ) chat_history.append((prompt, answer)) return "", chat_history with gr.Blocks() as app: gr.Markdown("# 뉴스 기사 탐색 챗봇") gr.Markdown( """ ## Chat 얻고 싶은 정보에 대해 질문해보세요. """ ) chatbot = gr.Chatbot(label="Chat History") prompt = gr.Textbox(label="Input prompt") clear = gr.ClearButton([prompt, chatbot]) prompt.submit(respond, [prompt, chatbot], [prompt, chatbot]) app.launch(inline=False, share=True) app.close()
728x90'BOOK' 카테고리의 다른 글
쿠버네티스 모니터링 (2) 2024.10.26 소프트웨어 설계 접근법 (1) 2024.09.28 회의 요약 보고서 작성법 (1) 2024.07.25 부트캠프 QA편 (0) 2024.06.23 알고리즘 인사이드 with 파이썬 (0) 2024.05.25