Laravel AI 에이전트에 실시간 웹 지식 부여하기
요약
Laravel AI SDK를 사용할 때 특정 AI 제공자에 종속된 웹 검색 도구의 한계와 위험성을 분석합니다. 제공자별 기능 차이로 인한 장애 조치(failover) 실패 문제를 지적하며, 이를 해결하기 위해 커스텀 도구를 직접 구축하는 방식을 제안합니다.
핵심 포인트
- 제공자 종속적 웹 도구는 모델 교체 시 기능 누락 위험이 있음
- WebSearch와 WebFetch는 모든 모델에서 동일하게 작동하지 않음
- 기존 도구는 결과값이 가공되지 않아 구조화된 답변이 어려움
- 안정적인 에이전트를 위해 커스텀 Tool 클래스 활용 권장
- Tabstack 패키지를 통한 독립적인 웹 리서치 도구 구축 가능
Laravel AI SDK의 가장 큰 장점 중 하나는 특정 제공자(provider)에 종속되지 않는다는 점입니다. OpenAI를 Anthropic으로 교체하거나, 장애 조치(failover)를 위해 Gemini를 추가하더라도 에이전트 코드는 거의 바뀌지 않습니다. 이것이 핵심적인 가치 제안이며, 대부분의 경우 그 가치가 유지됩니다.
하지만 당신의 에이전트가 웹을 탐색해야 할 때 문제가 발생합니다.
제공자 불가지론(provider-agnostic) 약속의 허점
이 SDK는 에이전트에게 웹 접근 권한을 부여하기 위해 두 가지 제공자 도구인 WebSearch와 WebFetch를 제공합니다. 이들은 매우 편리하여, 몇 줄의 코드만으로 에이전트가 검색을 하거나 페이지를 가져올 수 있습니다. 하지만 이들은 SDK의 통합 레이어(unified layer)의 일부가 아닙니다. 대신 당신이 사용하는 AI 제공자에 의해 네이티브하게 구현되어 있으며, 이는 해당 기능의 가용성이 당신이 선택한 모델이 무엇인지에 따라 전적으로 달라짐을 의미합니다.
WebSearch는 Anthropic, OpenAI, Gemini, 그리고 OpenRouter에서 작동합니다. WebFetch는 Anthropic과 Gemini에서만 작동합니다. 따라서 만약 당신이 Groq, DeepSeek, Mistral 또는 xAI를 포함하는 장애 조치 체인(failover chain)을 구성했는데, 이들 중 하나가 활성 제공자가 된다면, 당신의 에이전트는 조용히 웹 탐색 능력을 상실하게 됩니다. 에러도, 경고도 발생하지 않습니다. 그저 출처를 인용하지 않거나, 확인했어야 할 페이지가 변경되었음을 인지하지 못하는 에이전트가 될 뿐입니다.
이는 운영 환경(production)에서 발견하기에는 매우 뼈아픈 일입니다. 속도 제한(rate limit)이나 서비스 중단으로 인해 기능이 중단되는 것을 막기 위해 특별히 장애 조치 체인을 구축했는데, 알고 보니 폴백 제공자(fallback provider) 중 하나가 내내 특정 기능을 조용히 누락하고 있었던 셈이니까요.
작동하더라도 매우 얕은 수준입니다
제공자 문제는 잠시 제쳐두더라도, WebSearch와 WebFetch가 모두 사용 가능한 제공자라 할지라도, 반환되는 결과물은 가공되지 않은(raw) 상태입니다. 즉, 검색 결과나 가져온 페이지 콘텐츠를 모델이 스스로 추론해야 합니다. 스키마(schema)도 없고, 보장된 인용 추적(citation tracking)도 없습니다. 만약 에이전트가 구조화되고 출처가 명시된 답변을 반환하기를 원한다면, 그 추론 과정은 당신이 제어하거나 테스트할 수 있는 레이어가 아닌, 모델 자체의 추론(inference) 과정 어딘가에서 일어나게 됩니다.
많은 유스케이스 (use cases)에서는 그것으로 충분합니다. 하지만 답변이 방어 가능하거나 재현 가능해야 하는 경우, 즉 연구 보조원, 경쟁사 분석 보고서(competitive brief), 또는 사용자가 "이 정보가 어디에서 왔나요?"라고 물을 수 있는 모든 상황에서는 그것만으로는 충분하지 않습니다.
어떤 프로바이더가 활성화되어 있든 상관없는 인프라 위에서 직접 도구를 구축하세요
해결책은 프로바이더 네이티브 (provider-native) 웹 도구에 의존하는 것을 멈추고, 대신 에이전트에게 커스텀 도구 (custom tool)를 제공하는 것입니다. 이는 프롬프트에 답변하는 모델이 무엇인지와 상관없이 API에 의해 뒷받침되는 도구입니다. 이것이 바로 Laravel AI SDK의 Tool 클래스가 존재하는 이유입니다.
juststeveking/tabstack은 이를 구축할 수 있는 클라이언트를 제공합니다. 이 패키지의 agent()->research() 메서드는 질문을 받고, 여러 소스를 검색하며, 답변을 합성하고, 인용구가 포함된 보고서를 스트리밍으로 반환하는 과정을 단 한 번의 호출로 수행합니다.
이 패키지는 Laravel 통합 기능을 기본적으로 제공하지 않으므로, 첫 번째 단계는 어디에서든 주입 (injection)될 수 있도록 서비스 프로바이더 (service provider)에 바인딩하는 것입니다:
<?php
namespace App\Providers;
...
config/services.php에 키를 추가합니다:
'tabstack' => [
'key' => env('TABSTACK_API_KEY'),
],
이제 도구 자체를 구현해 보겠습니다. 이는 agent()->research()를 래핑 (wrap)하여 에이전트에게 출처가 나열된 보고서를 전달합니다:
<?php
namespace App\Ai\Tools;
...
->result() 호출은 스트림이 완료될 때까지 블로킹 (blocking)되며, 사용자가 직접 이벤트를 소비하게 하는 대신 타입이 지정된 ResearchResult를 반환합니다. 덕분에 도구의 handle 메서드를 단순하게 유지할 수 있습니다. 만약 진행 상황을 실시간으로 에이전트에게 스트리밍하고 싶다면, 클라이언트는 ->each()와 원시 반복 (raw iteration) 기능도 제공하지만, 도구 호출 (tool call)의 경우에는 일반적으로 블로킹된 결과값을 원하는 경우가 많습니다.
다른 도구와 마찬가지로 tools 메서드를 통해 어떤 에이전트에도 연결할 수 있습니다:
<?php
namespace App\Ai\Agents;
...
이제 프로바이더를 원하는 대로 교체해 보세요:
$response = (new MarketAnalyst)->prompt(
'What are the current pricing trends for cloud browser automation APIs?',
provider: [Lab::OpenAI, Lab::Anthropic, Lab::Groq],
...
에이전트의 웹 조사 능력은 세 가지 중 어떤 모델이 프롬프트에 응답하느냐에 따라 달라지지 않습니다. 도구는 여러분의 것이며, 어떤 모델이 이를 호출하든 동일하게 작동합니다.
이것이 단순 fetch보다 뛰어난 이유
지원되는 프로바이더(provider)에서 WebFetch를 사용하여 특정된 알려진 URL을 가리키도록 설정함으로써 유사한 기능을 구축할 수도 있습니다. 하지만 이는 정답이 있는 페이지가 어디인지 이미 알고 있을 때만 작동합니다. /research는 그 반대의 경우, 즉 출처를 알 수 없는 질문을 위해 설계되었습니다. 이 경우의 핵심 가치는 적절한 출처를 선택하고, 이를 읽고, 증거(receipts)를 첨부하여 단일한 답변으로 합성하는 데 있습니다. 이는 단일 페이지를 가져오는(fetching) 것과는 진정으로 다른 작업이며, SDK의 내장 도구들이 시도하지 않는 영역입니다.
요약 (The takeaway)
Laravel AI SDK의 프로바이더 독립성(provider independence)은 가장 큰 특징 중 하나이지만, 실제로는 그 독립성에 포함되지 않는 도구를 사용하려 할 때 한계에 부딪힙니다. 웹 접속은 프롬프트에 응답한 모델이 무엇인지에 따라 에이전트가 잃어버려서는 안 되는 기능이어야 합니다. 현재 프로바이더가 무엇을 노출하고 있는지에 의존하는 대신, API를 기반으로 한 실제 Tool 클래스로 이를 구축하는 것이 그 약속을 온전히 유지하는 방법입니다.
Laravel AI SDK로 에이전트를 구축 중이며 이러한 도구를 즉시 사용하고 싶다면, Packagist의 juststeveking/tabstack에서 시작해 보시길 권장합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기