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
19a69673
Commit
19a69673
authored
Sep 10, 2026
by
段廷瑞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: Agent交互优化
parent
ad2f9bb4
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
60 additions
and
16 deletions
+60
-16
AgentEngineLogicTests.cs
AgentTest/AgentEngineLogicTests.cs
+22
-2
Tools.Agent.dll
AppHome/Tools.Agent.dll
+0
-0
Tools.Agent.xml
AppHome/Tools.Agent.xml
+1
-1
AgentEngine.cs
Tools.Agent/Agent/AgentEngine.cs
+9
-5
OpenAiCompatibleClient.cs
Tools.Agent/Agent/OpenAiCompatibleClient.cs
+20
-2
AgentConfig.cs
Tools.Agent/Config/AgentConfig.cs
+4
-2
AgentSettingsForm.Designer.cs
Tools.Agent/Forms/AgentSettingsForm.Designer.cs
+4
-4
No files found.
AgentTest/AgentEngineLogicTests.cs
View file @
19a69673
...
@@ -34,8 +34,8 @@ namespace AgentTest
...
@@ -34,8 +34,8 @@ namespace AgentTest
{
{
var
cfg
=
new
AgentConfig
();
var
cfg
=
new
AgentConfig
();
Assert
.
Equal
(
32768
,
cfg
.
MaxTokens
,
"默认输出上限应为原默认值的 4 倍
"
);
Assert
.
Equal
(
16384
,
cfg
.
MaxTokens
,
"默认输出上限应调整为兼容值
"
);
Assert
.
Equal
(
128000
,
cfg
.
MaxContextTokens
,
"默认上下文预算应为原默认值的 4 倍
"
);
Assert
.
Equal
(
64000
,
cfg
.
MaxContextTokens
,
"默认上下文预算应调整为兼容值
"
);
Assert
.
True
(
cfg
.
EnableOptionalTools
,
"可选能力默认应启用"
);
Assert
.
True
(
cfg
.
EnableOptionalTools
,
"可选能力默认应启用"
);
}
}
...
@@ -50,8 +50,28 @@ namespace AgentTest
...
@@ -50,8 +50,28 @@ namespace AgentTest
Assert
.
Contains
(
schema
,
"doc_export"
,
"默认工具应包含文档导出"
);
Assert
.
Contains
(
schema
,
"doc_export"
,
"默认工具应包含文档导出"
);
}
}
[
Test
]
public
void
NormalizeMessageContents_ConvertsInvalidTypes_AndKeepsLists
()
{
var
original
=
new
JArray
{
new
JObject
{
[
"role"
]
=
"user"
,
[
"content"
]
=
JValue
.
CreateNull
()
},
new
JObject
{
[
"role"
]
=
"assistant"
,
[
"content"
]
=
new
JObject
{
[
"value"
]
=
"legacy"
}
},
new
JObject
{
[
"role"
]
=
"user"
,
[
"content"
]
=
new
JArray
{
new
JObject
{
[
"type"
]
=
"text"
,
[
"text"
]
=
"图片问题"
}
}
},
};
var
normalized
=
OpenAiCompatibleClient
.
NormalizeMessageContents
(
original
);
Assert
.
Equal
(
JTokenType
.
String
,
normalized
[
0
][
"content"
]?.
Type
,
"null content 应转为空字符串"
);
Assert
.
Equal
(
""
,
normalized
[
0
][
"content"
]?.
Value
<
string
>());
Assert
.
Equal
(
JTokenType
.
String
,
normalized
[
1
][
"content"
]?.
Type
,
"对象 content 应转为字符串"
);
Assert
.
Equal
(
JTokenType
.
Array
,
normalized
[
2
][
"content"
]?.
Type
,
"合法多模态 content 数组应保留"
);
Assert
.
Equal
(
JTokenType
.
Null
,
original
[
0
][
"content"
]?.
Type
,
"规范化不应修改原始消息"
);
}
// ── token 估算 ──
// ── token 估算 ──
[
Test
]
[
Test
]
public
void
EstimateTokens_Text_CjkAndAscii
()
public
void
EstimateTokens_Text_CjkAndAscii
()
{
{
...
...
AppHome/Tools.Agent.dll
View file @
19a69673
No preview for this file type
AppHome/Tools.Agent.xml
View file @
19a69673
...
@@ -61,7 +61,7 @@
...
@@ -61,7 +61,7 @@
</summary>
</summary>
</member>
</member>
<member
name=
"F:Tools.MyAgent.Agent.AgentEngine._contextTokens"
>
<member
name=
"F:Tools.MyAgent.Agent.AgentEngine._contextTokens"
>
<summary>
上下文 token 预算(由配置注入;默认
128
000)
</summary>
<summary>
上下文 token 预算(由配置注入;默认
64
000)
</summary>
</member>
</member>
<member
name=
"F:Tools.MyAgent.Agent.AgentEngine.MaxToolReturnChars"
>
<member
name=
"F:Tools.MyAgent.Agent.AgentEngine.MaxToolReturnChars"
>
<summary>
工具结果回填模型的字符上限(#42:超限压缩 + 完整结果落盘)。
<summary>
工具结果回填模型的字符上限(#42:超限压缩 + 完整结果落盘)。
...
...
Tools.Agent/Agent/AgentEngine.cs
View file @
19a69673
...
@@ -28,7 +28,7 @@ namespace Tools.MyAgent.Agent
...
@@ -28,7 +28,7 @@ namespace Tools.MyAgent.Agent
private
CancellationTokenSource
_cts
;
private
CancellationTokenSource
_cts
;
private
int
_disposeStarted
;
private
int
_disposeStarted
;
/// <summary>上下文 token 预算(由配置注入;默认
128
000)</summary>
/// <summary>上下文 token 预算(由配置注入;默认
64
000)</summary>
private
int
_contextTokens
=
AgentConfig
.
DefaultMaxContextTokens
;
private
int
_contextTokens
=
AgentConfig
.
DefaultMaxContextTokens
;
// #31 故障转移
// #31 故障转移
...
@@ -194,8 +194,12 @@ namespace Tools.MyAgent.Agent
...
@@ -194,8 +194,12 @@ namespace Tools.MyAgent.Agent
_client
.
ApiKey
=
cfg
.
ApiKey
??
""
;
_client
.
ApiKey
=
cfg
.
ApiKey
??
""
;
_client
.
Model
=
string
.
IsNullOrEmpty
(
cfg
.
Model
)
?
"deepseek-v4-flash"
:
cfg
.
Model
;
_client
.
Model
=
string
.
IsNullOrEmpty
(
cfg
.
Model
)
?
"deepseek-v4-flash"
:
cfg
.
Model
;
_client
.
Temperature
=
cfg
.
Temperature
;
_client
.
Temperature
=
cfg
.
Temperature
;
_client
.
MaxTokens
=
cfg
.
MaxTokens
>
0
?
cfg
.
MaxTokens
:
AgentConfig
.
DefaultMaxTokens
;
_client
.
MaxTokens
=
cfg
.
MaxTokens
>
0
_contextTokens
=
cfg
.
MaxContextTokens
>
0
?
cfg
.
MaxContextTokens
:
AgentConfig
.
DefaultMaxContextTokens
;
?
Math
.
Min
(
cfg
.
MaxTokens
,
AgentConfig
.
MaxAllowedTokens
)
:
AgentConfig
.
DefaultMaxTokens
;
_contextTokens
=
cfg
.
MaxContextTokens
>
0
?
Math
.
Min
(
cfg
.
MaxContextTokens
,
AgentConfig
.
MaxAllowedContextTokens
)
:
AgentConfig
.
DefaultMaxContextTokens
;
// R12:策略参数(越界回退默认,防止手改配置文件导致异常行为)
// R12:策略参数(越界回退默认,防止手改配置文件导致异常行为)
_maxToolRounds
=
ClampStrategy
(
cfg
.
MaxToolRounds
,
1
,
50
,
15
);
_maxToolRounds
=
ClampStrategy
(
cfg
.
MaxToolRounds
,
1
,
50
,
15
);
_maxHistoryMessages
=
ClampStrategy
(
cfg
.
MaxHistoryMessages
,
3
,
200
,
60
);
_maxHistoryMessages
=
ClampStrategy
(
cfg
.
MaxHistoryMessages
,
3
,
200
,
60
);
...
@@ -299,7 +303,7 @@ namespace Tools.MyAgent.Agent
...
@@ -299,7 +303,7 @@ namespace Tools.MyAgent.Agent
foreach
(
var
tc
in
result
.
ToolCalls
)
foreach
(
var
tc
in
result
.
ToolCalls
)
{
{
_cts
.
Token
.
ThrowIfCancellationRequested
();
_cts
.
Token
.
ThrowIfCancellationRequested
();
string
toolResult
=
await
ExecuteToolAsync
(
tc
,
_cts
.
Token
).
ConfigureAwait
(
false
);
string
toolResult
=
await
ExecuteToolAsync
(
tc
,
_cts
.
Token
).
ConfigureAwait
(
false
)
??
""
;
messages
.
Add
(
new
JObject
messages
.
Add
(
new
JObject
{
{
[
"role"
]
=
"tool"
,
[
"role"
]
=
"tool"
,
...
@@ -971,7 +975,7 @@ namespace Tools.MyAgent.Agent
...
@@ -971,7 +975,7 @@ namespace Tools.MyAgent.Agent
// #29 工具日志
// #29 工具日志
AgentLogger
.
LogTool
(
tc
.
Name
,
desc
,
sw
.
ElapsedMilliseconds
,
SummarizeToolResult
(
result
));
AgentLogger
.
LogTool
(
tc
.
Name
,
desc
,
sw
.
ElapsedMilliseconds
,
SummarizeToolResult
(
result
));
// #42 结果压缩:超长结果压缩后回填模型,完整结果落盘供溯源
// #42 结果压缩:超长结果压缩后回填模型,完整结果落盘供溯源
result
=
CompressToolResult
(
result
,
tc
.
Name
);
result
=
CompressToolResult
(
result
,
tc
.
Name
)
??
""
;
if
(
gen
==
System
.
Threading
.
Volatile
.
Read
(
ref
_runGeneration
))
if
(
gen
==
System
.
Threading
.
Volatile
.
Read
(
ref
_runGeneration
))
{
{
lock
(
_toolTrace
)
lock
(
_toolTrace
)
...
...
Tools.Agent/Agent/OpenAiCompatibleClient.cs
View file @
19a69673
...
@@ -243,6 +243,24 @@ namespace Tools.MyAgent.Agent
...
@@ -243,6 +243,24 @@ namespace Tools.MyAgent.Agent
}
}
}
}
internal
static
JArray
NormalizeMessageContents
(
JArray
messages
)
{
var
normalized
=
messages
==
null
?
new
JArray
()
:
(
JArray
)
messages
.
DeepClone
();
foreach
(
var
message
in
normalized
.
OfType
<
JObject
>())
{
var
content
=
message
[
"content"
];
if
(
content
==
null
||
content
.
Type
==
JTokenType
.
Null
)
{
message
[
"content"
]
=
""
;
}
else
if
(
content
.
Type
!=
JTokenType
.
String
&&
content
.
Type
!=
JTokenType
.
Array
)
{
message
[
"content"
]
=
content
.
ToString
(
Formatting
.
None
);
}
}
return
normalized
;
}
/// <summary>
/// <summary>
/// 发起一次流式补全,返回最终结果(正文 / 推理 / 工具调用)。
/// 发起一次流式补全,返回最终结果(正文 / 推理 / 工具调用)。
/// <para>对 429 / 5xx / 连接超时 / 流中断做指数退避 + 抖动重试(最多 2 次),最终失败才抛出。</para>
/// <para>对 429 / 5xx / 连接超时 / 流中断做指数退避 + 抖动重试(最多 2 次),最终失败才抛出。</para>
...
@@ -253,7 +271,7 @@ namespace Tools.MyAgent.Agent
...
@@ -253,7 +271,7 @@ namespace Tools.MyAgent.Agent
var
body
=
new
JObject
var
body
=
new
JObject
{
{
[
"model"
]
=
Model
,
[
"model"
]
=
Model
,
[
"messages"
]
=
messages
,
[
"messages"
]
=
NormalizeMessageContents
(
messages
)
,
[
"stream"
]
=
true
,
[
"stream"
]
=
true
,
[
"max_tokens"
]
=
MaxTokens
,
[
"max_tokens"
]
=
MaxTokens
,
};
};
...
@@ -485,7 +503,7 @@ namespace Tools.MyAgent.Agent
...
@@ -485,7 +503,7 @@ namespace Tools.MyAgent.Agent
var
body
=
new
JObject
var
body
=
new
JObject
{
{
[
"model"
]
=
Model
,
[
"model"
]
=
Model
,
[
"messages"
]
=
messages
,
[
"messages"
]
=
NormalizeMessageContents
(
messages
)
,
[
"stream"
]
=
false
,
[
"stream"
]
=
false
,
[
"max_tokens"
]
=
maxTokens
,
[
"max_tokens"
]
=
maxTokens
,
};
};
...
...
Tools.Agent/Config/AgentConfig.cs
View file @
19a69673
...
@@ -10,8 +10,10 @@
...
@@ -10,8 +10,10 @@
public
sealed
class
AgentConfig
public
sealed
class
AgentConfig
{
{
public
const
double
DefaultTemperature
=
0.3
;
public
const
double
DefaultTemperature
=
0.3
;
public
const
int
DefaultMaxTokens
=
32768
;
public
const
int
DefaultMaxTokens
=
16384
;
public
const
int
DefaultMaxContextTokens
=
128000
;
public
const
int
MaxAllowedTokens
=
32768
;
public
const
int
DefaultMaxContextTokens
=
64000
;
public
const
int
MaxAllowedContextTokens
=
200000
;
// ════════════════ 核心项(主设置页) ════════════════
// ════════════════ 核心项(主设置页) ════════════════
...
...
Tools.Agent/Forms/AgentSettingsForm.Designer.cs
View file @
19a69673
...
@@ -554,7 +554,7 @@
...
@@ -554,7 +554,7 @@
0
});
0
});
this
.
numMaxTokens
.
Location
=
new
System
.
Drawing
.
Point
(
384
,
28
);
this
.
numMaxTokens
.
Location
=
new
System
.
Drawing
.
Point
(
384
,
28
);
this
.
numMaxTokens
.
Maximum
=
new
decimal
(
new
int
[]
{
this
.
numMaxTokens
.
Maximum
=
new
decimal
(
new
int
[]
{
65536
,
32768
,
0
,
0
,
0
,
0
,
0
});
0
});
...
@@ -567,7 +567,7 @@
...
@@ -567,7 +567,7 @@
this
.
numMaxTokens
.
Size
=
new
System
.
Drawing
.
Size
(
96
,
23
);
this
.
numMaxTokens
.
Size
=
new
System
.
Drawing
.
Size
(
96
,
23
);
this
.
numMaxTokens
.
TabIndex
=
4
;
this
.
numMaxTokens
.
TabIndex
=
4
;
this
.
numMaxTokens
.
Value
=
new
decimal
(
new
int
[]
{
this
.
numMaxTokens
.
Value
=
new
decimal
(
new
int
[]
{
32768
,
16384
,
0
,
0
,
0
,
0
,
0
});
0
});
...
@@ -590,7 +590,7 @@
...
@@ -590,7 +590,7 @@
0
});
0
});
this
.
numContext
.
Location
=
new
System
.
Drawing
.
Point
(
92
,
60
);
this
.
numContext
.
Location
=
new
System
.
Drawing
.
Point
(
92
,
60
);
this
.
numContext
.
Maximum
=
new
decimal
(
new
int
[]
{
this
.
numContext
.
Maximum
=
new
decimal
(
new
int
[]
{
8
00000
,
2
00000
,
0
,
0
,
0
,
0
,
0
});
0
});
...
@@ -603,7 +603,7 @@
...
@@ -603,7 +603,7 @@
this
.
numContext
.
Size
=
new
System
.
Drawing
.
Size
(
96
,
23
);
this
.
numContext
.
Size
=
new
System
.
Drawing
.
Size
(
96
,
23
);
this
.
numContext
.
TabIndex
=
6
;
this
.
numContext
.
TabIndex
=
6
;
this
.
numContext
.
Value
=
new
decimal
(
new
int
[]
{
this
.
numContext
.
Value
=
new
decimal
(
new
int
[]
{
128
000
,
64
000
,
0
,
0
,
0
,
0
,
0
});
0
});
...
...
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