Delphi에서 AI 에이전트 만들기: 함수 호출과 MCP 도구 사용

· 컴포넌트

빠른 답변: AI 에이전트는 그저 당신의 코드를 호출할 수 있는 언어 모델입니다. 당신은 일련의 도구를 설명하고, 모델은 그중 하나를 언제 호출할지 결정하며, 당신의 애플리케이션이 그것을 실행해 결과를 반환하면, 모델은 거기서부터 이어갑니다 — 작업이 끝날 때까지 루프로요. sgcWebSockets는 Delphi나 C++ Builder에서 이를 만드는 두 가지 방법을 제공합니다. 제공자 함수 호출(모델이 OpenAI, Anthropic 또는 Gemini 컴포넌트를 통해 당신의 함수 중 하나를 호출하도록 요청)과 MCP(개방형 Model Context Protocol로, 당신의 서버가 도구를 노출하면 MCP를 지원하는 어떤 클라이언트나 에이전트든 이를 발견하고 호출할 수 있음)입니다. 둘 다 같은 아이디어를 사용하며, 에이전트가 어디에 사는지에 맞는 것을 고르면 됩니다.

사람들은 때때로 "에이전트"를 특별한 모델로 상상합니다. 그렇지 않습니다. 그것은 평범한 채팅 모델에, 모델이 대화 밖으로 손을 뻗을 수 있게 하는 당신 코드 안의 작은 제어 루프를 더한 것입니다. 모델이 데이터베이스를 쿼리하거나, 파일을 읽거나, 내부 API를 호출하는 함수를 부를 수 있게 되면, 그것은 챗봇이기를 멈추고 행동할 수 있게 됩니다. 아래의 두 경로는 오직 누가 도구를 호스팅하는가에서만 다릅니다.

에이전트 루프

제공자에 관계없이 모든 에이전트는 같은 주기를 따릅니다.

  1. 사용자의 메시지를 도구 정의 목록(이름, 설명, 매개변수)과 함께 보냅니다.
  2. 모델은 평문으로 답하거나, "이 인자로 도구 X를 호출하라"고 응답합니다.
  3. 도구를 요청하면, 당신의 코드가 실제 작업을 실행하고 결과를 돌려줍니다.
  4. 모델은 결과를 읽고 또 다른 도구를 호출하거나 최종 답변을 생성합니다.
  5. 모델이 도구를 더 이상 요청하지 않을 때까지 반복합니다.

모델은 결코 스스로 무언가를 실행하지 않습니다. 호출을 제안할 뿐이며, 실제로 무엇이 실행되는지는 당신의 Delphi 코드가 통제합니다. 그것이 바로 이 패턴을 실제 시스템 앞에 두어도 안전하게 만드는 점입니다.

경로 1: 제공자 함수 호출

단일 모델에 당신의 코드에 대한 접근을 부여하는 가장 직접적인 방법은 제공자 자체의 함수 호출 API입니다. 사용 가능한 함수를 선언하면, 모델이 필요할 때 하나를 고르고, 당신의 컴포넌트에서 이벤트가 발생해 결과를 공급할 수 있습니다. OpenAI 컴포넌트에서는 도구를 어시스턴트에 한 번 정의한 다음, 호출을 처리합니다.

Assistant := TsgcAIOpenAIAssistant.Create(nil);
Assistant.OpenAIOptions.ApiKey := 'sk-...';
Assistant.AssistantOptions.Name := 'Delphi Weather Bot';
Assistant.AssistantOptions.Instructions.Text :=
  'You are a weather bot. Use the provided functions to answer questions.';
Assistant.AssistantOptions.Model := 'gpt-4o';

// Describe the callable functions as JSON tool definitions
Assistant.AssistantOptions.Tools.Functions.Functions.Text :=
  '[{"type":"function","function":{"name":"get_current_temperature",' +
  '"description":"Get the current temperature for a specific location",' +
  '"parameters":{"type":"object","properties":{"location":{"type":"string"}},' +
  '"required":["location"]}}}]';

모델이 값이 필요하다고 결정하면, 컴포넌트는 OnFunctionCall을 발생시킵니다. aRequest._Function._Name을 검사해 어떤 도구가 요청되었는지 알아내고, 답을 aResponse.Output에 기록합니다 — 그 결과는 곧바로 모델로 다시 전달되어 모델이 응답을 완성할 수 있습니다.

procedure TForm1.AssistantFunctionCall(Sender: TObject;
  const aRequest: TsgcOpenAIClass_ToolCall;
  const aResponse: TsgcHTTPOpenAI_ToolCall_Response);
begin
  if aRequest._Function._Name = 'get_current_temperature' then
    aResponse.Output := 30
  else if aRequest._Function._Name = 'get_rain_probability' then
    aResponse.Output := 10;
end;

그 이벤트 핸들러가 바로 에이전트 루프입니다. 모델이 도구를 요청할 때마다 당신은 그것을 실행하고 반환하며, 컴포넌트는 모델이 필요한 모든 것을 가질 때까지 대화를 이어갑니다. 이 경로는 에이전트가 당신 자신의 애플리케이션 안에 살면서 하나의 제공자와 대화할 때 이상적입니다. 같은 형태가 Anthropic과 Gemini 컴포넌트에서도 제공되므로, 종속될 일은 없습니다. 전체 예제는 OpenAI 함수 호출 따라하기를 보세요.

경로 2: MCP 도구

함수 호출은 당신의 도구를 하나의 앱 안 하나의 모델에 묶습니다. Model Context Protocol은 같은 아이디어를 재사용 가능한 서비스로 바꿉니다. 당신의 애플리케이션이 표준 JSON-RPC 엔드포인트로 일련의 도구를 노출하면, MCP를 지원하는 어떤 클라이언트나 에이전트든 — IDE 어시스턴트, 데스크톱 AI 앱, 또는 당신 자신의 에이전트 루프든 — 연결해 그 도구를 발견하고 호출할 수 있습니다. 도구를 한 번 작성하면 모든 MCP 호스트가 사용할 수 있습니다.

sgcWebSockets에서 서버 측은 TsgcWSAPIServer_MCP입니다. 이를 sgcWebSockets HTTP 서버에 연결하고, Tools.AddTool로 도구를 등록하고, 들어오는 호출을 OnMCPRequestTool에서 처리합니다.

uses
  sgcWebSocket_Server, sgcAI, sgcAI_MCP_Classes, sgcAI_MCP_Server;

procedure TForm1.SetupMCPServer;
begin
  MCPServer.Server := Server;
  MCPServer.EndpointOptions.Endpoint := '/mcp';
  MCPServer.MCPOptions.ServerInfo.Name    := 'sgc-mcp-server';
  MCPServer.MCPOptions.ServerInfo.Version := '1.0.0';

  // Register a callable tool with a typed argument
  with MCPServer.Tools.AddTool('GetTemperature',
    'Get the actual temperature in a city.') do
    InputSchema.Properties.AddProperty('city', True);

  MCPServer.OnMCPRequestTool := MCPRequestTool;
  Server.Port   := 8080;
  Server.Active := True;
end;

연결된 클라이언트가 도구를 호출하면, 강타입 요청 및 응답 객체와 함께 이벤트가 발생합니다. 도구 이름은 aRequest.Params.Name에서, 인자는 aRequest.Params.Arguments에서 읽은 다음, 답을 aResponse.Result.Content.AddText로 기록합니다.

procedure TForm1.MCPRequestTool(Sender: TObject;
  const aSession: TsgcAI_MCP_Session;
  const aRequest: TsgcAI_MCP_Request_ToolsCall;
  const aResponse: TsgcAI_MCP_Response_ToolsCall);
begin
  if aRequest.Params.Name = 'GetTemperature' then
    aResponse.Result.Content.AddText('The current temperature in ' +
      aRequest.Params.Arguments.Item[0].Value + ' is 22 Celsius');
end;

이 핸들러는 함수 호출 이벤트와 같은 일을 하지만, 이제 도구는 네트워크를 통해 어떤 MCP 호스트든 도달할 수 있습니다. MCP는 공개된 표준이므로, 대화를 이끄는 에이전트를 당신이 직접 작성할 필요가 전혀 없습니다. 자세한 내용은 MCP 개요MCP Server 컴포넌트 페이지를 읽어보세요.

어떤 경로를 써야 할까요?

원하는 것이…사용컴포넌트
당신 자신의 앱 안에 살면서 하나의 제공자와 대화하는 에이전트제공자 함수 호출TsgcAIOpenAIAssistant
MCP를 지원하는 어떤 클라이언트나 에이전트든 발견하고 호출할 수 있는 도구MCP 서버TsgcWSAPIServer_MCP
다른 사람의 MCP 서버가 호스팅하는 도구를 호출하기MCP 클라이언트TsgcWSAPIClient_MCP

이 둘은 상호 배타적이지 않습니다. 흔한 설계는 앱 내부 에이전트가 자체의 비공개 도구에는 제공자 함수 호출을 사용하면서, 동시에 MCP 클라이언트로서 조직 어딘가의 공유 도구 서버에 연결하는 것입니다. 어느 쪽을 선택하든 당신이 작성하는 루프는 거의 동일하므로, 나중에 둘 사이를 오가는 비용은 저렴합니다.

시작하기

두 경로 모두 sgcWebSockets에 포함되어 있습니다(MCP 서버와 클라이언트는 Enterprise 컴포넌트입니다). 무료 평가판을 받아서, 함수 호출에는 TsgcAIOpenAIAssistant를, MCP 서비스에는 TsgcWSAPIServer_MCP를 놓고, 도구 이벤트를 연결하면, 몇 줄로 당신 자신의 코드에 따라 행동할 수 있는 에이전트를 갖게 됩니다. 모든 AI 빌딩 블록은 AI & LLM 컴포넌트 허브에서 둘러보세요.

질문이 있거나 에이전트 설계에 도움이 필요하신가요? 문의하기 — 코드를 작성한 사람들로부터 답변을 받게 됩니다.

관련 글