From 9fe13fa7192fab814c249d0e22b5865925106f68 Mon Sep 17 00:00:00 2001 From: PeterZhong Date: Sat, 31 May 2025 11:52:41 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E5=A4=8DArcGIS=20Pro=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=8C=83=E5=9B=B4=E7=BB=93=E6=9E=9C=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=202.=20=E8=AF=86=E5=88=AB=E5=8D=95?= =?UTF-8?q?=E6=9D=A1=E6=B6=88=E6=81=AF=E6=9C=AB=E5=B0=BE=E7=9A=84[DONE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/tool/ArcGisPro.cs | 41 +++++++++++++++++++++++++++----- host/Gateway.cs | 11 ++++++--- host/prompt/SystemPrompt.cs | 6 +++-- ui/dockpane/TestDockpane.xaml | 2 +- ui/dockpane/TestDockpane.xaml.cs | 2 +- 5 files changed, 49 insertions(+), 13 deletions(-) diff --git a/client/tool/ArcGisPro.cs b/client/tool/ArcGisPro.cs index 163f253..f1b9866 100644 --- a/client/tool/ArcGisPro.cs +++ b/client/tool/ArcGisPro.cs @@ -6,8 +6,11 @@ using System.Threading.Tasks; using ArcGIS.Core.Data; using ArcGIS.Core.Data.Raster; using ArcGIS.Core.Geometry; +using ArcGIS.Desktop.Core.Geoprocessing; using ArcGIS.Desktop.Framework.Threading.Tasks; using LinkToolAddin.server; +using LinkToolAddin.ui.dockpane; +using log4net; using ModelContextProtocol.Server; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -16,14 +19,40 @@ namespace LinkToolAddin.client.tool; public class ArcGisPro { - [McpServerTool, Description("可以通过调用ArcGIS Pro的地理处理工具实现一些数据处理功能。")] + private static ILog log = LogManager.GetLogger(typeof(ArcGisPro)); + [McpServerTool, Description("可以通过调用ArcGIS Pro的地理处理工具实现一些数据处理功能,传入参数必须严格遵循ArcGIS Pro调用工具的标准调用名和参数要求知识库。")] public static async Task ArcGisProTool(string toolName, List toolParams) { - // Call the ArcGIS Pro method and get the result - var result = await server.CallArcGISPro.CallArcGISProTool(toolName, toolParams); - - // Serialize the result back to a JSON string - return result; + IGPResult results = await Geoprocessing.ExecuteToolAsync(toolName, toolParams); + JsonRpcResultEntity jsonRpcResultEntity; + if (results.IsFailed) + { + log.Error(results.ErrorMessages); + jsonRpcResultEntity = new JsonRpcErrorEntity() + { + Error = new Error() + { + Code = results.ErrorCode, + Message = JsonConvert.SerializeObject(results.ErrorMessages) + } + }; + }else if(results.HasWarnings) + { + log.Warn(results.Messages); + jsonRpcResultEntity = new JsonRpcSuccessEntity + { + Result = JsonConvert.SerializeObject(results.Messages) + }; + } + else + { + log.Info("success gp tool"); + jsonRpcResultEntity = new JsonRpcSuccessEntity + { + Result = JsonConvert.SerializeObject(results.Messages) + }; + } + return jsonRpcResultEntity; } [McpServerTool, Description("查看指定数据的坐标系、范围、几何类型、是否有Z坐标和M坐标,获取字段列表等")] diff --git a/host/Gateway.cs b/host/Gateway.cs index 28935f0..d20b0a8 100644 --- a/host/Gateway.cs +++ b/host/Gateway.cs @@ -222,7 +222,7 @@ public class Gateway }; callback?.Invoke(chatMessageListItem); } - if (reponse == "[DONE]") + if (reponse.EndsWith("[DONE]")) { goOn = false; } @@ -467,15 +467,20 @@ public class Gateway } else { + string content = chunk; + if (content.EndsWith("[DONE]")) + { + content = content.Substring(0, content.Length - 6); + } //普通流式消息卡片 MessageListItem chatMessageListItem = new ChatMessageItem() { - content = chunk, + content = content, role = "assistant", type = MessageType.CHAT_MESSAGE, id = timestamp.ToString() }; - messageContent = chunk; + messageContent = content; callback?.Invoke(chatMessageListItem); } } diff --git a/host/prompt/SystemPrompt.cs b/host/prompt/SystemPrompt.cs index 69f180a..67ea12c 100644 --- a/host/prompt/SystemPrompt.cs +++ b/host/prompt/SystemPrompt.cs @@ -20,14 +20,16 @@ public class SystemPrompt "4.如果目前工作已经完成无法知道用户其他需求时,一定要单独输出一条内容为'[DONE]'的消息表示工具调用结束。不要在文本的末尾。" + "5.不得在同一消息中混合说明文字与工具调用。" + "结果:用户将以以下格式返回工具调用结果:\n {tool_name}\n {result}\n。应为字符串类型,可以表示文件或其他输出类型。" + - "工具调用示例:MCP工具调用的格式要求示例:以下是使用虚拟工具的示例:\\n gaode:maps_geo\\n {\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}\\n"; + "工具调用示例:MCP工具调用的格式要求示例:以下是使用虚拟工具的示例:\\n gaode:maps_geo\\n {\\\"address\\\":\\\"广州市政府, 广州市\\\", \\\"city\\\":\\\"广州\\\"}\\n"+ + "特别地:需要调用ArcGIS Pro工具前必须先查询帮助文档、标准调用名和参数后再进行调用"; //"现在你是一个精通地理信息分析和ArcGIS Pro软件的专家,请以此身份回答用户的问题。\r\n\r\n指令:\r\n你需要使用一组工具来回答用户的问题。也可以通过 标签调用用户提示词,以帮助你更好地理解任务。所有操作完成后,在最后一条输出中包含 '[DONE]',但不要单独发送这条消息。\r\n\r\n调用工具要求:\r\n1. 每次只能调用一个工具,并等待用户的反馈结果。\r\n2. 所有工具调用都必须基于前一步的结果进行推理和决策。\r\n3. 工具调用必须以 XML 格式输出,并且必须作为**独立的一条消息输出**,前后不得有任何解释性文字或说明内容。\r\n4. 如果需要提供解释、说明或引导信息,请先单独输出一段普通文本,**其中不能包含任何 XML 标签或格式**。\r\n5. 不得重复调用已经成功执行过的工具,除非有新的参数或上下文需要重新调用。\r\n\r\n工具调用背景:\r\n你有以下工具可以调用:{{toolInfos}} \r\n用户的数据库路径是:{{gdbPath}}\r\n\r\n输出风格:\r\n- 所有工具调用都必须使用标准 XML 格式输出,并且每条消息只包含一次调用。\r\n- 文字说明必须单独输出,且为普通段落格式,不含任何 XML 或 Markdown 标记。\r\n- 输出顺序应为:【可选的文字说明】→【必选的工具调用】,或者仅输出工具调用。\r\n\r\n工具调用格式示例:\r\n\r\n {tool_name}\r\n {json_arguments}\r\n\r\n\r\n例如:\r\n\r\n gaode:maps_geo\r\n {\"address\":\"广州市政府, 广州市\", \"city\":\"广州\"}\r\n\r\n\r\n注意事项:\r\n1. 工具名称必须与实际工具完全一致。\r\n2. 参数必须为合法 JSON 格式,且符合工具要求。\r\n3. 用户时间宝贵,请高效调用工具,尽快完成任务。\r\n4. 最终完成时应在最后一次响应中包含 [DONE],而不是单独输出。\r\n\r\n工具调用结果返回格式:\r\n用户将以如下格式返回工具调用结果:\r\n\r\n {tool_name}\r\n {result}\r\n\r\n\r\n例如:\r\n\r\n ArcGIS_Pro:GP\r\n {\"output_file\": \"source.shp\"}\r\n\r\n\r\n请始终遵循此格式以确保工具调用被正确解析和执行。"; public static string ContinuePromptTemplate = "这是上述工具调用的结果。{{toolResult}}\n请根据以下执行结果,清晰解释执行结果并执行下一步操作。" + "执行下一步工具的要求:1. 解析工具输出结果2. 调用下一个工具时确保参数继承前序输出。请据此继续执行"; public static string ErrorPromptTemplate = "执行上一个工具的时候出现以下错误,需按以下流程处理:1. 错误解析:分析错误类型及具体原因(见下方错误信息),根据错误信息选择修复方案,```" + - "2. 修复方案:(1)根据错误类型生成对应的工具重试策略(2)参数调整:明确需要修改的参数及修改方式。3. 工具重试:使用调整后的参数重新调用工具。错误信息如下,请根据报错信息重试,4.如果没有具体的错误描述信息请检查输出文件是否已经存在,若已经存在默认执行成功"; + "2. 修复方案:(1)根据错误类型生成对应的工具重试策略(2)参数调整:明确需要修改的参数及修改方式。3. 工具重试:使用调整后的参数重新调用工具。错误信息如下,请根据报错信息重试,4.如果没有具体的错误描述信息请检查输出文件是否已经存在,若已经存在默认执行成功"+ + "5.查询可能相关的知识库和帮助文档,纠正调用参数中存在的错误"; public static string SysPrompt(string gdbPath, string toolInfos) { diff --git a/ui/dockpane/TestDockpane.xaml b/ui/dockpane/TestDockpane.xaml index 53c1501..d7b5e09 100644 --- a/ui/dockpane/TestDockpane.xaml +++ b/ui/dockpane/TestDockpane.xaml @@ -29,7 +29,7 @@ - + diff --git a/ui/dockpane/TestDockpane.xaml.cs b/ui/dockpane/TestDockpane.xaml.cs index 0286d87..1628085 100644 --- a/ui/dockpane/TestDockpane.xaml.cs +++ b/ui/dockpane/TestDockpane.xaml.cs @@ -199,7 +199,7 @@ namespace LinkToolAddin.ui.dockpane { string userPrompt = PromptTestTextBox.Text; // Gateway.SendMessage(userPrompt,"qwen-max","C:/Project/test.gdb",AddReply); - Gateway.SendMessageStream(userPrompt,"qwen-max", "F:\\secondsemester\\linktool\\test\\linktooltest\\linktooltest.gdb", AddReplyStream); + Gateway.SendMessageStream(userPrompt,"qwen-max", "D:\\01_Project\\20250305_LinkTool\\20250420_AiDemoProject\\20250420_AiDemoProject.gdb", AddReplyStream); } public void AddReplyStream(MessageListItem msg)