在 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 & LLM 组件中心浏览每一个 AI 构建模块。

有疑问,或想要帮你设计智能体?联系我们 — 你会收到来自代码编写者本人的回复。

相关内容