Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
Ftt_Common
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Ftt_Common
Commits
0fff0a7b
Commit
0fff0a7b
authored
Aug 27, 2026
by
段廷瑞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pref: 智能体模型选择与交互优化
parent
a3a8c203
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
272 additions
and
24 deletions
+272
-24
OpenAiCompatibleClient.cs
Tools/MyAgent/Agent/OpenAiCompatibleClient.cs
+68
-4
AgentConfig.cs
Tools/MyAgent/Config/AgentConfig.cs
+3
-0
AgentSettingsForm.Designer.cs
Tools/MyAgent/Forms/AgentSettingsForm.Designer.cs
+14
-1
AgentSettingsForm.cs
Tools/MyAgent/Forms/AgentSettingsForm.cs
+186
-19
wMyAgent.cs
Tools/MyAgent/wMyAgent.cs
+1
-0
No files found.
Tools/MyAgent/Agent/OpenAiCompatibleClient.cs
View file @
0fff0a7b
...
...
@@ -48,6 +48,61 @@ namespace Tools.MyAgent.Agent
public
double
Temperature
{
get
;
set
;
}
=
0.3
;
public
int
MaxTokens
{
get
;
set
;
}
=
8192
;
/// <summary>获取当前兼容接口公开的模型列表(不影响聊天请求)</summary>
public
async
Task
<(
bool
Ok
,
string
Message
,
List
<
string
>
Models
)>
FetchModelsAsync
(
CancellationToken
ct
)
{
try
{
using
(
var
cts
=
CancellationTokenSource
.
CreateLinkedTokenSource
(
ct
))
{
cts
.
CancelAfter
(
15000
);
string
baseUrl
=
BaseUrl
?.
Trim
().
TrimEnd
(
'/'
);
if
(
string
.
IsNullOrEmpty
(
baseUrl
))
return
(
false
,
"BaseUrl 不能为空"
,
null
);
string
modelsUrl
=
baseUrl
.
EndsWith
(
"/v1"
,
StringComparison
.
OrdinalIgnoreCase
)
?
baseUrl
+
"/models"
:
baseUrl
+
"/v1/models"
;
using
(
var
req
=
new
HttpRequestMessage
(
HttpMethod
.
Get
,
modelsUrl
))
{
if
(!
string
.
IsNullOrWhiteSpace
(
ApiKey
))
req
.
Headers
.
TryAddWithoutValidation
(
"Authorization"
,
"Bearer "
+
ApiKey
);
using
(
var
resp
=
await
Http
.
SendAsync
(
req
,
cts
.
Token
).
ConfigureAwait
(
false
))
{
string
json
=
await
resp
.
Content
.
ReadAsStringAsync
().
ConfigureAwait
(
false
);
if
(!
resp
.
IsSuccessStatusCode
)
return
(
false
,
$"HTTP
{(
int
)
resp
.
StatusCode
}
:
{
TruncateModelResponse
(
json
,
200
)}
"
,
null
);
var
obj
=
JObject
.
Parse
(
json
);
var
data
=
obj
[
"data"
]
as
JArray
;
var
models
=
data
==
null
?
new
List
<
string
>()
:
data
.
OfType
<
JObject
>()
.
Select
(
x
=>
x
[
"id"
]?.
Value
<
string
>())
.
Where
(
x
=>
!
string
.
IsNullOrWhiteSpace
(
x
))
.
Distinct
(
StringComparer
.
OrdinalIgnoreCase
)
.
OrderBy
(
x
=>
x
,
StringComparer
.
OrdinalIgnoreCase
)
.
ToList
();
return
models
.
Count
==
0
?
(
false
,
"接口未返回可用模型"
,
null
)
:
(
true
,
$"获取到
{
models
.
Count
}
个模型"
,
models
);
}
}
}
}
catch
(
OperationCanceledException
)
{
return
(
false
,
"获取模型列表超时,请检查网络与 BaseUrl。"
,
null
);
}
catch
(
Exception
ex
)
{
return
(
false
,
ex
.
Message
,
null
);
}
}
private
static
string
TruncateModelResponse
(
string
text
,
int
max
)
{
if
(
string
.
IsNullOrEmpty
(
text
))
return
""
;
return
text
.
Length
<=
max
?
text
:
text
.
Substring
(
0
,
max
)
+
"…"
;
}
/// <summary>是否使用系统代理(默认 true;公司内网常用)。
/// 优先读取 HTTPS_PROXY / HTTP_PROXY 环境变量,否则用系统 IE 代理设置。
/// 修复:原实现属性为死字段(handler 在构造时绑定,开关从不生效);
...
...
@@ -321,10 +376,9 @@ namespace Tools.MyAgent.Agent
return
messages
.
Count
>
1
;
}
/// <summary>发送一次请求并读取 SSE 流;非成功状态码抛 HttpRequestException(附 Data["HttpStatusCode"])</summary>
private
async
Task
<
ChatResult
>
SendOnceAsync
(
JObject
body
,
CancellationToken
ct
)
{
var
req
=
new
HttpRequestMessage
(
HttpMethod
.
Post
,
BaseUrl
.
TrimEnd
(
'/'
)
+
"/chat/completions"
);
var
req
=
new
HttpRequestMessage
(
HttpMethod
.
Post
,
ResolveChatEndpoint
(
BaseUrl
)
);
req
.
Headers
.
TryAddWithoutValidation
(
"Authorization"
,
"Bearer "
+
ApiKey
);
req
.
Content
=
new
StringContent
(
body
.
ToString
(
Formatting
.
None
),
Encoding
.
UTF8
,
"application/json"
);
...
...
@@ -372,7 +426,15 @@ namespace Tools.MyAgent.Agent
}
}
/// <summary>连接测试:发送最小补全请求,返回(是否成功,信息)</summary>
private
static
string
ResolveChatEndpoint
(
string
baseUrl
)
{
string
value
=
(
baseUrl
??
""
).
Trim
().
TrimEnd
(
'/'
);
if
(
value
.
EndsWith
(
"/chat/completions"
,
StringComparison
.
OrdinalIgnoreCase
))
return
value
;
return
value
.
EndsWith
(
"/v1"
,
StringComparison
.
OrdinalIgnoreCase
)
?
value
+
"/chat/completions"
:
value
+
"/v1/chat/completions"
;
}
public
async
Task
<(
bool
Ok
,
string
Message
)>
TestConnectionAsync
(
CancellationToken
ct
)
{
try
...
...
@@ -387,7 +449,7 @@ namespace Tools.MyAgent.Agent
using
(
var
cts
=
CancellationTokenSource
.
CreateLinkedTokenSource
(
ct
))
{
cts
.
CancelAfter
(
15000
);
var
req
=
new
HttpRequestMessage
(
HttpMethod
.
Post
,
BaseUrl
.
TrimEnd
(
'/'
)
+
"/chat/completions"
);
var
req
=
new
HttpRequestMessage
(
HttpMethod
.
Post
,
ResolveChatEndpoint
(
BaseUrl
)
);
req
.
Headers
.
TryAddWithoutValidation
(
"Authorization"
,
"Bearer "
+
ApiKey
);
req
.
Content
=
new
StringContent
(
body
.
ToString
(
Formatting
.
None
),
Encoding
.
UTF8
,
"application/json"
);
...
...
@@ -396,6 +458,8 @@ namespace Tools.MyAgent.Agent
string
json
=
await
resp
.
Content
.
ReadAsStringAsync
().
ConfigureAwait
(
false
);
if
(!
resp
.
IsSuccessStatusCode
)
return
(
false
,
$"HTTP
{(
int
)
resp
.
StatusCode
}
:
{
Truncate
(
json
,
200
)}
"
);
if
(
json
.
TrimStart
().
StartsWith
(
"<"
,
StringComparison
.
Ordinal
))
return
(
false
,
"接口返回 HTML,请检查 BaseUrl 是否正确(通常应填写服务根地址或 /v1 地址)。"
);
var
obj
=
JObject
.
Parse
(
json
);
var
content
=
obj
[
"choices"
]?[
0
]?[
"message"
]?[
"content"
]?.
Value
<
string
>();
...
...
Tools/MyAgent/Config/AgentConfig.cs
View file @
0fff0a7b
...
...
@@ -23,6 +23,9 @@
/// <summary>【核心】模型名称(可填写任意 OpenAI 兼容模型,如 Ollama 本地模型)</summary>
public
string
Model
{
get
;
set
;
}
=
"deepseek-v4-flash"
;
/// <summary>按提供商保存的模型列表(获取成功后持久化,兼容旧配置缺省为空)</summary>
public
Dictionary
<
string
,
List
<
string
>>
ModelLists
{
get
;
set
;
}
=
new
Dictionary
<
string
,
List
<
string
>>();
/// <summary>【核心】知识库根目录(支持本地路径或网络共享 UNC 路径,如 \\服务器\共享名)</summary>
public
string
KnowledgeBasePath
{
get
;
set
;
}
=
""
;
...
...
Tools/MyAgent/Forms/AgentSettingsForm.Designer.cs
View file @
0fff0a7b
...
...
@@ -36,6 +36,7 @@
this
.
lblApiKey
=
new
System
.
Windows
.
Forms
.
Label
();
this
.
txtApiKey
=
new
System
.
Windows
.
Forms
.
TextBox
();
this
.
btnTestApi
=
new
System
.
Windows
.
Forms
.
Button
();
this
.
btnFetchModels
=
new
System
.
Windows
.
Forms
.
Button
();
this
.
lblBaseUrl
=
new
System
.
Windows
.
Forms
.
Label
();
this
.
txtBaseUrl
=
new
System
.
Windows
.
Forms
.
TextBox
();
this
.
lblModel
=
new
System
.
Windows
.
Forms
.
Label
();
...
...
@@ -165,6 +166,7 @@
this
.
grpModel
.
Controls
.
Add
(
this
.
txtBaseUrl
);
this
.
grpModel
.
Controls
.
Add
(
this
.
lblModel
);
this
.
grpModel
.
Controls
.
Add
(
this
.
cmbModel
);
this
.
grpModel
.
Controls
.
Add
(
this
.
btnFetchModels
);
this
.
grpModel
.
Location
=
new
System
.
Drawing
.
Point
(
8
,
12
);
this
.
grpModel
.
Name
=
"grpModel"
;
this
.
grpModel
.
Size
=
new
System
.
Drawing
.
Size
(
596
,
164
);
...
...
@@ -260,9 +262,19 @@
"deepseek-r1"
});
this
.
cmbModel
.
Location
=
new
System
.
Drawing
.
Point
(
92
,
124
);
this
.
cmbModel
.
Name
=
"cmbModel"
;
this
.
cmbModel
.
Size
=
new
System
.
Drawing
.
Size
(
48
6
,
25
);
this
.
cmbModel
.
Size
=
new
System
.
Drawing
.
Size
(
30
6
,
25
);
this
.
cmbModel
.
TabIndex
=
8
;
//
// btnFetchModels
//
this
.
btnFetchModels
.
Location
=
new
System
.
Drawing
.
Point
(
406
,
123
);
this
.
btnFetchModels
.
Name
=
"btnFetchModels"
;
this
.
btnFetchModels
.
Size
=
new
System
.
Drawing
.
Size
(
172
,
25
);
this
.
btnFetchModels
.
TabIndex
=
9
;
this
.
btnFetchModels
.
Text
=
"获取模型列表"
;
this
.
btnFetchModels
.
UseVisualStyleBackColor
=
true
;
this
.
btnFetchModels
.
Click
+=
new
System
.
EventHandler
(
this
.
OnFetchModels
);
//
// grpKb
//
this
.
grpKb
.
Controls
.
Add
(
this
.
lblMode
);
...
...
@@ -1084,6 +1096,7 @@
private
System
.
Windows
.
Forms
.
Label
lblApiKey
;
private
System
.
Windows
.
Forms
.
TextBox
txtApiKey
;
private
System
.
Windows
.
Forms
.
Button
btnTestApi
;
private
System
.
Windows
.
Forms
.
Button
btnFetchModels
;
private
System
.
Windows
.
Forms
.
Label
lblBaseUrl
;
private
System
.
Windows
.
Forms
.
TextBox
txtBaseUrl
;
private
System
.
Windows
.
Forms
.
Label
lblModel
;
...
...
Tools/MyAgent/Forms/AgentSettingsForm.cs
View file @
0fff0a7b
This diff is collapsed.
Click to expand it.
Tools/MyAgent/wMyAgent.cs
View file @
0fff0a7b
...
...
@@ -216,6 +216,7 @@ namespace Tools.MyAgent
BaseUrl
=
cfg
.
BaseUrl
,
Model
=
cfg
.
Model
,
Provider
=
cfg
.
Provider
,
ModelLists
=
cfg
.
ModelLists
??
new
Dictionary
<
string
,
List
<
string
>>(),
KnowledgeBasePath
=
cfg
.
KnowledgeBasePath
,
KbMode
=
cfg
.
KbMode
,
ShareUser
=
cfg
.
ShareUser
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment