Delphi程序和AI大模型交互

使用 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. 响应整体结构
    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
34
</NS1:XPlusYResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
2. 关键元素和属性解释
SOAP-ENV:Envelope:根元素,声明了 SOAP 必需的命名空间:

xmlns:SOAP-ENV=“http://schemas.xmlsoap.org/soap/envelope/”:SOAP 信封命名空间。

xmlns:xsd 和 xmlns:xsi:XML Schema 命名空间,用于数据类型声明。

xmlns:SOAP-ENC=“http://schemas.xmlsoap.org/soap/encoding/”:SOAP 编码命名空间,表示使用了 SOAP 1.1 编码规则。

SOAP-ENV:Body:消息体,包含实际的响应内容。

SOAP-ENV:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”:明确指定了消息体采用 SOAP 编码风格,与 WSDL 中定义的 use=“encoded” 一致。

xmlns:NS1=“urn:IMyTestIntf-IIMyTest”:在 Body 上声明了命名空间前缀 NS1,其值为操作的命名空间 urn:IMyTestIntf-IIMyTest。

NS1:XPlusYResponse:响应元素,命名空间前缀 NS1 指向 urn:IMyTestIntf-IIMyTest,元素名 XPlusYResponse 遵循 RPC 响应的命名惯例(方法名 + “Response”)。它包含一个子元素 return。

return:输出参数元素,表示函数的返回值。

xsi:type=“xsd:int”:通过 xsi:type 显式声明了数据类型为整数(xsd:int),符合 SOAP 编码规范中对数据类型的描述。

元素内容为 34,即计算结果(12 + 22 = 34)。

  1. 与请求的对应关系
    请求中我们发送了 XPlusY 操作,参数 X=12 和 Y=22。

服务器正确处理了请求,计算两数之和,并将结果包装在标准响应结构中返回。

响应中的命名空间和编码风格与请求完全匹配,体现了 RPC/encoded 模式的服务交互。

  1. 结论
    该响应表明:

调用 成功(无 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 了。

Read more

华为OD机试双机位C卷真题:自动化维修流水线(C/C++/Java/Python/Go/JS)

华为OD机试双机位C卷真题:自动化维修流水线(C/C++/Java/Python/Go/JS)

自动化维修流水线 华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型 华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解 题目描述 小伙伴反馈题目大意:给定m条流水线,流水线可并行处理维修任务,给出n个任务,并给出每个任务的执行时间,要求完成所有任务的最短时间。 输入描述 第一行输入 任务数n和流水线数量m,用空格分割 第二行输入 每个任务完成所用时间 输出描述 输出最短执行完成所有任务数量 用例1 输入 10 1 10 20 30 5 5 5 5 10 5 10 输出 105 题解 思路:二分 + 递归回溯

By Ne0inhk

2026年人工智能发展趋势:效率重构、生态协同与规范前行

进入2026年,人工智能产业告别了对参数规模的盲目追逐,迈入“技术提质、产业落地、治理完善”的三重迭代期。技术层面,大模型向高效化演进、小模型实现场景突围,智能体能力持续升级;产业层面,AI与实体经济深度融合,从辅助工具向核心生产力转变;治理层面,全球监管规则加速落地,安全与合规成为行业发展的前置条件。本文结合真实案例与权威数据,拆解2026年人工智能的核心发展趋势,呈现技术变革与产业实践的真实图景。 趋势一:范式转移,小模型崛起重构AI效率格局 2026年成为小模型发展的分水岭,AI行业从“规模崇拜”转向“效率优先”,核心驱动力源于大模型边际效益递减与能源成本高企的双重压力。国际能源署测算,2026年AI相关电力消耗将相当于日本全国用电量,粗放式的参数扩张模式已难以为继,而“密度定律”的普及推动行业转向精细化运营——通过技术优化让模型更“小”且能力更强,小模型不再是大模型的简化版,而是针对特定场景的高效解决方案。 小模型的突破集中在特定任务性能、成本控制与端侧部署三大维度。性能上,小模型在垂直领域已实现对前沿大模型的超越:微博自研的VibeThinker模型仅15亿参数,却在

By Ne0inhk
AI评估建议可信度:破解决策迷局

AI评估建议可信度:破解决策迷局

demo:更新决策数学模型的版本https://www.coze.cn/s/yCV7zGc-F6A/ #人的一生处处在决策,决策的好坏决定结果有没有遗憾,有的人寻求外在建议综合决策,而无法判断建议是否可靠,因此,提出Cognitive Trustworthiness Evaluator, CTE,这是一个极具潜力且前沿的交叉领域项目——将认知科学、行为经济学、概率推理与人工智能结合,构建一个基于认知偏差建模的建议可信度评估智能体(Cognitive Trustworthiness Evaluator, CTE) 一、项目目标 构建一个智能体(Agent),通过分析用户在表达观点、提出建议时所体现出的认知特征(尤其是与概率感、事后归因、幸存者偏差、反事实思维等相关的模式),对其认知可靠性进行量化评分,并据此判断其建议是否值得采纳。 核心假设:一个人对不确定性的理解能力(即“概率感”)及其对因果关系的误判倾向,是其建议质量的重要预测指标。 二、理论基础与关键维度 我们聚焦以下五个核心认知维度,每个维度均有心理学/行为经济学实证支持: 表格 维度定义行为表现可观测信

By Ne0inhk