이것은 Lyft의 친구들로부터의 게스트 포스트입니다. SCX 데이터 사이언스 및 MLE 팀이 기술이 아닌 도메인 전문가가 AI 에이전트를 배포할 수 있게 해주는 멀티 에이전트 고객 지원 시스템을 구축했습니다. 머신러닝 엔지니어 Akshay Sharma가 주도했습니다. 귀중한 기여감사드립니다.
TL;DR
LangGraph를 활용하여 정교한 멀티 에이전트 시스템을 조율함으로써 Lyft는 고객 지원 운영을 변화시켰고, 라이더와 드라이버의 수백만 건의 상호작용을 관리하고 있습니다. 저희 "셀프 서빙" 플랫폼은 LangGraph의 서브그래프 아키텍처와 LangSmith의 강력한 추적 및 모니터링 도구를 통합하여 기술이 아닌 도메인 전문가가 독립적으로 AI 에이전트를 개발하고 개선할 수 있도록 힘을 실어줍니다. 이러한 전환은 에이전트 개발 시간을 대략 6개월에서 단 몇 주로 단축시켰으며, 자동화된 LLM-as-a-judge 평가 시스템을 통해 높은 기준을 유지하고 있습니다.
Lyft의 목표: 안전하게 에이전트 반복 속도 높이기
계정 접근, 손상 청구, 요금 검토 및 수익 분쟁을 포함한 수많은 범주에서 Lyft의 AI Assist는 라이더와 드라이버의 고객 지원을 관리합니다. 저희의 여정은 2023년에 시작되었지만 프로세스는 노동 집약적이었습니다. 각 AI 에이전트를 개발하려면 머신러닝 엔지니어(MLE)와 엔지니어링 팀의 몇 개월에 걸친 헌신적인 작업이 필요했습니다. 라이더와 드라이버를 위한 에이전트를 성공적으로 출시했으며 효율성도 증가했지만, 전체적인 속도는 여전히 상당한 병목이었습니다.
2026년까지 저희의 기존 운영 모델은 새로운 사용자 세그먼트, 추가 문제 유형, 자율 주행 자동차 지원 등으로 인한 지속 불가능한 수요 급증에 직면했습니다. 개발 사이클은 느린 반복 루프에 의존했습니다. 도메인 전문가는 워크플로우 동작을 정의하고, MLE는 이를 도구 설정 및 프롬프트로 변환했습니다. 추적을 검토하고, 문제를 지적하고, 코드를 조정하는 이러한 왕복은 모든 단일 에이전트마다 주 단위의 협업이 필요했습니다. 결과적으로 고객 문제에 대한 가장 깊은 이해를 가진 사람들은 기술적 중개자 없이 솔루션을 구현할 수 없었습니다.
이는 우리에게 중대한 질문으로 이어졌습니다. ops 팀, VoC 리더, 제품 관리자가 자연어를 사용하여 에이전트를 직접 구성하고 개선할 수 있을까요? 저희의 목표는 일일 반복 프로세스에서 기술적 중개자를 제거하여 학습과 배포를 가속화하는 것이었습니다. 중요하게도, 이러한 셀프 서빙으로의 전환은 경험, 정확성 및 안전성에 대한 엄격한 기준을 손상시킬 수 없었습니다. 모든 에이전트는 여전히 수동으로 설계된 시스템의 품질과 일치해야 했습니다.
아키텍처: LangGraph를 기반으로 구축된 멀티 에이전트 시스템
라우터 멀티 에이전트 패턴
저희 시스템은 LangGraph의 라우터 멀티 에이전트 아키텍처를 따릅니다. 메타 에이전트는 상태 저장 라우터로 작동합니다. 들어오는 요청을 분류하고 Command(goto=...)를 사용하여 적절한 특화된 서브에이전트로 디스패치합니다. 각 서브에이전트는 완전한 LangGraph StateGraph이며 메타 에이전트의 서브그래프 노드로 등록됩니다.
라이더와 드라이버를 위해 별도의 라우터 인스턴스를 실행합니다. 라이더가 지원을 요청하면 메타 에이전트가 rider_intent 서브에이전트로 라우팅하고, 이는 라이더별 의도에 대해 분류합니다(예: 분실물, 요금 분쟁, 여행 문제). 드라이버의 경우 driver_intent 서브에이전트로 라우팅하고, 이는 드라이버별 의도를 처리합니다(예: 수익, 계정 접근, 손상 청구). 의도 에이전트가 대화 중에 사용자가 더 전문화된 에이전트가 필요하다고 판단하면 Command(goto=..., graph=Command.PARENT)를 사용하여 메타 에이전트로 제어를 반환하고, 메타 에이전트는 적절한 전문가로 재라우팅합니다. 예를 들어 드라이버 의도 에이전트에서 손상 청구 에이전트로 대화 중에 점프합니다.
각 서브에이전트는 전문화 여부와 관계없이 일관된 노드 패턴을 따릅니다:
이는 우리에게 두 가지 중요한 특성을 제공합니다. 첫째, 안전성이 매 턴마다 병렬로 실행되므로 악의적 의도 감지 및 안전 문제 감지가 LLM 추론이 일어나기 전에 LangGraph의 Command(goto=[...]) 팬아웃을 통해 동시에 실행됩니다. 둘째, 서브에이전트는 모듈식이고 독립적으로 배포 가능합니다. 새 에이전트를 추가한다는 것은 새 서브그래프를 정의하고 메타 에이전트에 등록하는 것을 의미합니다.
전문화된 에이전트와 구성 가능한 에이전트
에이전트의 두 가지 범주가 있습니다:
전문화된 에이전트는 복잡한 고위험 워크플로우를 위해 MLE에 의해 손으로 만들어집니다. 예를 들어 저희의 손상 청구 에이전트는 이미지 처리, 부정 행위 감지, 다단계 분류 및 로우 코드 접근 방식으로는 너무 복잡한 자동화 호출을 지원합니다.
구성 가능한 에이전트는 셀프 서빙 레이어입니다. 이들은 저희의 내부 설정 서비스에 저장된 JSON 설정에서 런타임에 초기화되며, 프롬프트는 LangSmith의 프롬프트 허브에서 가져옵니다. 도메인 전문가는 저희의 구조화된 템플릿(역할, 범위, 워크플로우 단계, 콘텐츠 지침)에 따라 프롬프트를 작성하고, ConfigurableAgent 클래스가 나머지를 처리합니다: 그래프 구성, 도구 바인딩, 안전 게이트 및 상태 관리.
# 구성 가능한 에이전트는 시작 시 동적으로 로드됩니다
for configurable_agent in load_configurable_agents():
self.configurable_subagents[configurable_agent.config.intent] = configurable_agent
# 각각은 메타 에이전트에 서브그래프로 등록됩니다
for configurable_subagent in self.configurable_subagents.values():
graph_builder.add_node(
configurable_subagent.config.intent,
configurable_subagent.get_state_graph()
)
graph_builder.add_edge(configurable_subagent.config.intent, "finalize")이는 제품 관리자가 예를 들어 드라이버 세금 질문을 위한 에이전트를 정의할 수 있다는 의미입니다. 프롬프트와 JSON 설정을 작성하면 됩니다. MLE 코드 변경이 필요하지 않습니다. 플랫폼이 그래프 구성, 도구 실행, 체크포인팅, 추적 및 안전성을 처리합니다.
DynamoDB를 사용한 상태 지속성
다중 턴 대화에는 지속적인 상태가 필요합니다. 저희는 LangGraph의 BaseCheckpointSaver 인터페이스를 구현하는 커스텀 DynamoDBSaver를 구축했으며, 인메모리 가정 없이 턴 간 지속적인 대화 상태를 제공합니다. 각 체크포인트는 전체 그래프 상태, 실행 메타데이터 및 부모 체크포인트 참조를 저장하여 프로덕션에서 대화 재생, 디버깅 및 상태 검사를 가능하게 합니다.
LangSmith: 추적에서 프로덕션 모니터링까지
모든 에이전트 턴 추적
LANGSMITH_TRACING=true를 사용하여 모든 환경(개발, 스테이징, 프로덕션)에 걸쳐 모든 에이전트 호출이 LangSmith로 추적됩니다. 각 추적은 전체 그래프 실행을 캡처합니다: 어떤 노드가 실행되었는지, LLM이 무엇을 보았는지, 어떤 도구가 호출되었는지, 토큰 사용량 및 매 단계의 지연 시간.
저희는 필터링을 위한 런타임 메타데이터를 구축하는 유틸리티를 사용하여 커스텀 메타데이터로 추적을 풍부하게 합니다:
# 메타데이터는 LangSmith로 흘러가 필터링 및 디버깅을 위해 사용됩니다
tags = build_langsmith_metadata(
agent_name=self.name,
user_type=context.user_type,
interaction_id=context.interaction_id
)이는 매우 가치 있었습니다. 드라이버가 혼란스러운 응답을 보고할 때 정확한 추적을 가져와 모든 노드의 입출력을 보고, 문제가 의도 분류, 도구 실행 또는 최종 LLM 응답에 있었는지 식별하고 몇 시간 내에 수정할 수 있습니다.
LLM-as-a-Judge 평가 파이프라인
어떤 에이전트가 트래픽의 100%에 출시되기 전에 저희의 평가 파이프라인을 통과해야 합니다. 프로세스:
- 소규모 프로덕션 출시(5~10%) — 에이전트가 낮은 볼륨의 실제 트래픽을 제공합니다.
- 샘플 프로덕션 추적 — 저희는 실제 대화를 평가 데이터셋으로 캡처합니다.
- LLM-as-a-Judge 평가자 실행 — LangSmith의 프롬프트 허브의 공유 판사 프롬프트 템플릿을 사용하여 에이전트별 메트릭으로 확장합니다.
저희의 기본 평가 메트릭(모든 에이전트에 적용):
그러면 각 전문화된 에이전트에 대해 일부 도메인별 메트릭을 추가합니다. 예를 들어, 핵심 수익 에이전트는 에이전트가 관련 정책을 따랐거나 벗어났는지, 또는 비논리적이거나 일관성 없는 추론을 사용했는지를 확인합니다.
평가자는 LangSmith의 다중 턴 평가자를 사용하여 프로덕션 추적에 대해 자동으로 실행되며, 스레드 필터(예: run name is ride_earnings)와 초기 출시 중에는 높고 신뢰도가 증가함에 따라 점감하는 샘플링 속도로 구성됩니다.
프로덕션 모니터링 대시보드
프로덕션의 모든 에이전트에는 다음을 추적하는 복제된 LangSmith 모니터링 대시보드가 있습니다:
- 실행 볼륨 및 오류율 — 예상치 못한 스파이크나 장애가 발생하고 있나요?
- p50/p95 지연 시간 — 에이전트가 실시간 지원에 충분히 빠르게 응답하고 있나요?
- 토큰 사용량 — 비용이 예산 범위 내인가요?
- 도구 호출 성공률 — 외부 API 통합이 건강한가요?
- 시간 경과에 따른 LLM-as-a-Judge 점수 — 품질이 상향 또는 하향 추세인가요?
저희는 또한 LangSmith 메트릭에 의해 트리거되는 PagerDuty 경고를 설정했습니다. 오류율이 5%를 초과하거나 p95 지연 시간이 15분 윈도우에서 10초를 넘으면 온콜 엔지니어에게 자동으로 페이지됩니다.
프로덕션 모니터링 대시보드의 일부인 도구별 오류율의 예시 차트
프로덕션에서 실행 중인 커스텀(에이전트별) 메트릭을 사용한 LLM Judge 평가. 팁: 점수보다는 이진 출력(True/False 또는 Pass/Fail)을 사용하세요. 점수는 부정확하고 실행 불가능합니다.
어려운 교훈: 프롬프트 품질이 인프라가 아닌 병목
저희가 에이전트 빌딩을 기술이 아닌 팀원에게 개방했을 때, 가장 어려운 부분은 플랫폼 자체(도구 바인딩을 올바르게 처리, 그래프의 엣지 케이스 처리, 상태 관리)일 것이라고 가정했습니다. 저희가 틀렸습니다.
가장 어려운 부분은 프롬프트 품질이었습니다. 도메인 전문가는 그들의 문제 유형을 깊이 있게 알고 있었지만 항상 그 지식을 LLM이 안정적으로 따를 수 있는 명령으로 변환하는 방법을 알고 있었던 것은 아닙니다. 저희는 행복한 경로를 아름답게 처리했지만 엣지 케이스에서 무너진 에이전트를 보았습니다. 프롬프트가 드라이버가 요금을 분쟁할 때 에이전트가 해야 할 일을 정의했을 수도 있지만, 드라이버가 대화 중에 주제를 바꾸면 어떤 일이 일어나는지에 대해서는 아무 말도 없었습니다. 또는 톤 섹션이 "공감하다"라고 말했지만 그것이 실제로 무엇을 의미하는지 지정하지 않아 LLM이 매번 다르게 해석했습니다.
실패 모드는 놀랍도록 일관되었습니다: 범위 벗어난 정의 누락(에이전트가 도구가 없는 질문에 답하려고 시도함), 모호한 분기 논리(명시적 진입 또는 종료 조건이 없는 단계), 그리고 종이에는 좋게 들리지만 LLM에게 즉흥할 수 있는 너무 많은 여유를 제공하는 모호한 콘텐츠 지침.
저희는 두 가지 방향에서 이것을 공격했습니다.
첫째, 구조화된 프롬프트 작성 프레임워크입니다. 저희는 다섯 가지 필수 요소를 포함하는 템플릿을 만들었습니다: 정체성(이 에이전트는 누구인가, 어떤 사용자 유형, 어떤 주제 영역), 주요 목표(모호한 "도움" 또는 "처리"가 아닌 구체적인 동사), 범위(범위 내 AND 범위 외 명시적 라우팅 작업 포함), 단계 워크플로우(각 if/else에 대한 진입 조건, 분기 및 모든 단계에 대한 터미널 작업을 포함한 번호 매김 단계), 콘텐츠 지침(추상적 원칙이 아닌 구체적 do/don't 규칙과 예시 구문). 저희는 이를 모든 프롬프트가 활성화 전에 통과해야 하는 검토 체크리스트와 쌍을 이루었으며, "모든 단계가 출구를 가지고 있는가?" 및 "도구를 사용할 수 없을 때 수행할 작업에 대한 명령이 있는가?"와 같은 것들입니다.
둘째, 자동화된 프롬프트 검증입니다. 저희는 어떤 프롬프트가 프로덕션에 도달하기 전에 실행되는 Git 기반 프롬프트 린팅 파이프라인을 구축하고 있습니다. 도메인 전문가가 저희의 빌더 UI에서 프롬프트 작성을 마치면 저희의 설정 저장소에 대해 풀 요청을 엽니다. 그러면 CI 파이프라인이 두 가지 검사 레이어를 실행합니다: 빠른 정적 규칙(형식이 잘못된 템플릿 변수, 중복 의도 슬러그, 맞춤법 오류 포착) 다음으로 프롬프트 주입 취약점, 모순된 명령 및 구조적 막다른 지점을 감지하는 LLM 구동 규칙(대화 흐름에 빠져나갈 수 없는 경우). 모든 위반이 병합을 차단합니다. 저자는 UI에서 인라인 피드백을 받고 MLE를 끌어들일 필요 없이 문제를 직접 수정할 수 있습니다.
이 모든 것의 핵심 통찰: 프롬프트를 코드 주석이 아닌 제품 사양으로 취급하세요. 프롬프트가 더 명시적일수록, 에이전트는 더 일관됩니다. 그리고 품질 문제를 더 일찍 포착할수록, 이상적으로는 단일 실제 고객이 출력을 보기 전에, 전체 시스템이 개선되는 속도가 빨라집니다.
결과
셀프 서빙 에이전트 플랫폼을 출시한 이후:
- 에이전트 개발 시간: ~6개월(첫 드라이버 에이전트)에서 새로운 구성 가능한 에이전트의 경우 ~2주로 단축.
- 에이전트 커버리지: 여러 문제 유형을 다루는 프로덕션의 성장하는 수의 구성 가능한 에이전트, 여러 전문화된 에이전트와 함께.
- 평가 커버리지: 프로덕션의 100% 에이전트에는 라이브 추적에 대해 실행되는 자동화된 LLM-as-a-Judge 파이프라인이 있습니다.
- 품질: 저희가 Langsmith 평가 메트릭을 기반으로 설정한 환각 가드레일로 인해 환각 및 모순 비율이 20% 감소했습니다.
- 운영 효율성: 많은 비엔지니어링 팀 멤버가 이제 독립적으로 에이전트를 구축하고 반복하고 있습니다.
- AI 해결률: 저희의 셀프 서빙 플랫폼을 사용하여 몇 가지 에이전트를 출시한 이후 16% 증가했습니다.
다음 단계
저희는 이 플랫폼을 더욱 발전시킬 수 있는 몇 가지 영역을 살펴보고 있습니다:
- 프롬프트 린팅 파이프라인 완성 — 위에서 설명한 Git 기반 CI 검증은 적극적으로 개발 중입니다. 완전히 출시되면, 모든 구성 가능한 에이전트 프롬프트는 프로덕션에 도달하기 전에 자동화된 정적 및 LLM 구동 검사를 통과해야 하며 일반적인 오류에 대한 수동 MLE 검토가 0이 됩니다.
- 모킹 및 시뮬레이션 인프라 — 에이전트 빌더가 실제 트래픽에 배포하기 전에 합성 대화 및 모킹된 도구 응답에 대해 테스트할 수 있는 시뮬레이션 레이어를 구축하여 새 에이전트에 대한 피드백 루프를 크게 단축합니다.
- 쌍 평가 — LangSmith의 쌍 주석 큐를 사용하여 출시 전 인간 검토자와 프롬프트 수정을 A/B 테스트합니다.
- 더 많은 지역 및 사용자 유형으로 확장 — Freenow 고객을 유럽으로 확장하고 자율 주행 자동차 지원 시나리오로 플랫폼을 가져옵니다.
- 더 깊은 평가 자동화 — 샘플링된 평가에서 모든 프로덕션 추적에 대한 연속 채점으로 이동하고, 자동 프롬프트 성능 저하 경고를 제공합니다.