使用AI服务中枢的对话框
本节内容可以参考文件"CaseStudy\LLMCaller.foxdb"的窗口"使用AI服务中枢的对话框"。
本节的对话框访问的是上一节设计的AI服务中枢,所以运行本节示例之前,请先打开上一节的示例文件AIServer.foxdb。
1、窗口的AfterLoad事件代码:
'''Async
1、读取存储在本地的上下文
Vars("localMessages")
=
New
JArray()
'
用于本地保存历史对话
If
FileSys.FileExists(ProjectPath &
"aiMessages.txt")
Then
Dim
msgstr
As
String
= FileSys.ReadAllText(ProjectPath &
"aiMessages.txt")
Vars("localMessages")
= JsonConvert.DeserializeObject(msgstr)
End
If
' 2.
初始化
WebViewer
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Await
wv.EnsureCoreWebView2Async(Nothing)
' 后面的代码完全相同......
2、发送按钮的代码:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
inputBox
As
WinForm.TextBox = e.Form.Controls("TextBox1")
Dim
userMsg
As
String
= inputBox.Text.Trim()
If
userMsg =
""
Then
Return
inputBox.Text =
""
' ---- 1.
显示用户消息
----
Dim
userMsgEncoded
As
String
= HTMLEncode(userMsg).Replace(vbCrLf,
"<br>").Replace(vbLf,
"<br>")
Await
wv.ExecuteScriptAsync("addMessage('user',
"
& JsonConvert.ToString(userMsgEncoded) &
")")
Await
wv.ExecuteScriptAsync("addTempMessage('⏳
服务中枢正在思考...')")
' ---- 2.
构造并发送请求到
AIServer ----
Dim
reqObj
As
New
JObject()
reqObj("user_id")
=
"EMP_1001"
'
假定当前登录员工工号
reqObj("question")
= userMsg
Dim
localMessages
As
JArray = Vars("localMessages")
If
localMessages
IsNot
Nothing
AndAlso
localMessages.Count > 0
Then
reqObj("messages")
= localMessages
End
If
Dim
hc
As
New
HttpClient("http://127.0.0.1:18688/ask")
hc.SkipError =
True
hc.ContentType =
"application/json"
hc.Content = reqObj.ToString()
'
因为是跨进程请求,等待时间可能稍长,这期间界面不会卡死
Dim
res
As
String
=
Await
hc.GetDataAsync()
Await
wv.ExecuteScriptAsync("removeTempMessage()")
' ---- 3.
处理返回结果
----
If
hc.StatusCode = 200
Then
Dim
respObj
As
JObject = JsonConvert.DeserializeObject(res)
If
respObj("success").ToObject(Of
Boolean)()
Then
'
将服务端合并后的最新
messages
保存在本地,供下一轮使用
Vars("localMessages")
= respObj("messages")
Dim
answer
As
String
= respObj("answer").ToString()
Dim
think
As
String
= respObj("think").ToString()
think = HtmlEncode(think).Replace(vbCrLf,
"<br>").Replace(vbLf,
"<br>")
Await
wv.ExecuteScriptAsync("addMessage('assistant',
'')")
Await
wv.ExecuteScriptAsync("appendThink("
& JsonConvert.ToString(think) &
")")
Await
wv.ExecuteScriptAsync("appendAnswer("
& JsonConvert.ToString(answer) &
")")
Else
Dim
err
As
String
= respObj("error").ToString()
Await
wv.ExecuteScriptAsync("addMessage('assistant',
"
& JsonConvert.ToString("服务端报错:"
& err) &
")")
End
If
Else
Await
wv.ExecuteScriptAsync("addMessage('assistant',
'无法连接到
AI
服务中枢,请检查内网。')")
End
If
打开这个AI对话框,依次提问:
“2025年的销冠是哪个员工", "2026年呢", "向狐狸爸爸问好", "从北京天安门到故宫的步行路线?"
可以看到这个对话框已经具备了各种能力,但它只负责输入问题,然后得到答案,不会泄露任何重要信息,例如APIKey、MCP地址、工具定义和执行细节等等。
这个AI对话框唯一的不足是没有实现打字效果,未来的版本或许会改进,但作为服务中枢,一般不应该开始SSE流,因为会加重负载。