Agent:LLM의 새로운 응용프로그램 -2부
안녕하세요, 서비스 개발실에서 AI engineer로 일하고 있는 오진성이라고 합니다.
시작
앞서 1부에서 전체적인 Agent의 개념들을 다뤄봤습니다. 이번 글에서는 실제 Agent를 구현하고, Agent들의 Pipeline을 어떻게 만드는지 설명합니다. 마지막으로 크라우드웍스에서 일을 할 때, Agent를 어떻게 쓰는지 예제 하나를 공개합니다.
Agent들을 가지고 일 처리하는 Pipeline을 구축하는 유형들
여러가지 방법으로 Agent들을 이어 붙여서 일을 처리하는 유형(Pattern)들이 있습니다. 아래 방식은 MS가 만든 AutoGen framework의 문서에 나와 있는 방법들입니다.
둘이 대화하고 결과내기 (Two-Agent Chat and Chat Result)
두 Agent 간의 채팅(Two-Agent Chat) 은 우리가 생각하는 ‘대화를 하는’ 패턴입니다. 서로 역할이 다른 두 Agent가 서로 ‘이 문제를 어떻게 풀것인가’ 논의를 하면서 답을 해나가는 것입니다.
Fig 5. Two-Agent Chat 유형. 두개의 Agent가 대화를 하고, 이 결과를 가지고 답을 하는 방식이다. (출처: https://microsoft.github.io/autogen/ )
AutoGen framework에서는 이것은 아래처럼 구현합니다.
import os
from autogen import ConversableAgent
# 두 개의 Agent 설정
cathy = ConversableAgent(
"cathy",
system_message="Your name is Cathy and you are a part of a duo of comedians.",
llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.9, "api_key": os.environ.get("OPENAI_API_KEY")}]},
human_input_mode="NEVER", # Never ask for human input.
)
joe = ConversableAgent(
"joe",
system_message="Your name is Joe and you are a part of a duo of comedians.",
llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.7, "api_key": os.environ.get("OPENAI_API_KEY")}]},
human_input_mode="NEVER", # Never ask for human input.
)
# 최대 2번 돌고 cathy에게 명령을 하고 이를 joe가 받아서 처리하게 한다.
result = joe.initiate_chat(cathy, message="Cathy, tell me a joke.", max_turns=2)
Code 2. AutoGen의 ChatTermination예제 코드
이것의 출력은 아래처럼 나옵니다.
joe (to cathy):Cathy, tell me a joke.--------------------------------------------------------------------------------
cathy (to joe):Sure, here's one for you:Why don't scientists trust atoms?Because they make up everything!--------------------------------------------------------------------------------
joe (to cathy):Haha, that's a good one, Cathy! Okay, my turn. Why don't we ever tell secrets on a farm?Because the potatoes have eyes, the corn has ears, and the beans stalk.--------------------------------------------------------------------------------
cathy (to joe):Haha, that's a great one! A farm is definitely not the place for secrets. Okay, my turn again. Why couldn't the bicycle stand up by itself?Because it was two-tired!--------------------------------------------------------------------------------
Code 3. AutoGen의 ChatTermination 예제 결과
Code 3.에서 보듯, 인간의 개입 없이, 초기 대화만 넣어주면, 주어진 System prompt에 따라 ‘스스로’ 움직입니다. 목표만 주어지고 질문만 주어지면 스스로 컴퓨터가 문제를 해결하는 소프트웨어를 인간이 만든것입니다.
Agent에 인간의 개입을 추가하기 (Human in-the-loop)
Fig 6. Human-in-the-loop 컴포넌트가 Auto-reply앞에 있다. 이것은 수신 메시지를 가로채서 Auto-reply 컴포넌트에 전달할지 사람의 피드백을 제공할지를 결정할 수 있다. (출처: https://microsoft.github.io/autogen/ )
많은 애플리케이션에서는 Agent와 함께 사람을 투입해야 할 수도 있습니다. 예를 들어, 사람의 피드백을 통해 Agent를 올바른 방향으로 이끌고 목표를 지정하는 등의 작업을 수행할 수 있습니다. 위의 그림에서 보여주듯 Human-in-the-loop 컴포넌트가 Auto-reply앞에 있는 것을 보실 수 있습니다. 이것은 수신 메시지를 가로채서 Auto-reply 컴포넌트에 전달할지 사람의 피드백을 제공할지를 결정하겠다는 뜻입니다. (참고)
이어이어 대화하기 (Sequential Chats)
이 패턴은 “이어 이어 대화하기(Sequential Chats)”라는 이름처럼, 두 에이전트가 대화하면서 이전 대화의 내용을 다음 대화에 이어서 가져가는 방식입니다. 간단히 말하면, 에이전트 A와 B가 대화를 하고 나면, 그 대화 내용을 요약해서 에이전트 C와 A의 다음 대화에 전달하는 것입니다. 이렇게 해서 A는 차례대로 C, D, E 등과 대화하면서 중간 요약된 내용들을 계속 이어받습니다. 마지막에는 그동안의 모든 대화 내용을 종합하여 최종 결론을 내리게 됩니다. 이 패턴은 여러 단계로 나누어진 복잡한 작업을 처리할 때 특히 유용합니다.
Fig 7. Sequential Chats의 개요 (출처: https://microsoft.github.io/autogen/ )
이 패턴에서는 한 쌍의 Agent가 먼저 두 Agent 간의 채팅을 시작한 다음 대화 요약이 다음 두 Agent 간의 채팅내용을 넘겨주게 (carreyover)됩니다. 다음 채팅은 넘겨준 내용을 컨텍스트의 넘겨주는 (carreyover) 매개 변수로 전달하여 초기 메시지를 생성합니다.
대화가 진행됨에 따라 넘겨주는 내용이 누적되므로 이후의 각 채팅은 이전 채팅의 모든 넘겨진 대화를 가지고 시작합니다. 위 그림은 모든 채팅에 대해 별개의 수신자 Agent를 보여주지만 시퀀스의 수신자 Agent를 반복해서 할 수 있습니다. 쉽게 말하면 모든 대화를 단 두개의 Agent로 둘 수 있다는 뜻입니다.
다 모여 대화하기 (Group chat)
Fig 8. Group chat의 개요. 이 방식의 핵심은 모든 Agent들이 하나의 대화에 기여하고 같은 내용을 공유하는 것이다. 그림과 같이 한 Agent에서 답을 받고, 그 답을 다른 Agent들에 전달하는 것이다. (출처: https://microsoft.github.io/autogen/ )
이 방식의 핵심은 모든 Agent들이 하나의 대화에 기여하고 같은 내용을 공유하는 것입니다. 위 그림과 같이 한 Agent에서 답을 받고, 그 답을 다른 Agent들에 전달합니다. 이 과정을 모든 대화가 끝날때까지 반복합니다.
Agent를 선택하는 방법은 여러가지 방법중 하나를 고를 수 있습니다. round robin, random, manual, auto 등이 가능합니다.
크라우드웍스는 Agent를 어떻게 쓰나
크라우드웍스도 내부에서 Agent를 많이 만들어서 씁니다. 저희가 실제 쓰는 내용을 보여드릴수는 없습니다. 하지만 어떻게 사용하는지 쉽게 설명을 해보겠습니다.
Agent 하나 만들기
먼저 하나의 Agent를 만들고 일을 시킨다고 가정하겠습니다. 그런데 저희가 또 Prompt를 다 생각해서 일이리 쓰기에는 어렵습니다. 그래서 이렇게 Prompt를 작성해주는 Agent가 있습니다.
이 다음에 이런 ‘요청’을 Agent에 보냅니다.
context를 공식적인 자리에서 발표하는 내용으로 바꿔주는 prompt를 작성해야 돼. 구체적인 지침을 포함한 prompt를 작성해줘
그러면 이렇게 Prompt를 만들어 줍니다.
주어진 문맥을 분석하여 간결하고 전문적인 어조로 재구성하세요. 불필요한 세부 사항은 제외하고, 핵심 내용에 초점을 맞추세요. 발표 형식에 맞게 서론, 본론, 결론 구조를 갖추고, 청중에게 명확하게 전달할 수 있도록 전문적인 언어와 체계적인 논리 전개를 사용하세요.
세부 지침:
1. 서론에서는 주제를 소개하고 발표의 목적과 중요성을 간략히 설명합니다.
2. 본론에서는 주요 내용을 객관적이고 체계적으로 제시합니다. 세부 사항보다는 큰 흐름에 초점을 맞춥니다.
3. 결론에서는 발표 내용을 요약하고 청중에게 남기는 메시지를 전달합니다.
4. 전체적으로 품위 있고 경어체를 사용하여 공식적인 분위기를 유지합니다.
5. 전문용어나 통계 데이터를 적절히 활용하여 발표의 신뢰성을 높입니다.
6. 시각적 자료(PPT 등)를 활용하여 청중의 이해를 돕습니다.
이러면 이러한 일을 하는 Agent를 PresentationScriptWriter라고 부를 수 있습니다. langchain이든 AutoGen이든 위의 방식으로 구현할 수 있습니다. 이후 만약 발표대본을 써야 한다면 이런 Agent를 불러다 쓰면 됩니다.
이렇게 업무에 필요한 Prompt를 미리 정의해 놓고 이를 필요할 때마다 불러쓴다면 어떨까요? 실제 이 예제는 내부에서 데이터 관련 작업을 하는데 필요한 것을 만들었던 것 중 하나입니다.
Agent 여러 개 동원하기
전문가 간의 대화 및 특정 페르소나가 부여된 LLM들 간의 대화 데이터를 생성할 때 활용됩니다. 페르소나가 부여된 LLM 에이전트들이 상호작용하며 최종 대화 데이터를 생성하는 방식입니다. 그러나 AutoGen에 구현된 LLM 에이전트 오케스트레이션은 시나리오에 특정 페르소나가 지정된 경우 원활하게 작동하지 않는 문제가 있습니다. 따라서 상황에 따라 LLM 에이전트 오케스트레이션을 사용하는 경우와 그렇지 않은 경우로 나누어 데이터를 생성해야 합니다.
LangGraph와 AutoGen을 같이 써서 일을 할 때도 있습니다. 대표적으로 데이터 관련 업무를 할 때 QA 생성 / 재작성 / 요약 테스트 수행을 위해 이렇게 만들어 봤습니다.
예를들어 AutoGen의 페르소나 생성함수를 이용해서 테스트별 전문 Agent를 생성합니다. 보통 이렇게 4분(?)을 모셔옵니다.
qa_agent_roles = {
"GeneralQAExpert": "일반 주제 QA 생성 전문가",
"TechnicalQAExpert": "기술 문서 QA 생성 전문가",
"EducationalQAExpert": "교육용 QA 생성 전문가",
"AnalyticalQAExpert": "분석적 사고 훈련용 QA 생성 전문가"
}
이렇게 하면 AutoGen의 페르소나 생성 함수로 각 Expert에 대한 구체적인 prompt가 자동으로 생성됩니다. 예를 들어 GeneralQAExpert는 아래와 같이 생성이 됩니다.
{
"name": "GeneralQAExpert",
"system_message": "GeneralQAExpert로서, 당신의 역할은 다양한 주제에 대해 정확하고 유용한 QA 셋을 생성하는 것입니다. 다음 지침을 따라 작업을 수행하십시오:\n\n1. 주어진 주제나 문서의 주요 개념과 핵심 사항을 신속하게 이해하십시오.\n2. 주제의 다양한 측면을 다룰 수 있도록 난이도와 유형이 다양한 질문을 구성하십시오 (예: 정의, 응용, 비교, 비판적 사고 등).\n3. 각 질문에 명확하고 정확한 답변을 제공하십시오.\n4. 질문과 답변이 주제의 전반적인 이해를 도울 수 있도록 체계적으로 구성하십시오.\n5. 필요에 따라 답변에 추가 설명, 예시, 또는 추가 문서를 포함하여 이해를 돕도록 하십시오.\n6. 생성된 QA 셋의 일관성과 논리적 연결을 유지하십시오.\n7. 대상 독자의 이해 수준과 목적에 맞게 QA 셋의 난이도와 내용 깊이를 맞추십시오.\n\nQA 셋을 생성할 때, 항상 정확성, 명확성, 접근성을 최고 우선으로 두고 작업하십시오. 추가 정보나 지침이 필요하면 이를 명확하게 요청하십시오.",
"description": "GeneralQAExpert는 다양한 주제에 대해 정확하고 유용한 QA 셋을 생성하며, 이를 위해 주제의 핵심 개념을 신속히 파악하고 난이도와 유형이 다양한 질문과 답변을 체계적으로 구성하여 독자의 이해를 돕는 역할을 합니다."
}
여기서 description은 system_message를 요약한 것으로 AutoGen 동작시에 매우 중요한 변수이지만 AutoGen 프레임워크를 사용하는 경우가 아니라면 사용하지 않습니다.
그리고 여기에는 공개할 수 없지만, 내부에서는 LLM Agent Orchestration이라는 것을 만들어서 쓰고 있습니다. 이것은 AutoGen의 Task 분석 후 Agent 자동 선택 기능과 LangGraph에서 제공하는 기본 Agent Orchestration기능을 합쳐서 구현한 것입니다. 이것은 Task에 맞는 Agent들을 자동으로 선택하고 선택된 Agent들은 LangGraph로 서로 상호작용할 수 있게끔 연결해주는 역할을 합니다.
결론
Agent라는 것을 만들어서 일을 하는 것은, 마치 새로운 조수를 채용하는 것 같은 느낌입니다. 그리고 마치 팀을 운영하는 거 같은 착각이 들기도 합니다.
저는 주로 LLM 시스템을 검증하는 데이터들을 만들때 이런 Agent들을 동원합니다. 만약 현재 하는 일들 중에 반복되고, 귀찮은 일들이 있다면 이런 Agent 를 이용해서 자신의 일들을 단순화하고 자동화 하기를 꼭 시도해보시기를 권합니다.
채용공고
서비스 개발팀은 현재 아래와 같은 포지션들을 열어놓고 있습니다. 저희와 같이 일하고 싶으신 분들은 지원 부탁드립니다.
- AI-Software Engineer(Senior)
- Front-end-engineer (Senior)
- AI-Software Engineer(Junior)
- Back-end-engineer(Junior)
참고
- 허정준 지음, 정진호 그림, 박재호 감수, LLM을 활용한 실전 AI애플리케이션 개발(2024), 책만
- AutoGen https://microsoft.github.io/autogen/
- Shubham Shardul, LangGraph: Challenges as a Multi-Agent Orchiestrator? (2024), https://medium.com/@shubham.shardul2019/is-langgraph-the-ultimate-multi-agent-maestro-explore-its-potential-and-hidden-hurdles-c7e454a3e089