본문 바로가기
프로그래밍

Multi Agent로 신문기사 작성해보기 (AutoGen + OpenAI API)

by Good.PhD 2024. 9. 15.

'AI와 화학물질'이라는 책을 출간했다. 출판사에서 책 소개를 하는 신문 기사를 작성해보자고 제안하면서, 투고할 신문 기사 하나를 참고하라고 보내줬다. 그냥 코파일럿이랑 클로드를 써도 되긴 하지만, 그냥 쓰기는 어렵다고 생각을 했다. 왜냐하면 책이 출간된지 얼마 되지도 않았고 웹상에는 책 내용이 공개되어 있지 않았기 때문이다.

 

언어모델로 책을 소개하는 신문기사를 작성하려면 아래 단계들이 필요하다고 생각했다.

1) 책의 전체 내용을 요약하는 글을 만들어야 함. (챕터별로 충분한 요약 내용 필요)

2) 참고할 신문기사도 제공해야 함. (이 기사의 형식을 참고해서 글을 정리해야 함)

3) 1번과 2번을 참고해서 신문기사를 작성.

 

책 내용은 웹에 공개된 내용이 아니기 때문에 모델이 책 내용에 대해서 접근할 수가 없다. 그래서 그냥 책을 요약해달라는 프롬프트를 넣어봤자 제대로 책을 요약할 수는 없다. 또 책 내용을 코파일럿에 그냥 붙여넣자니 글의 양이 너무 많았다. 그래서 1차시도로 코파일럿에서 pdf 파일을 연 후에 책 내용 요약을 요청해봤지만, 요약이 의도한대로 잘 되지 않았다. 책이 머리말과 10챕터로 구성되어 있는데, 챕터별로 5-6문장으로 요약하라고 했지만 아무리 요청해도 챕터별로 1문장으로만 정리해버려서 쓸모 없는 글만 생성이 되었다. 

 

그래서 한번 python으로 신문 기사를 작성해보기로 했다. deeplearning.ai에서는 AutoGen이라는 라이브러리를 소개하는 강의가 있다. AutoGen은 마이크로소프트 사에서 개발한 라이브러리로 ChatGPT를 이용해서 multi agent를 쉽게 구현해볼 수 있게 만들었다.

AutoGen 실습 내용

 

강의에서 실습했던 내용은 블로그 작성하기였는데, AutoGen AssistantAgent를 이용해서 writer, critic, SEO reviewer, legal reviewer, ehtical reviewer, meta reviewer라는 에이전트 들을 각각 정의하고, 언어모델끼리 서로 피드백을 주고받으면서 블로그를 완성해가도록 했다. 

해당 내용으로 강의 준비도 한번 해본적 있어서 여기서 조금 더 수정해서 신문기사 작성을 해볼 수 있지 않을까 생각이 들었다. 다만 여기서 약간의 변화는 필요했다.

 

코드에서의 흐름은

1) 책 pdf 파일에서 텍스트를 읽어서 요약

2) 신문기사 텍스트를 프롬프트에 삽입해서 해당 글을 기반으로 신문 기사를 작성하도록 요청

3) AutoGen에 정의한 에이전트간 대화를 통해 기사를 수정 (Writer, Critic은 동일. SEO reviewer를 제외하고, Business reviewer와 format reviewer로 바꾸었다)

 

1. pdf 파일 내용 요약하기

deeplearnig.ai 에서 langchain 강의를 들었었는데, langchain이라는 라이브러리에서 pdf를 읽어오는 기능이 제공되는걸 기억하고 있어서 찾아봤다. 사용 방법은 copilot한테 물어가면서 찾아봤는데, pdf를 다루는데 필요한 라이브러리를 알려줬다. 그래서 먼저 콜랩에서 설치!

라이브러리 설치

 

설치한 후에 Google drive에 편집할 파일을 올리고 langchain에서 pdf 내 텍스트를 읽어봤는데... (자세한 위치는 삭제했지만 삭제된 부분은 파일이 위치한 경로를 입력하면 된다)

lngchain에서 PDF를 읽어본 결과

 

PyPDFLoader를 사용해서 모든 페이지를 읽어온 후에, 확인을 해봤다. page[10]은 아마 11번째 페이지일 거라고 추측한다. (인덱스가 0번부터 시작하니...) 임의로 아무 페이지나 찍어서 그냥 출력을 해봤는데, 이상한 기호들이 출력되는 것을 볼 수 있다. 한국어 인식을 잘 못했나보다. encoding 문제일 수도 있고... 해서 코파일럿에 해결책을 물어봤더니 다른 라이브러리를 추천해줬다.

 

pdf 텍스트 읽기 성공

 

pymupdf 라는 라이브러리를 추천해줬고, 여기서 pdf를 읽었더니 성공적으로 책의 텍스트를 가져왔다. 책이 총 132페이지 정도 된다. 그중에서 그냥 131페이지 내용을 가져와봤고, 책 내용이 제대로 출력되었다.

 

책 전체 글자수 확인

 

책 전체 글자수를 확인해보니 74562자인 것으로 확인. 이제 책 내용 요약을 요청하려고 하는데, 이 내용을 다 입력할 수 있을지 잘 몰라서 확인 과정을 거쳤다. 모든 언어 모델은 입력 가능한 토큰의 최대치가 정해져있다. 이를 초과하면 모델에 입력이 다 안된다. 토큰은 글자 혹은 단어와는 조금 다른 개념인데, 언어모델은 문장을 토큰으로 쪼개서 입력을 한다. 예를 들면 learning이라면 learn이 한 토큰, ing가 또 한 토큰이 될 수 있다. 그래서 토큰 개수는 단어 개수도 아니고 글자 개수도 아니다. 다만 문장을 효율적으로 분할시키기 위해 모델을 개발할 때 서로 다르게 토큰을 정의하는 것 같다.

 

tiktoken으로 token 개수 확인

 

GPT-4o로 책 내용을 요약할 계획인데, 토큰 크기가 얼마나 되는지 확인해보기로 했다. 내 책은 빈칸 포함해서 74652자인데, 토큰으로 바꾸면 40294가 된다. 상당히 크다. GPT-4o에서 최대 토큰 개수는 128,000이라고 하니 넉넉하다고 생각했다. 

1) openAI API를 이용해서 책 내용을 요약하고,

2) 요약한 글을 AutoGen 프롬프트에 입력해서 전달하면 되겠지..?

라고 생각하고 진행했다.

 

그런데 GPT-4o에 책 내용을 넣어서 입력하자 바로 에러가 발생했다. API 자체에 제한이 있나보다. 40000토큰이 넘으면 제한을 걸고 있는 것 같다. 그래서 토큰 길이를 기준으로 텍스트를 나눈후에 요약을 해보기로 했다.

openAI API로 책 요약을 해봤다

 

먼저는 GPT-4o에서 토큰 제한이 있으니 책 전체 텍스트를 토큰 개수 기준으로 나눴다. (코드는 코파일럿이 알려줬다) 그다음에 나눈 텍스트를 각각 모델에 넣어서 요약을 요청했다. 마지막 셀에서는 각 요약문을 하나의 텍스트로 합치는 작업을 거친다. 이렇게 해서 책을 나눠서 요약해봤다.

사실 여기서 몇가지 해볼만한 실험이 있는데, 시간 관계상 해보지는 못했다.

1) 책을 토큰으로 나누면 부적절하게 문장이 잘려나갈 수 있어 일부 내용은 요약이 잘 안될 수 있다. 그래서 이렇게 나누기 보다는 책의 텍스트가 잘리는 부분은 조금 겹치도록 해서 내용 손실을 막을 수 있다.

2) 이렇게 임의의 길이로 자르기 보다는 챕터별로 자르면 더 좋을 것 같은데, 너무 늦은 밤에 작업하느라 그냥 대충 자르긴 했다. 원래 가장 바람직한건 머리말, 챕터 별로 텍스트들을 모두 나눠서 잘랐으면 좋았을 것 같다. 

3) 챕터별로 요약이 오래 걸릴 수도 있으니 2챕터씩 묶어서 요약을 해볼수도 있지 않을까 생각도 했다.

 

아무튼 그냥 대충 잘라낸 텍스트로 진행해보기로 했다. 미리 밝히자면, 이렇게 작성한 글의 퀄리티가 만족스럽지는 않았다. 텍스트 요약 부분을 너무 대충 처리한게 문제가 아닐까 생각도 든다.

프롬프트를 위한 텍스트 제공

 

final_summary 안에 책 요약본을 저장해뒀다. 그리고 해당 본문을 첨부하면서 신문기사를 작성하라는 요구 사항을 전달했다. format은 참고할 신문기사다. 이 내용을 참고해서 기사를 작성하도록 요청했다.

AutoGen 에이전트 정의

 

AutoGen 에이전트는 system 메세지를 전달하게 되어 있는데, 여기서 각 에이전트들의 역할을 명시할 수 있다. 

reviwer 에이전트

 

기본적으로 구성은 writer가 초안을 작성하고 critic은 글의 수정을 요청한다. critic이 다른 reviewer 들의 피드백을 받아서 writer에게 전달하면 writer가 피드백을 반영해서 글의 수정을 진행한다. 시스템 메세지를 잘 정리하는게 중요한데, 시스템 메세지를 너무 급하게 적어서 조금 아쉬운 감이 있다.

 

<시스템 메세지 작성 아이디어>

format에 제공한 기사로 부터 각 리뷰어의 관점에서 중요한 부분을 강조할 수 있는 시스템 프롬프트를 만들어내도 되지 않을까 생각한다. 모델에 format을 전달하고, 법적인 관점에서 해당 기사를 분석하고 에이전트의 시스템 프롬프트 작성을 요청했으면 어땠을까 하는 아이디어가 떠올랐지만 코딩 완료하고 한참 뒤에 떠올랐다 :)

 

마지막 리뷰어

 

각 reviewer들마다 피드백을 제공하는데 마지막에 피드백을 통합해서 정리하는게 좋을 것 같아서 meta_reviewer에게 그 역할을 부여했다.

AutoGen 에서 대화를 주고 받는 순서

 

AutoGen 사용 방식은 그림에 있는 링크로 들어가면 확인할 수 있다. 구글에서 AutoGen 검색해서 notebook을 찾아냈고, 그 내용도 같이 보면서 참고했다. 대화는 review_chats에 저장된 순서로 진행된다. 

 

멀티 에이전트 대화 시작!

 

ciritic에게 review_chat을 전달해주기 때문에 중간에 critic이 대화를 주고받는 역할을 중재하는 모습이 계속 나온다. critic이 초기에 writer에게 메세지를 전달하면서 대화가 시작된다. 각 에이전트 별로 max_turn 값을 받는데, 이건 최대 대화 반복횟수이다. 1이면, 한번만 메세지를 만들고 끝이고, 2면 2번 메세지를 주고 받는다. API는 입력 토큰 / 출력 토큰 개수로 비용이 부과된다. 그래서 max_turn을 올리면 비용도 함께 올라간다.

initiate_chat()을 실행하면 critic이 자기의 메세지를 전달하는 것을 볼 수 있다. 그러면 writer가 해당 요청사항에 대해서 글을 작성한다. 그러면 ciritic이 그 글을 reviewer들에게 차례차례 전달하면서 피드백을 만들어가고, 마지막에 meta reviewer 가 피드백을 모두 정리하면 그 내용을 writer에게 전달하면서 최종 버전이 나오게 된다.

 

critic과 writer의 대화만 출력해볼 수 있다

 

이렇게 하면 최종 버전만 출력해볼 수 있따. 결론부터 말하면,, 최종적으로 나온 글은 별로 마음에 안들었다. 새벽에 1시간 반동안 작업했는데, 이래저래 실망.. 그래서 결국 이전 글처럼 코파일럿과 클로드를 이용해서 최종 초안을 정리했다. (인사말 작성하기 글!)

그래도 나름 재미있는 작업이었고, AutoGen 강의 들은 이후 나름 실제 필요한 업무에 처음 사용해봐서 재미는 있었다. :)