基于提示词工程和MCP构建垂直Agent应用
1.前言
今年在大模型应用领域很流行深度研究,中间大模型会按需调用各种工具,比如 网页搜索、天气查询和生成文档等。为了实现这种复杂的需求,需要综合利用提示词工程、MCP工具和多轮调用等技术。
在垂直行业,内部有很多的API,为了解决特定业务的痛点,提升效率,可以把内部的多个服务包装成 mcp工具,再利用提示词进行场景编排,让大模型发挥更大的作用。同时,也可以不编排场景,直接利用大模型的自主规划能力调用 mcp工具,灵活性很强。
2.构造System Prompt
这是构建 agent最重要一步,没有之一。
这里需要充分使用提示词工程中的技巧,例如 提供当前时间、设置角色、行业信息、任务背景和执行步骤等。
下面将会对提示词进行拆解:
-
当前时间
样栗:
现在的时间是:2025年8月15日 21:50:05
大模型本身是没有时间信息的,当需要调用参数包含日期的 mcp工具时,大模型就能根据现在的时间推断出特定的时间,常见的有 今天、昨天、上周、上个月等。
-
角色设定
样栗:
你是一个大数据集群的任务分析智能体,专注于保障Hadoop平台上任务的稳定运行、效率优化、根因分析、故障原因分析并提供修复建议。你具备以下核心能力:
- 结构化问题拆解与规划能力
- 多轮工具调用能力
- 任务运行日志分析能力
- 任务依赖链分析能力
在这里给大模型设置了身份信息,并给出了对应环境背景,能够让大模型更加聚焦于特定领域,最后生成的答复会更准确。
-
核心原则
样栗:
你必须严格遵循以下原则和流程,任何违反都将导致任务失败:
-
流程铁律: 严格按照
1. 问题解析 → 2. 调用工具 → 3. 总结输出
的顺序执行,不得跳过或错序,不得重复进行问题分析和调用工具 -
规划驱动: 分析用户问题,确定要调用哪些工具,以及工具调用的顺序
-
工具调用: 不得重复调用同一个工具,也不得调用未规划好的工具
这里是在对大模型的行为进行约束,避免出现答非所问和减少幻觉,特别是在工具调用上,要求他一定要用提供的工具,不能凭空捏造。
-
-
执行步骤
这里需要按细分场景,动态生成执行步骤,在实际落地过程中,这一步相当关键,会极大的影响工具调用的准确性和稳定性。
这里以分析 hadoop失败任务场景为例:
以下是一个完整的失败任务分析案例,展示了如何遵循流程完成一次分析。请严格模仿此案例的交互模式。
## 任务:DWD_WEIO_HJ_2025_D,日期 20250812 失败的原因是什么
### 第1步:问题解析
用户在询问任务:
DWD_WEIO_HJ_2025_D
,批次:20250812
为什么失败。为了回答这个问题,我需要调用工具收集任务相关信息,分析总结任务失败的原因,并提供处置建议。### 第2步:调用任务执行状态查询工具
输出下面的内容:
<tool_use>
query_task_status
{“taskId”: “DWD_WEIO_HJ_2025_D”, “date”: “20250812”}
</tool_use>
用户回复:
{“taskId”: “DWD_WEIO_HJ_2025_D”, “date”: “20250812”,“status”:“失败”}
如果任务确实失败了,则执行下面的步骤,反之提示用户
### 第3步:调用任务错误日志查询工具
输出下面的内容:
<tool_use>
fetch_task_error_log
{“taskId”: “DWD_WEIO_HJ_2025_D”, “date”: “20250812”}
</tool_use>
用户回复:
{“taskId”: “DWD_WEIO_HJ_2025_D”, “date”: “20250812”, “errorLog”:"EXECUTION FAILED: Task MAPRED-SPARK error SparkException: [Error 1] Job aborted due to stage failure: Task 0 in stage 9782202.0 failed 4 times, most recent failure: Lost task 0.3 in stage 9782202.0 : java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Invalid Value ““1"” for decimal(3,3)”}
可能用到的知识如下:
{“日志”:“org.apache.hadoop.hive.ql.metadata.HiveException: Invalid Value”,“处置建议”:“确认Hive表中列的类型和实际数据是否一致”}
### 第3步:总结输出
原因分析:
查询到
DWD_WEIO_HJ_2025_D
的失败日志如下:>EXECUTION FAILED: Task MAPRED-SPARK error SparkException: [Error 1] Job aborted due to stage failure: Task 0 in stage 9782202.0 failed 4 times, most recent failure: Lost task 0.3 in stage 9782202.0 : java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Invalid Value "“1"” for decimal(3,3)
从报错信息来看,任务在执行时碰到了数据无法插入到hive表的问题,提示无效的值。
处置建议:
-
确认Hive表中列的类型和实际数据是否一致
-
调整hive表列的类型或者对数据做二次转换
-
联系Hadoop集群管理员协助处理
上面
可能用到的知识
是从知识库中根据任务错误日志召回的内容,对于增强大模型回复的可操作性具有重要作用。其次上面比较重要的就是工具调用的说明,调用哪些工具、顺序是什么样的,大模型是擅于模仿的,在失败任务分析这个细分场景,大模型的表现就会比较符合预期。 -
-
工具清单
这里的mcp工具以 xml格式提供给大模型,在实际落地过程中证明比较可靠。
样栗:
你可以使用以下工具,工具信息通过xml格式描述:
<tool_list>
<tool_use>
query_task_status
{“taskId”: “String”, “date”: “String”}
</tool_use>
<tool_use>
fetch_task_error_log
{“taskId”: “String”, “date”: “String”}
</tool_use>
</tool_list>
选择调用工具时,用以下格式:
<tool_use>
<name>工具名称</name><arguments>参数</arguments>
</tool_use>
如果调用工具,用户将按以下格式回应:
<tool_use_result>
工具名称
调用结果
</tool_use_result>
工具清单也建议动态生成,根据细分场景提供对应的工具,降低大模型选错工具的概率。
-
回答格式
样栗:
输出内容要包含下面的信息:
- 原因分析,任务失败日志和关键词需要高亮显示,依赖任务要用表格进行展示
- 修复建议,先给出具体的修复建议,最后给出联系Hadoop集群管理员
这个按需就行调整即可,主要是规范大模型回复格式。
-
注意事项
样栗:
调用工具完成后,每次观察进行反思,直到获得足够信息无需继续使用工具即可回答问题,再进行总结,输出原因分析和处置建议,整体回答要简洁
把需要给大模型强调的事项可以放到最后这个章节。
上面提到执行步骤
和工具清单
这两步需要动态生成,思路就是先用大模型做意图识别,确认用户问题指向的细分场景,然后生成该场景对应的执行步骤和工具清单即可。
3.构造完整Messages
调用大模型接口前,需要构造消息数组,第一条则是上一步构造的 system prompt:
system_prompt = "xxx"
messages = []
messages.append({"role": "system", "content": system_prompt})
如果有历史对话,则先把历史对话添加进去,最后添加用户本次的问题。
这里需要注意要把历史对话里面的 system prompt剔除,或者在保存的时候就去除。
messages.append({"role": "user", "content": query})
补充:
这里的 role是角色的意思,有 system、user、assistant三种,user就代表用户。
4.解析工具调用请求
在构造 system prompt时给大模型说明了,选择工具时回复下面的内容:
<tool_use><name>fetch_task_error_log</name><arguments>{"taskId": "DWD_WEIO_HJ_2025_D", "date": "20250812"}</arguments>
</tool_use>
解析完这个 xml后使用 mcp客户端调用对应的工具即可。
mcp 客户端没有特别要求,比如 使用 langchain提供的就行。
5.回传工具调用结果
使用 mcp客户端完成工具调用后,需要把结果按下面的格式进行组装,和 system prompt格式相呼应:
工具调用结果:
<tool_use_result><name>fetch_task_error_log</name><result>{"taskId": "DWD_WEIO_HJ_2025_D", "date": "20250812", "errorLog":"EXECUTION FAILED: Task MAPRED-SPARK error SparkException: [Error 1] Job aborted due to stage failure: Task 0 in stage 9782202.0 failed 4 times, most recent failure: Lost task 0.3 in stage 9782202.0 : java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Invalid Value ""1"" for decimal(3,3)"}</result>
</tool_use_result>可能用到的知识如下:
{"日志":"org.apache.hadoop.hive.ql.metadata.HiveException: Invalid Value","处置建议":"确认Hive表中列的类型和实际数据是否一致"}
然后把大模型回复和工具调用结果添加到第3步的消息数组末尾,如下:
messages.append({"role": "assistant", "content": tool_call})
messages.append({"role": "user", "content": tool_result})
最后,使用新的消息数组再次调用大模型对话接口。
6.最终效果
针对 hadoop任务一直处于已创建不运行的细分场景,实现效果如下:
可以看到上面大模型首先对问题进行分析,规划要调用的工具,这个场景正常会用到查询依赖任务和失败任务日志两个工具,然后再实际调用工具拿到额外信息。
这里总结下多轮工具调用的原理:
迭代 解析工具、调用 mcp工具和回传工具结果这个流程,直到把该场景需要的多个工具全部调用完成,大模型总结并输出。
在实际落地过程中,发现大模型有循环调用工具的情况,这一点光靠提示词无法避免,需要在代码里做异常处理。
7.总结
本文以 hadoop任务分析为业务场景,重点介绍了如何构造 system prompt和 mcp工具的使用,其中根据细分场景动态生成提示词和工具列表、工具的多轮调用是重点。通过工具的多轮调用才能拿到足够多的信息,解决复杂业务问题,创造价值。