프로덕션 환경을 위한 에이전트 설계 방법
요약
본 가이드는 LangChain과 OpenAI functions agent를 활용하여 Cal.ai와 같은 스케줄링 에이전트를 프로덕션 환경에 배포하는 기술적 원리를 설명합니다. 핵심은 LLM에게 필요한 도구(tools) 세트, 채팅 모델, 그리고 사용자 컨텍스트가 포함된 프롬프트를 제공하여 복잡한 작업을 수행하게 하는 것입니다.
핵심 포인트
- LangChain과 OpenAI functions agent를 사용해 스케줄링 에이전트를 구현합니다.
- 에이전트는 도구(tools), 채팅 모델, 접두사 프롬프트 세 가지 핵심 입력값을 필요로 합니다.
- 프롬프트에는 사용자 ID, 시간대 등 개인화된 컨텍스트 정보를 포함해야 합니다.
- 도구 오류 처리 및 사용자의 로컬 시간대 형식화가 중요합니다.
에디터 노트: 이 게시물은 Rubric Labs 팀의 Dexter Storey, Sarim Malik, Ted Spare가 작성했습니다.
중요 링크
목표
본 가이드는 LangChain을 사용하여 스케줄링 에이전트인 Cal.ai를 프로덕션 환경에 배포하는 데 사용되는 근간 기술과 논리를 설명합니다.
배경
최근 Rubric Labs 팀은 Cal.com의 AI 기반 이메일 비서 구축 기회를 가졌습니다. 참고로, 저희는 어려운 엔지니어링 문제를 해결하는 것을 좋아하는 빌더들로 구성된 팀입니다.
프로젝트의 비전은 복잡한 캘린더 관리 세계를 단순화하는 것이었습니다. 우리가 염두에 두었던 핵심 기능 중 일부는 다음과 같습니다:
비형식적인 이메일을 예약으로 전환:
에이전트는 파인튜닝된 GPT 모델 버전을 사용하는 LangChain OpenAI functions agent입니다. 이 에이전트에는 미리 정의된 함수 또는 도구(tools)가 전달되며, 어떤 함수를 호출해야 할지 감지할 수 있습니다. 이를 통해 필요한 입력값과 원하는 출력을 지정할 수 있습니다.
에이전트는 에이전트 루프(agent loop)에서 문서화되어 있습니다.
OpenAI functions agent에는 두 가지 필수 입력값이 필요합니다:
- Tools — 도구는 이름, 설명, 입력 스키마를 가진 간단한 Javascript 함수입니다.
- Chat model — 채팅 모델은 '채팅 메시지'가 입력값 및 출력값이 되는 LLM(대규모 언어 모델) 모델의 변형입니다.
도구와 채팅 모델 외에도, 모델에 컨텍스트를 추가하기 위해 접두사 프롬프트(prefix prompt)도 전달합니다. 각 입력값에 대해 살펴보겠습니다.
👉
명확한 이해를 돕기 위해 비유를 사용하겠습니다. 이 에이전트는 Peer라는 이름의 전기 기술자입니다. Peer는 다른 어떤 전기 기술자와도 달리, 수년간의 훈련과 학습을 통해 깊은 지능에 접근할 수 있습니다 (모델). 하지만 문제(입력)가 주어졌을 때, Peer의 작업(출력)이 항상 고객의 기대와 일치하지는 않습니다. 어느 날, Bailey라는 이름의 고객이 Peer를 고용하고 그에게 제한된 도구 세트—납땜 인두기, 배터리, 전선, 전구—를 제공합니다. Peer는 자신의 지식과 제공된 도구를 사용하여 Bailey의 기대에 정확히 부합하는 해결책을 제시합니다.
프롬프트(Prompt)
프롬프트란 컨텍스트를 제공하여 모델을 프로그래밍하는 방법입니다. 사용자 정보(userId, user.username, user.timezone 등)는 프롬프트를 구성하는 데 사용되어 에이전트에 전달됩니다.
const prompt = You are Cal.ai - a bleeding edge scheduling assistant that interfaces via email.`
최종 답변은 결정적이고, 완전하며, 잘 형식화되어야 합니다.
때로는 도구가 오류를 반환합니다. 이 경우, 오류를 지능적으로 처리하거나 사용자에게 더 많은 정보를 요청해야 합니다.
도구는 항상 UTC 시간을 처리하지만, 사용자에게 전송되는 시간은 해당 사용자의 시간대에 맞춰 형식화되어야 합니다.
주요 사용자의 ID는: ${userId}
주요 사용자의 사용자 이름은: ${user.username}
주요 사용자의 시간대에서의 현재 시간은: ${now(user.timeZone)}
주요 사용자의 시간대는: ${user.timeZone}
주요 사용자의 이벤트 유형들은: ${user.eventTypes}
주요 사용자의 근무 시간은: ${user.workingHours}
...
전체 프롬프트는 여기에서 찾을 수 있습니다.
채팅 모델 (Chat Model)
채팅 모델(chat model)은 언어 모델(language model)의 한 변형으로, 채팅 메시지를 입력과 출력으로 노출합니다. 이 프로젝트에서는 OPENAI_API_KEY를 사용하여 접근할 수 있는 OpenAI의 GPT-4 모델을 사용합니다 (API 키 생성 방법은 여기에서 읽어보세요).
더 나은 채택률을 위해 사용자 경험이 매우 빨라야 한다는 것을 알고 있었습니다. 저희는 gpt-3.5-turbo로 실험했지만, 흥미롭게도 더 우회적인 방식으로 작업을 완료하면서 전반적으로 시간이 더 오래 걸리는 경우가 많았습니다.
일관된 출력을 생성하기 위해 temperature를 0으로 설정했습니다. 온도가 높을수록 더 창의적이지만 일관성 없는 출력이 나옵니다.
`const model = new ChatOpenAI({
modelName: "gpt-4",
openAIApiKey: env.OPENAI_API_KEY,
temperature: 0,
});
도구 (Tools)
도구(tool)는 Javascript 함수, 이름, 입력 스키마(Zod 사용), 설명으로 구성되며 구조화된 데이터와 함께 작동하도록 설계되었습니다.
이 프로젝트에서 사용되는 도구들은 동적 구조화 도구(DynamicStructuredTool) 유형이며, 이는 구조화된 데이터와 함께 작동하도록 설계되었습니다. 동적 구조화 도구는 LangChain의 StructuredTool 클래스를 확장한 것으로, 기본적으로 제공된 함수로 _call 메서드를 재정의합니다. DynamicStructuredTool에 대한 스키마는 아래를 참조하세요.
`DynamicStructuredTool({
description: "주요 사용자의 캘린더에 예약을 생성합니다.", // 설명
func: createBooking(), // 함수
name: "createBooking", // 이름
schema: z.object({ // 스키마
from: z.string().describe("ISO 8601 날짜/시간 문자열"),
...
}),
});
DynamicStructuredTool의 입력값에 대한 전체 예시는 여기에서 볼 수 있습니다.
도구(tools) 세트를 생성함으로써, 우리는 에이전트에게 미리 정의된 작업을 수행할 수 있는 추가적인 기능을 제공합니다. 이 프로젝트에 사용되는 모든 도구는 여기에 문서화되어 아래에 나열됩니다. 각 도구는 사용자 요청을 이해하고, CRUD 작업을 수행하여 Cal.com API와 상호 작용하며, 응답을 처리할 수 있도록 하는 복잡한 로직을 가지고 있습니다.
`const tools = [
createBooking(apiKey, userId, users),
deleteBooking(apiKey),
getAvailability(apiKey),
getBookings(apiKey, userId),
sendBookingLink(apiKey, user, users, agentEmail),
updateBooking(apiKey, userId),
];
위 도구들의 입력값은 AI 에이전트가 접근해서는 안 되는 변수들이므로, 에이전트 루프를 우회하여 해당 도구에 주입됩니다.
동적 프롬프트와 채팅 모델을 사용하여, 도구 파서(tool parser)는 사용자 요청을 처리하는 데 가장 적합한 도구를 선택하고, 원하는 동작을 수행할 수 있을 때까지 반복적으로 실행합니다. 이는 오류가 발생할 경우 대체 도구를 선택하여 폴백(fallback)을 허용하는 것까지 포함하는 반복적 학습(iterative learning)을 따릅니다.

Executor
마지막으로, 이 도구들, 채팅 모델, 프롬프트는 에이전트를 초기화하고 실행기(executor)를 실행하여 응답을 생성하는 데 사용됩니다.
`const executor = await initializeAgentExecutorWithOptions(tools, model, {
agentArgs: { prefix: prompt }},
agentType: "openai-functions",
verbose: true,
});
응답 (Response)
에이전트가 다양한 도구를 활용하여 루프를 돌고, LLM 모델과 채팅하며 Cal.com API와 상호 작용하는 과정을 거치면, 최종 응답을 내보내며 종료됩니다. 이 응답은 Sendgrid나 Resend 같은 이메일링 서비스를 사용하여 사용자에게 이메일로 전송됩니다. 해당 이메일은 확인(confirmation) 또는 오류(error) 중 하나가 될 것입니다.
기술 스택 (Tech Stack)
결론 (Conclusion)
AI 에이전트가 스코프된 도구(scoped tools)를 갖추는 것은 정말 강력한 조합임이 분명합니다. LLM 모델의 지식과 구조화된 도구를 결합하는 것은 자연어 문제에 구조화된 데이터를 적용하여 해결하는 데 도움을 주며, 이는 해당 에이전트의 신뢰성을 높입니다. 저희는 AI 에이전트가 계속 발전함에 따라 그 미래에 매우 기대하고 있으며, Cal.com 및 LangChain과의 파트너십을 통해 프로덕션 환경에서 오픈 소스 에이전트를 구축하는 것이 향후 프로젝트를 위한 템플릿 역할을 하기를 바랍니다.
💬
본 게시물에 대한 피드백이 있으시면 [email protected]으로 연락 주십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 LangChain Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기