跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言AI

Delphi 程序与 AI 大模型交互实践

演示了如何使用 Delphi 构建 WebService 服务器,并通过 AI 大模型生成 SOAP 请求 XML 来调用本地函数。通过拦截客户端通信、分析 WSDL 以及验证 AI 生成的 XML 有效性,证明了 AI 可以作为 Agent 理解并执行本地代码逻辑。最终实现了 AI 自动发送请求并解析返回结果的技术闭环,为 Delphi 开发 AI Agent 提供了可行方案。

GRACE Grace发布于 2026/4/5更新于 2026/9/1077 浏览

使用 Delphi 写 AI 大模型的 Agent

简单的概念解释

所谓的 Agent 是运行在本地电脑上的一个程序。这个程序可以让大模型来调用,在本地电脑上执行一些代码,然后把代码执行结果给大模型,并且大模型还能够理解代码的执行结果。

如何实现的思考

AI 大模型的输入和输出都是字符串。在聊天方式下,人脑当然可以阅读理解 AI 输出的内容。如果我们使用 Delphi 来写程序,如何知道 AI 想要调用哪个函数?如何让 Delphi 程序去执行这个函数?

Delphi 内置的 WebService 框架

WebService 的底层是 SOAP 调用,而 SOAP 调用的底层通讯是 XML 字符串!

尝试

首先,用 Delphi 创建一个 WebService 服务器端程序用于测试。

构造一个 WebService 服务器端程序

我使用 Delphi 创建了一个 WebService 服务器端程序,它输出给客户端调用的接口定义代码:

type TMyArrayInt = Array Of Integer; { Invokable interfaces must derive from IInvokable }
IIMyTest = interface(IInvokable) ['{10981E31-3C5C-4611-BB68-5964025D690F}'] { Methods of Invokable interface must not use the default } { calling convention; stdcall is recommended }
function Hello(const S: string): string; stdcall;
procedure HelloWord(const S: string; var MyResult: string); stdcall;
function TestArray(A: TIntegerSOAPArray ): TIntegerSOAPArray ; stdcall;
function XPlusY(const X, Y: Integer): Integer; stdcall;
end;

这里,我们聚焦到 function XPlusY(const X, Y: Integer): Integer; stdcall; 上,它的实现代码是:

function TIMyTest.XPlusY(const X, Y: Integer): Integer;
begin
  Result := X + Y;
end;
WebService 验证客户端

同样,使用 Delphi 创建一个标准的 WebService 客户端程序,去调用服务器的 XPlusY 函数,代码如下:

procedure TFmMain.Button3Click(Sender: TObject);
var Intf: IIMyTest; X, Y, Z: Integer;
begin
  Intf := HTTPRIO1 as IIMyTest;
  X := 10;
  Y := 33;
  Z := Intf.XPlusY(X, Y);
  ShowMessage(Z.ToString);
end;

运行服务器端程序和客户端程序,客户端程序上的 Button3 点击后,确实收到服务器端的返回,弹出消息框显示43,成功。

获得 Delphi 的 WebService 客户端程序向服务器发起函数调用的通讯内容

因为客户端是使用 HTTPRIO1 这个控件去调用服务器端,因此,我们在 HTTPRIO1.OnBeforeExecute 事件里面写代码拦截,代码如下:

procedure TFmMain.HTTPRIO1BeforeExecute(const MethodName: string; SOAPRequest: TStream);
var S: TStringStream; SS: string;
begin
  S := TStringStream.Create;
  try
    SoapRequest.Position := 0;
    S.CopyFrom(SoapRequest);
    S.Position := 0;
    SS := S.ReadString(S.Size);
    Log(SS);
  finally
    S.Free;
  end;
end;

上述代码中,Log 方法的代码如下:

procedure TFmMain.Log(const S: string);
begin
  TThread.Synchronize(nil, procedure begin Memo1.Lines.Add(S); end );
end;

也就是说,把 HTTPRIO1 向服务器发送的函数调用的请求内容,写到 Memo1 里面,让我可以看见。 接下来再次使用这个客户端程序,执行一次对服务器端 XPlusY 函数的调用,HTTPRIO1 发送的内容如下:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body xmlns:NS1="urn:IMyTestIntf-IIMyTest" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><NS1:XPlusY><X xsi:type="xsd:int">10</X><Y xsi:type="xsd:int">33</Y></NS1:XPlusY></SOAP-ENV:Body></SOAP-ENV:Envelope>
使用 HTTP Post 直接发送这个 XML 的内容给服务器

创建一个新的 Delphi 程序,在里面放三个控件:

  • Button1;
  • Memo1;
  • IdHTTP1

IdHTTP1 用于向服务器发起 http 访问。对于 SOAP 来说,这里应该发起 http 的 Post 而不是 http 的 Get。

把上面我们从 WebService 客户端程序抓到的 XML 保存为文件,文件名:XML_1.txt,然后使用 IdHTTP1 把它 Post 给 WebService 服务器端,代码如下:

procedure TFmMain.Button1Click(Sender: TObject);
var S, URL: string;
begin
  Memo1.Lines.Clear;
  URL := 'http://localhost:8080/soap/IIMyTest';
  S := IdHTTP1.Post(URL,'XML_2.txt'); //成功
  Memo1.Lines.Add(S);
end;

运行这个程序,点击 Button1,能够从 Memo1 上看到来自 WebService 服务器的返回。返回数据是:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:IMyTestIntf-IIMyTest"><NS1:XPlusYResponse><return xsi:type="xsd:int">43</return></NS1:XPlusYResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

上面这段 XML 表明,服务器正确执行了 XPlusY 函数,返回了 43 这个正确的结果。

AI 怎么玩?

这里作为测试,我使用了 DeepSeek 的网页版本。我通过聊天的方式,告诉 DeepSeek:

你是一个能够理解 SOAP 调用的专家,我给你一个 SOAP 服务器的调用规范,你能够理解并创建客户端调用这个 SOAP 服务器的 XML 代码吗? 

AI 回答:

当然可以!我是理解 SOAP 协议和 XML 结构的专家,您只需提供 SOAP 服务的调用规范(例如 WSDL 地址、操作名称、命名空间、请求参数等),我就能为您生成对应的客户端调用 XML 代码。请提供详细信息,我会尽力帮您构建正确的 SOAP 请求。

然后我把服务器的 WSDL 在聊天页面里面发送给 AI,WSDL 如下:

# 理解并调用 WebService
## 以下是指定的 WebService 服务器端能够提供的服务的 WSDL:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns1="http://www.borland.com/namespaces/Types" name="IIMyTestservice" targetNamespace="http://tempuri.org/">
 <types>
  <xs:schema xmlns="http://www.borland.com/namespaces/Types" targetNamespace="http://www.borland.com/namespaces/Types">
   <xs:complexType name="TIntegerSOAPArray">
    <xs:complexContent>
     <xs:restriction base="soapenc:Array">
      <sequence xmlns="http://www.w3.org/2001/XMLSchema"/>
      <xs:attribute xmlns:n1="http://schemas.xmlsoap.org/wsdl/" ref="soapenc:arrayType" n1:arrayType="xs:int[]"/>
     </xs:restriction>
    </xs:complexContent>
   </xs:complexType>
  </xs:schema>
 </types>
 <message name="Hello0Request">
  <part name="S" type="xs:string"/>
 </message>
 <message name="Hello0Response">
  <part name="return" type="xs:string"/>
 </message>
 <message name="HelloWord1Request">
  <part name="S" type="xs:string"/>
  <part name="MyResult" type="xs:string"/>
 </message>
 <message name="HelloWord1Response">
  <part name="MyResult" type="xs:string"/>
 </message>
 <message name="TestArray2Request">
  <part name="A" type="ns1:TIntegerSOAPArray"/>
 </message>
 <message name="TestArray2Response">
  <part name="return" type="ns1:TIntegerSOAPArray"/>
 </message>
 <message name="XPlusY3Request">
  <part name="X" type="xs:int"/>
  <part name="Y" type="xs:int"/>
 </message>
 <message name="XPlusY3Response">
  <part name="return" type="xs:int"/>
 </message>
 <portType name="IIMyTest">
  <operation name="Hello">
   <input message="tns:Hello0Request"/>
   <output message="tns:Hello0Response"/>
  </operation>
  <operation name="HelloWord">
   <input message="tns:HelloWord1Request"/>
   <output message="tns:HelloWord1Response"/>
  </operation>
  <operation name="TestArray">
   <input message="tns:TestArray2Request"/>
   <output message="tns:TestArray2Response"/>
  </operation>
  <operation name="XPlusY">
   <input message="tns:XPlusY3Request"/>
   <output message="tns:XPlusY3Response"/>
  </operation>
 </portType>
 <binding name="IIMyTestbinding" type="tns:IIMyTest">
  <binding xmlns="http://schemas.xmlsoap.org/wsdl/soap/" transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="Hello">
   <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="urn:IMyTestIntf-IIMyTest#Hello"/>
   <input>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </input>
   <output>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </output>
  </operation>
  <operation name="HelloWord">
   <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="urn:IMyTestIntf-IIMyTest#HelloWord"/>
   <input>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </input>
   <output>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </output>
  </operation>
  <operation name="TestArray">
   <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="urn:IMyTestIntf-IIMyTest#TestArray"/>
   <input>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </input>
   <output>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </output>
  </operation>
  <operation name="XPlusY">
   <operation xmlns="http://schemas.xmlsoap.org/wsdl/soap/" soapAction="urn:IMyTestIntf-IIMyTest#XPlusY"/>
   <input>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </input>
   <output>
    <body xmlns="http://schemas.xmlsoap.org/wsdl/soap/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:IMyTestIntf-IIMyTest"/>
   </output>
  </operation>
 </binding>
 <service name="IIMyTestservice">
  <port name="IIMyTestPort" binding="tns:IIMyTestbinding">
   <address xmlns="http://schemas.xmlsoap.org/wsdl/soap/" location="http://localhost:8080/soap/IIMyTest"/>
  </port>
 </service>
</definitions>

请详细分析上述 WSDL,仔细思考,给出这个 WebService 服务器提供了多少个函数,给出一个函数列表,包括每个函数的参数。

AI 回答如下:根据提供的 WSDL 文件分析,该 WebService 服务器提供了 4 个函数,每个函数对应一个操作(operation)。以下是详细的函数列表及参数说明:

  1. Hello 描述:简单的问候函数,接收一个字符串并返回一个字符串。输入参数:S (string):输入的字符串。输出参数:return (string):返回的字符串。
  2. HelloWord 描述:接收两个字符串参数,并返回一个字符串(注意:输入参数中包含 MyResult,与输出参数同名,但属于不同的消息部分)。输入参数:S (string):第一个输入字符串。MyResult (string):第二个输入字符串。输出参数:MyResult (string):返回的字符串。
  3. TestArray 描述:接收一个整数数组,并返回一个整数数组。输入参数:A (TIntegerSOAPArray):整数数组,类型为自定义的 SOAP 数组。输出参数:return (TIntegerSOAPArray):整数数组。
  4. XPlusY 描述:接收两个整数,返回它们的和。输入参数:X (int):第一个整数。Y (int):第二个整数。输出参数:return (int):两数之和。 补充说明:所有操作均采用 RPC 编码风格(style="rpc"),并使用 SOAP 1.1 编码(encodingStyle="http://schemas.xmlsoap.org/soap/encoding/")。服务地址为:http://localhost:8080/soap/IIMyTest(需根据实际部署修改)。SOAP Action 格式为:urn:IMyTestIntf-IIMyTest#操作名,例如 Hello 的 SOAP Action 为 urn:IMyTestIntf-IIMyTest#Hello。消息体使用的命名空间为:urn:IMyTestIntf-IIMyTest。如果需要生成具体的 SOAP 请求 XML 示例,请告知要调用的函数及参数值。

我在网页聊天窗口继续输入:

# 调用 XPlusY 函数
现在你需要作为一个 WebService 客户端,调用服务器提供的 XPlusY 函数,你必须生成调用 XPlusY 函数的完整的符合 SOAP 协议的 XML 给服务器端。
调用 XPlusY 函数的两个参数分别是:X=12; Y=22;
请深入思考后输出符合规范的 XML

AI 输出作为 WebService 客户端调用服务器端函数的 XML 如下:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <soap:Body>
  <XPlusY xmlns="urn:IMyTestIntf-IIMyTest">
   <X xsi:type="xsd:int">12</X>
   <Y xsi:type="xsd:int">22</Y>
  </XPlusY>
 </soap:Body>
</soap:Envelope>

上述 XML 看起来和 Delphi 的客户端调用服务器端函数的 XML 有点不一样,但主要内容是相同的。我使用这个 XML 能不能成功调用 Delphi 写的 WebService 服务器端程序呢?把上述 XML 保存为 XML_0.TXT 然后用 IdHTTP1 去 POST 给服务器端程序,然后看到成功的返回内容,看起来服务器端正确理解了这个 XML 并执行了 XPlusY 这个函数。服务器返回的 XML 如下:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS1="urn:IMyTestIntf-IIMyTest"><NS1:XPlusYResponse><return xsi:type="xsd:int">34</return></NS1:XPlusYResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

那么,我的服务器端程序返回的 XML,AI 能不能正确理解呢?我把服务器返回的 XML 复制粘贴到 AI 的聊天框里面,输出 Delphi 写的服务器程序的返回值给 AI,

AI 的回答是:从 SOAP 调用的角度来看,服务器返回的 XML 是一个标准的 SOAP 1.1 响应,表明对 XPlusY 函数的调用已成功执行,并返回了计算结果。以下是详细解释:

  1. 响应整体结构
  2. 关键元素和属性解释
  3. 与请求的对应关系
  4. 结论

该响应表明:调用成功(无 SOAP Fault)。返回值为 34,验证了 XPlusY 函数的正确性。服务器遵循了 WSDL 定义的绑定,使用了 RPC/encoded 风格,并正确序列化了返回数据。因此,您的客户端调用已成功执行,并得到了预期的结果。

结论

经过上述测试,发现 DeepSeek 确实可以在明确要求 SOAP 调用的指示下,自己创建 SOAP 调用的 XML,并且能成功让 WebService 服务器程序执行相关的函数,也能正确理解函数执行的返回结果。

虽然 AI 和 WebService 服务器程序的通讯,是我在中间人工中转的,但验证了 AI 可以调用 WebService 程序。

如果我写一个程序,直接使用 AI 的 API 接口,我的程序就可以自动将 WebService 的 WSDL 发送给 AI,然后自动接收 AI 传过来的 XML,然后我的程序可以把这个 XML 发送给服务器,达到调用服务器的函数或者方法的目的,并且可以把函数调用结果返回给 AI,AI 也能正确理解返回结果,因此 AI 也可以决定接下来可以做什么。这样一来,技术上,我就可以使用 Delphi 来实现一个 AI agent 了。

目录

  1. 使用 Delphi 写 AI 大模型的 Agent
  2. 简单的概念解释
  3. 如何实现的思考
  4. Delphi 内置的 WebService 框架
  5. 尝试
  6. 构造一个 WebService 服务器端程序
  7. WebService 验证客户端
  8. 获得 Delphi 的 WebService 客户端程序向服务器发起函数调用的通讯内容
  9. 使用 HTTP Post 直接发送这个 XML 的内容给服务器
  10. AI 怎么玩?
  11. 理解并调用 WebService
  12. 以下是指定的 WebService 服务器端能够提供的服务的 WSDL:
  13. 调用 XPlusY 函数
  14. 结论

更多推荐文章

查看全部
  • 大语言模型 (LLM) 基础:原理、应用与挑战
  • 多模态大模型主流架构与技术要点总结
  • macOS Sequoia 与 Tahoe 功能性能对比及升级教程
  • C++ 红黑树插入与平衡调整详解
  • Python 3.14.2 Windows 安装指南
  • 2026 年前端跨端框架选型指南:Flutter、RN 与 uni-app 深度对比
  • 基于大模型的 Web UI 自动化方案对比与选型
  • 自然语言处理(NLP)在法律领域的应用与实战
  • AI 核心概念速通教程
  • 主流大模型降英文 AI 检测率横向测评:千问、DeepSeek、KIMI 等对比
  • Android WebView 内核升级方案详解
  • 字节跳动前端一面面试真题与深度解析
  • Flutter pathfinding 库的 OpenHarmony 适配实战
  • Linux 线程控制详解:POSIX 线程库与多线程编程实践
  • Windows 环境 AI 绘画工具网络代理冲突及 JSON 报错解决
  • MusePublic Art Studio 镜像部署:免配置运行 SDXL 绘画
  • 贪心算法实战:柠檬水找零、数组减半与最大数拼接
  • 机器人灵巧手:技术演进、市场格局与未来前景
  • 基于 Python + Django 的大学生自习室预约系统
  • 昇腾 910B 部署 Llama-2-7b 深度测评与实战指南

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online