멀티 에이전트 시스템 빌드

대규모 언어 모델의 강력한 애플리케이션은 LLM 기반 에이전트입니다. 에이전트는 태스크를 더 작은 태스크로 분할하는 방법을 계획하고 도구 호출을 사용하여 데이터베이스 또는 실제 기기와 같은 외부 리소스와 상호작용하는 태스크를 실행하여 복잡한 태스크를 실행할 수 있는 시스템입니다.

다음은 단일 프롬프트와 여러 도구를 사용하여 빌드된 매우 간단한 고객 서비스 상담사의 일부 발췌 내용입니다.

const menuLookupTool = ai.defineTool(
  {
    name: 'menuLookupTool',
    description: 'use this tool to look up the menu for a given date',
    inputSchema: z.object({
      date: z.string().describe('the date to look up the menu for'),
    }),
    outputSchema: z.string().describe('the menu for a given date'),
  },
  async (input) => {
    // Retrieve the menu from a database, website, etc.
    // ...
  }
);

const reservationTool = ai.defineTool(
  {
    name: 'reservationTool',
    description: 'use this tool to try to book a reservation',
    inputSchema: z.object({
      partySize: z.coerce.number().describe('the number of guests'),
      date: z.string().describe('the date to book for'),
    }),
    outputSchema: z
      .string()
      .describe(
        "true if the reservation was successfully booked and false if there's" +
          ' no table available for the requested time'
      ),
  },
  async (input) => {
    // Access your database to try to make the reservation.
    // ...
  }
);
const chat = ai.chat({
  model: gemini15Pro,
  system:
    "You are an AI customer service agent for Pavel's Cafe. Use the tools " +
    'available to you to help the customer. If you cannot help the ' +
    'customer with the available tools, politely explain so.',
  tools: [menuLookupTool, reservationTool],
});

에이전트에 기능이 몇 개만 있는 경우 위와 같은 간단한 아키텍처로 충분할 수 있습니다. 하지만 위의 제한된 예시에서도 고객이 기대할 만한 몇 가지 기능이 있습니다. 예를 들어 고객의 현재 예약을 표시하거나 예약을 취소하는 기능 등이 있습니다. 이러한 추가 기능을 구현하기 위한 도구를 점점 더 많이 빌드하면 몇 가지 문제가 발생하기 시작합니다.

  • 도구를 추가할수록 작업에 적합한 도구를 일관되게 올바르게 사용하는 모델의 기능이 확장됩니다.
  • 일부 작업은 단일 도구 호출이 아닌 사용자와 상담사 간에 더 집중된 대화로 처리하는 것이 가장 좋을 수 있습니다.
  • 일부 작업에는 특수 프롬프트가 유용할 수 있습니다. 예를 들어 상담사가 불만족한 고객에게 응답하는 경우 더 비즈니스적인 어조를 사용하는 것이 좋지만, 처음에 고객을 맞이하는 상담사는 더 친근하고 가벼운 어조를 사용할 수 있습니다.

복잡한 에이전트를 빌드할 때 발생하는 이러한 문제를 해결하는 한 가지 방법은 여러 개의 전문 에이전트를 만들고 범용 에이전트를 사용하여 작업을 위임하는 것입니다. Genkit은 프롬프트를 도구로 지정할 수 있도록 허용하여 이 아키텍처를 지원합니다. 각 프롬프트는 자체 도구 세트를 사용할 수 있는 단일 전문 에이전트를 나타내며, 이러한 에이전트는 사용자와의 기본 인터페이스인 단일 오케스트레이션 에이전트의 도구로 사용할 수 있습니다.

다음은 이전 예의 확장 버전이 다중 에이전트 시스템으로 표시되는 모습입니다.

// Define a prompt that represents a specialist agent
const reservationAgent = ai.definePrompt(
  {
    name: 'reservationAgent',
    description: 'Reservation Agent can help manage guest reservations',
    tools: [reservationTool, reservationCancelationTool, reservationListTool],
  },
  '{{role "system"}} Help guests make and manage reservations'
);

// Or load agents from .prompt files
const menuInfoAgent = ai.prompt('menuInfoAgent');
const complaintAgent = ai.prompt('complaintAgent');

// The triage agent is the agent that users interact with initially
const triageAgent = ai.definePrompt(
  {
    name: 'triageAgent',
    description: 'Triage Agent',
    tools: [reservationAgent, menuInfoAgent, complaintAgent],
  },
  `{{role "system"}} You are an AI customer service agent for Pavel's Cafe.
  Greet the user and ask them how you can help. If appropriate, transfer to an
  agent that can better handle the request. If you cannot help the customer with
  the available tools, politely explain so.`
);
// Start a chat session, initially with the triage agent
const chat = ai.chat(triageAgent);