Commit ad2f9bb4 authored by 段廷瑞's avatar 段廷瑞

pref: 生成参数微调,可选能力默认启用

parent 6a91399b
......@@ -70,3 +70,4 @@ bin
!/AppHome/Agent/industry/
/AppHome/Agent/config/AgentConfig.json
/cc
/AppHome/Logs
......@@ -4,6 +4,8 @@ using System.Collections.Generic;
using System.Threading;
using Tools.MyAgent;
using Tools.MyAgent.Agent;
using Tools.MyAgent.Agent.Tools;
using Tools.MyAgent.Config;
using Tools.MyAgent.Kb;
namespace AgentTest
......@@ -27,6 +29,27 @@ namespace AgentTest
Assert.Equal(0, errorCount, "释放后的迟到请求不应再向 UI 上报网络错误");
}
[Test]
public void DefaultConfig_UsesExpandedGenerationDefaults_AndOptionalTools()
{
var cfg = new AgentConfig();
Assert.Equal(32768, cfg.MaxTokens, "默认输出上限应为原默认值的 4 倍");
Assert.Equal(128000, cfg.MaxContextTokens, "默认上下文预算应为原默认值的 4 倍");
Assert.True(cfg.EnableOptionalTools, "可选能力默认应启用");
}
[Test]
public void DefaultToolSchema_IncludesOptionalTools()
{
var tools = ToolSchema.Build();
string schema = tools.ToString();
Assert.Contains(schema, "db_query", "默认工具应包含数据库查询");
Assert.Contains(schema, "db_schema", "默认工具应包含数据库结构查询");
Assert.Contains(schema, "doc_export", "默认工具应包含文档导出");
}
// ── token 估算 ──
[Test]
......
No preview for this file type
......@@ -61,7 +61,7 @@
</summary>
</member>
<member name="F:Tools.MyAgent.Agent.AgentEngine._contextTokens">
<summary>上下文 token 预算(由配置注入;默认 32000)</summary>
<summary>上下文 token 预算(由配置注入;默认 128000)</summary>
</member>
<member name="F:Tools.MyAgent.Agent.AgentEngine.MaxToolReturnChars">
<summary>工具结果回填模型的字符上限(#42:超限压缩 + 完整结果落盘)。
......@@ -126,7 +126,7 @@
<summary>本次运行已自动续写的轮数(每次 RunAsync 重置;见 FinishAnswerAsync)</summary>
</member>
<member name="F:Tools.MyAgent.Agent.AgentEngine._includeOptionalTools">
<summary>是否向模型下发可选/高级工具(默认只下发核心工具)</summary>
<summary>是否向模型下发可选/高级工具(默认下发全部已注册工具)</summary>
</member>
<member name="F:Tools.MyAgent.Agent.AgentEngine._toolRoleAllow">
<summary>工具级权限(P3):工具名 → 允许角色列表;空 = 全部可用(由 AgentConfig.ToolRoleAllow 注入)</summary>
......@@ -495,7 +495,7 @@
</summary>
</member>
<member name="M:Tools.MyAgent.Agent.ToolSchema.Build">
<summary>构建默认工具(核心能力)的 JSON Schema</summary>
<summary>构建默认工具(包含可选能力)的 JSON Schema</summary>
</member>
<member name="M:Tools.MyAgent.Agent.ToolSchema.Build(System.Boolean,System.Func{System.String,System.Boolean})">
<summary>
......@@ -720,7 +720,7 @@
<summary>故障转移(#31):备用模型配置;EnableFailover 且主模型连续失败达阈值时自动切换</summary>
</member>
<member name="P:Tools.MyAgent.Config.AgentConfig.EnableOptionalTools">
<summary>是否启用可选/高级工具(db_query、module_patch、img_search、/workflow)</summary>
<summary>是否启用可选/高级工具(db_query、module_patch、img_search、/workflow);默认启用,可显式关闭</summary>
</member>
<member name="P:Tools.MyAgent.Config.AgentConfig.EnableImageInput">
<summary>是否启用图片提问(多模态,v2.2):启用后粘贴截图随提问以 image_url 发送,需视觉模型支持(如 DeepSeek-VL / qwen-vl);默认启用</summary>
......@@ -1206,7 +1206,7 @@
</summary>
</member>
<member name="M:Tools.MyAgent.Kb.KbIndex.Start">
<summary>启动:打开/建库 + 后台构建(幂等)</summary>
<summary>启动索引:只在后台打开 SQLite 并开始构建,调用方不会被建库 IO 阻塞。</summary>
</member>
<member name="M:Tools.MyAgent.Kb.KbIndex.Invalidate">
<summary>标记变更,调度后台增量重建(带去抖;构建中则完成后自动续跑)</summary>
......@@ -1357,6 +1357,11 @@
<member name="P:Tools.MyAgent.Kb.KbService.IsSearchValid">
<summary>搜索范围是否有效(目录存在)</summary>
</member>
<member name="M:Tools.MyAgent.Kb.KbService.EnsureIndexStartedIfSmall(System.Int32)">
<summary>
仅为小型知识库自动启动索引。文件数未知或超过阈值时保持未建索引,避免打开窗口触发大规模 SQLite 建库。
</summary>
</member>
<member name="M:Tools.MyAgent.Kb.KbService.EnsureIndexStarted">
<summary>
启动后台检索索引(幂等):索引目录固定为输出目录下 index 文件夹,与所选知识库无关。
......
......@@ -28,8 +28,8 @@ namespace Tools.MyAgent.Agent
private CancellationTokenSource _cts;
private int _disposeStarted;
/// <summary>上下文 token 预算(由配置注入;默认 32000)</summary>
private int _contextTokens = 32000;
/// <summary>上下文 token 预算(由配置注入;默认 128000)</summary>
private int _contextTokens = AgentConfig.DefaultMaxContextTokens;
// #31 故障转移
private FailoverPolicy _failover;
......@@ -107,8 +107,8 @@ namespace Tools.MyAgent.Agent
/// <summary>本次运行已自动续写的轮数(每次 RunAsync 重置;见 FinishAnswerAsync)</summary>
private int _continueRounds;
/// <summary>是否向模型下发可选/高级工具(默认只下发核心工具)</summary>
private bool _includeOptionalTools;
/// <summary>是否向模型下发可选/高级工具(默认下发全部已注册工具)</summary>
private bool _includeOptionalTools = true;
/// <summary>工具级权限(P3):工具名 → 允许角色列表;空 = 全部可用(由 AgentConfig.ToolRoleAllow 注入)</summary>
private Dictionary<string, string> _toolRoleAllow = new Dictionary<string, string>();
......@@ -194,8 +194,8 @@ namespace Tools.MyAgent.Agent
_client.ApiKey = cfg.ApiKey ?? "";
_client.Model = string.IsNullOrEmpty(cfg.Model) ? "deepseek-v4-flash" : cfg.Model;
_client.Temperature = cfg.Temperature;
_client.MaxTokens = cfg.MaxTokens > 0 ? cfg.MaxTokens : 8192;
_contextTokens = cfg.MaxContextTokens > 0 ? cfg.MaxContextTokens : 32000;
_client.MaxTokens = cfg.MaxTokens > 0 ? cfg.MaxTokens : AgentConfig.DefaultMaxTokens;
_contextTokens = cfg.MaxContextTokens > 0 ? cfg.MaxContextTokens : AgentConfig.DefaultMaxContextTokens;
// R12:策略参数(越界回退默认,防止手改配置文件导致异常行为)
_maxToolRounds = ClampStrategy(cfg.MaxToolRounds, 1, 50, 15);
_maxHistoryMessages = ClampStrategy(cfg.MaxHistoryMessages, 3, 200, 60);
......
using System;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Tools.MyAgent.Config;
namespace Tools.MyAgent.Agent
{
......@@ -36,7 +36,7 @@ namespace Tools.MyAgent.Agent
_backup.ApiKey = backupApiKey ?? "";
_backup.Model = string.IsNullOrEmpty(backupModel) ? "qwen2.5" : backupModel;
_backup.Temperature = 0.3;
_backup.MaxTokens = 8192;
_backup.MaxTokens = AgentConfig.DefaultMaxTokens;
}
if (!enabled && _failedOver)
{
......
......@@ -9,6 +9,7 @@ using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tools.MyAgent.Config;
namespace Tools.MyAgent.Agent
{
......@@ -46,7 +47,7 @@ namespace Tools.MyAgent.Agent
public string ApiKey { get; set; } = "";
public string Model { get; set; } = "deepseek-v4-flash";
public double Temperature { get; set; } = 0.3;
public int MaxTokens { get; set; } = 8192;
public int MaxTokens { get; set; } = AgentConfig.DefaultMaxTokens;
/// <summary>获取当前兼容接口公开的模型列表(不影响聊天请求)</summary>
public async Task<(bool Ok, string Message, List<string> Models)> FetchModelsAsync(CancellationToken ct)
......
......@@ -10,8 +10,8 @@ namespace Tools.MyAgent.Agent
/// </summary>
public static class ToolSchema
{
/// <summary>构建默认工具(核心能力)的 JSON Schema</summary>
public static JArray Build() => Build(false);
/// <summary>构建默认工具(包含可选能力)的 JSON Schema</summary>
public static JArray Build() => Build(true);
/// <summary>
/// 构建工具 JSON Schema;includeOptional=true 时包含高级/可选工具;
......
......@@ -9,6 +9,10 @@
/// </summary>
public sealed class AgentConfig
{
public const double DefaultTemperature = 0.3;
public const int DefaultMaxTokens = 32768;
public const int DefaultMaxContextTokens = 128000;
// ════════════════ 核心项(主设置页) ════════════════
/// <summary>【核心】提供商预设名(DeepSeek / 通义千问 / OpenAI / 本地 Ollama / 自定义)</summary>
......@@ -52,13 +56,13 @@
// ════════════════ 高级项:生成参数 ════════════════
/// <summary>采样温度</summary>
public double Temperature { get; set; } = 0.3;
public double Temperature { get; set; } = DefaultTemperature;
/// <summary>输出上限(过小会导致长回答被截断残缺;若超出模型上限,客户端会自动减半重试兑底)</summary>
public int MaxTokens { get; set; } = 8192;
public int MaxTokens { get; set; } = DefaultMaxTokens;
/// <summary>上下文 token 预算(超出后自动裁剪历史 / LLM 摘要压缩;0 = 使用模型默认值)</summary>
public int MaxContextTokens { get; set; } = 32000;
public int MaxContextTokens { get; set; } = DefaultMaxContextTokens;
/// <summary>是否使用系统代理(挂 WebRequest.GetSystemWebProxy / HTTPS_PROXY 环境变量)</summary>
public bool UseSystemProxy { get; set; } = true;
......@@ -98,8 +102,8 @@
// ════════════════ 高级项:可选能力 ════════════════
/// <summary>是否启用可选/高级工具(db_query、module_patch、img_search、/workflow)</summary>
public bool EnableOptionalTools { get; set; } = false;
/// <summary>是否启用可选/高级工具(db_query、module_patch、img_search、/workflow);默认启用,可显式关闭</summary>
public bool EnableOptionalTools { get; set; } = true;
/// <summary>是否启用图片提问(多模态,v2.2):启用后粘贴截图随提问以 image_url 发送,需视觉模型支持(如 DeepSeek-VL / qwen-vl);默认启用</summary>
public bool EnableImageInput { get; set; } = true;
......
......@@ -554,7 +554,7 @@
0});
this.numMaxTokens.Location = new System.Drawing.Point(384, 28);
this.numMaxTokens.Maximum = new decimal(new int[] {
16384,
65536,
0,
0,
0});
......@@ -567,7 +567,7 @@
this.numMaxTokens.Size = new System.Drawing.Size(96, 23);
this.numMaxTokens.TabIndex = 4;
this.numMaxTokens.Value = new decimal(new int[] {
8192,
32768,
0,
0,
0});
......@@ -590,7 +590,7 @@
0});
this.numContext.Location = new System.Drawing.Point(92, 60);
this.numContext.Maximum = new decimal(new int[] {
200000,
800000,
0,
0,
0});
......@@ -603,7 +603,7 @@
this.numContext.Size = new System.Drawing.Size(96, 23);
this.numContext.TabIndex = 6;
this.numContext.Value = new decimal(new int[] {
32000,
128000,
0,
0,
0});
......
......@@ -270,9 +270,9 @@ namespace Tools.MyAgent.Forms
// 基础配置:UI 风格固定为 RichBox(RichTextBox + RTF 渲染),不再提供 WebView 选项
// 高级配置:生成参数
numTemp.Value = ClampDecimalToControl(_config.Temperature, numTemp, 0.3m);
numMaxTokens.Value = ClampToControl(_config.MaxTokens, numMaxTokens, 8192);
numContext.Value = ClampToControl(_config.MaxContextTokens, numContext, 32000);
numTemp.Value = ClampDecimalToControl(_config.Temperature, numTemp, (decimal)AgentConfig.DefaultTemperature);
numMaxTokens.Value = ClampToControl(_config.MaxTokens, numMaxTokens, AgentConfig.DefaultMaxTokens);
numContext.Value = ClampToControl(_config.MaxContextTokens, numContext, AgentConfig.DefaultMaxContextTokens);
chkProxy.Checked = _config.UseSystemProxy;
// 高级配置:策略参数(R12;越界回退默认,避免 NumericUpDown 赋值抛异常)
......
......@@ -27,7 +27,7 @@ namespace Tools.MyAgent
this.components = new System.ComponentModel.Container();
this.panelChat = new System.Windows.Forms.Panel();
this.panelBottom = new System.Windows.Forms.Panel();
this.btnSend = new System.Windows.Forms.Button();
this.lblShortcutHint = new System.Windows.Forms.Label();
this.txtInput = new System.Windows.Forms.TextBox();
this.panelToolbar = new System.Windows.Forms.Panel();
this.lblCopy = new System.Windows.Forms.LinkLabel();
......@@ -54,8 +54,8 @@ namespace Tools.MyAgent
//
// panelBottom
//
this.panelBottom.Controls.Add(this.btnSend);
this.panelBottom.Controls.Add(this.txtInput);
this.panelBottom.Controls.Add(this.lblShortcutHint);
this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelBottom.Location = new System.Drawing.Point(0, 490);
this.panelBottom.Margin = new System.Windows.Forms.Padding(4);
......@@ -64,20 +64,18 @@ namespace Tools.MyAgent
this.panelBottom.Size = new System.Drawing.Size(817, 148);
this.panelBottom.TabIndex = 1;
//
// btnSend
//
this.btnSend.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(212)))));
this.btnSend.Dock = System.Windows.Forms.DockStyle.Right;
this.btnSend.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnSend.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Bold);
this.btnSend.ForeColor = System.Drawing.Color.White;
this.btnSend.Location = new System.Drawing.Point(723, 6);
this.btnSend.Margin = new System.Windows.Forms.Padding(4);
this.btnSend.Name = "btnSend";
this.btnSend.Size = new System.Drawing.Size(89, 136);
this.btnSend.TabIndex = 1;
this.btnSend.Text = "发送";
this.btnSend.UseVisualStyleBackColor = false;
// lblShortcutHint
//
this.lblShortcutHint.Dock = System.Windows.Forms.DockStyle.Bottom;
this.lblShortcutHint.Font = new System.Drawing.Font("微软雅黑", 9F);
this.lblShortcutHint.ForeColor = System.Drawing.Color.Gray;
this.lblShortcutHint.Location = new System.Drawing.Point(5, 112);
this.lblShortcutHint.Name = "lblShortcutHint";
this.lblShortcutHint.Padding = new System.Windows.Forms.Padding(4, 0, 0, 0);
this.lblShortcutHint.Size = new System.Drawing.Size(807, 24);
this.lblShortcutHint.TabIndex = 2;
this.lblShortcutHint.Text = "Enter 发送,Shift + Enter 换行";
this.lblShortcutHint.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// txtInput
//
......@@ -228,7 +226,7 @@ namespace Tools.MyAgent
private System.Windows.Forms.Panel panelChat;
private System.Windows.Forms.Panel panelBottom;
private System.Windows.Forms.Button btnSend;
private System.Windows.Forms.Label lblShortcutHint;
private System.Windows.Forms.TextBox txtInput;
private System.Windows.Forms.Panel panelToolbar;
private System.Windows.Forms.LinkLabel lblNewChat;
......
......@@ -388,7 +388,7 @@ namespace Tools.MyAgent
cmbScope.SelectedIndexChanged += (s, e) => OnScopeComboChanged();
lblSaveKb.LinkClicked += (s, e) => SaveLastAnswerToKb();
lblCopy.LinkClicked += (s, e) => CopyLastAnswer();
btnSend.Click += (s, e) => OnSendButtonClick();
// 发送/取消均使用键盘:Enter 发送,ESC 取消
txtInput.KeyDown += OnInputKeyDown;
// 输入框拖入图片文件 → 加入待发送附图列表(与 Ctrl+V 粘贴同一套收图流程)
txtInput.AllowDrop = true;
......@@ -532,7 +532,7 @@ namespace Tools.MyAgent
// ── 发送 / 取消 ──────────────────────────────────
private void OnSendButtonClick()
private void OnSendOrCancel()
{
if (_engine.IsRunning)
{
......@@ -568,7 +568,7 @@ namespace Tools.MyAgent
txtInput.Text = "";
SetInputEnabled(false);
SetButtonState(true);
SetShortcutHint(true);
_messages.Add(new ChatMessage
{
......@@ -770,24 +770,20 @@ namespace Tools.MyAgent
txtInput.Focus();
}
private void SetButtonState(bool isRunning)
private void SetShortcutHint(bool isRunning)
{
if (isRunning)
{
btnSend.Text = "取消";
btnSend.BackColor = Color.FromArgb(220, 50, 50);
}
else
{
btnSend.Text = "发送";
btnSend.BackColor = Color.FromArgb(0, 120, 212);
}
lblShortcutHint.Text = isRunning
? "ESC 取消"
: "Enter 发送,Shift + Enter 换行";
lblShortcutHint.ForeColor = isRunning
? Color.FromArgb(190, 50, 50)
: Color.Gray;
}
private void ResetInputState()
{
SetInputEnabled(true);
SetButtonState(false);
SetShortcutHint(false);
txtInput.Focus();
}
......@@ -1060,7 +1056,7 @@ namespace Tools.MyAgent
// Enter:录入选中命令并作为消息发送
e.Handled = true; e.SuppressKeyPress = true;
CommitSelectedCommand();
OnSendButtonClick();
OnSendOrCancel();
return;
}
if (e.KeyCode == Keys.Escape)
......@@ -1098,7 +1094,7 @@ namespace Tools.MyAgent
{
// Enter:发送(回复中则为取消)
e.SuppressKeyPress = true;
OnSendButtonClick();
OnSendOrCancel();
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment