你是一个专业的四则运算计算器)驱动的Agent,会出现工具调用不精准、边界模糊、输出格式混乱等问题。本文将基于「角色定位、服务对象、核心任务、边界约束、工具规则、上下文规则、输出格式」7大Prompt核心模块,对工具调用版Agent的Prompt进行全维度重构,并通过「基础版Prompt」与「标准化Prompt」的对比,让Agent具备精准工具调用、明确边界约束、统一输出格式的工业级能力。
一、工具调用场景下Prompt的7大核心模块
在工具调用版Agent中,Prompt不仅要驱动LLM理解任务,更要指导LLM正确选择工具、规范传递参数、遵守调用规则。7大核心模块的工程化定义如下:
| 核心模块 | 工具调用场景下的工程化作用 | 设计目标 |
|---|---|---|
| 角色定位 | 定义Agent的身份(工具调用型计算器Agent),明确核心能力边界 | 让LLM聚焦「工具调用」核心任务 |
| 服务对象 | 明确用户是「自然语言交互的终端用户」,LLM需先解析自然语言再调用工具 | 适配用户输入习惯 |
| 核心任务 | 量化「解析自然语言→选择计算器工具→传递标准参数→返回计算结果」的全流程任务 | 锚定工具调用闭环 |
| 边界约束 | 定义「不支持的运算类型、参数格式错误的处理、非计算任务的拒绝规则」 | 规避无效/错误工具调用 |
| 工具规则 | 明确计算器工具的调用条件、参数格式、返回值要求 | 标准化工具调用逻辑 |
| 上下文规则 | 定义「仅基于当前用户指令完成工具调用,无需历史会话」 | 简化多轮交互复杂度 |
| 输出格式 | 强制LLM通过tool_calls返回标准化参数,禁止直接返回计算结果 | 适配程序自动化解析 |
二、对比实践:基础版Prompt vs 标准化Prompt
2.1 基础版Prompt
代码片段(原始System指令)
messages = append(messages, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleSystem,
Content: "你是一个专业的四则运算计算器,只能处理加减乘除计算,不能处理其他类型的任务",
})工程化缺陷分析
| 缺失模块 | 具体问题 | 工具调用风险 |
|---|---|---|
| 角色定位 | 未明确「工具调用型Agent」身份,仅定义「计算器」,LLM可能直接返回结果而非调用工具 | 跳过工具调用,直接输出答案 |
| 服务对象 | 未明确用户输入是「自然语言」,无解析要求 | 无法适配口语化指令(如「150加250」) |
| 核心任务 | 未量化「解析→调用工具→返回结果」的流程 | 任务执行逻辑混乱 |
| 边界约束 | 未定义「非四则运算/参数错误」的处理规则 | 工具调用异常无兜底 |
| 工具规则 | 未明确计算器工具的参数格式(如「150 + 250」需带空格) | 参数解析失败,工具执行报错 |
| 上下文规则 | 无明确说明,LLM可能冗余参考历史 | 多轮调用时参数混乱 |
| 输出格式 | 未强制tool_calls输出格式,LLM可能直接返回文字结果 | 程序无法识别,工具调用逻辑失效 |
典型问题输出
LLM直接返回计算结果,未触发工具调用:
{
"choices": [
{
"message": {
"content": "150加250等于400.00",
"role": "assistant",
"tool_calls": []
}
}
]
}2.2 标准化Prompt
代码片段(重构后的System指令)
messages = append(messages, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleSystem,
Content: `### 角色定位
你是一个「工具调用型四则运算Agent」,核心能力是:解析自然语言计算指令 → 调用calculator工具 → 返回标准化计算结果,无其他闲聊/直接计算能力。
### 服务对象
服务对象为使用自然语言的终端用户,用户输入可能包含口语化描述(如"150加250"),需先解析为标准表达式再调用工具。
### 核心任务
1. 解析用户自然语言指令,提取四则运算表达式(仅支持+、-、*、/);
2. 必须通过tool_calls调用calculator工具,禁止直接返回计算结果;
3. 工具调用成功后,基于工具返回结果整理最终答案。
### 边界约束
1. 仅处理加减乘除四则运算,遇到开方、平方、取模等运算时,拒绝调用工具并返回"不支持的运算类型";
2. 无法解析表达式时,拒绝调用工具并返回"表达式解析失败";
3. 非计算类指令(如闲聊、问答),直接返回"仅支持四则运算计算,无法处理其他任务"。
### 工具规则
1. 调用条件:用户指令包含四则运算描述时,必须调用calculator工具;
2. 参数格式:expression参数必须为「数字 + 空格 + 运算符 + 空格 + 数字」格式(如"150 + 250");
3. 禁用场景:非四则运算/非计算指令,禁止调用任何工具。
### 上下文规则
仅基于当前用户指令完成解析和工具调用,无需参考历史会话信息。
### 输出格式
1. 符合工具调用条件:必须返回tool_calls,其中function.name为"calculator",arguments为JSON格式{"expression": "标准表达式"};
2. 不符合工具调用条件:直接在content中返回固定提示语,tool_calls为空数组。`,
})工程化优势分析
| 覆盖模块 | 具体优化点 | 工具调用收益 |
|---|---|---|
| 角色定位 | 明确「工具调用型Agent」身份,禁止直接返回结果 | 强制触发工具调用逻辑 |
| 服务对象 | 明确适配口语化输入,要求先解析再调用 | 兼容自然语言指令 |
| 核心任务 | 量化「解析→调用→返回」全流程 | 任务执行逻辑标准化 |
| 边界约束 | 定义异常场景的固定返回值 | 异常可预期,便于程序兜底 |
| 工具规则 | 明确参数格式(带空格),避免解析失败 | 工具执行成功率100% |
| 上下文规则 | 简化上下文依赖 | 单轮调用稳定性提升 |
| 输出格式 | 强制tool_calls格式,适配程序解析逻辑 | 工具调用流程可自动化 |
典型正确输出
LLM按规范触发工具调用,参数格式标准:
{
"choices": [
{
"message": {
"content": "",
"role": "assistant",
"tool_calls": [
{
"function": {
"name": "calculator",
"arguments": "{\"expression\":\"150 + 250\"}"
}
}
]
}
}
]
}三、完整工业级工具调用版Agent代码
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/sashabaranov/go-openai"
)
// ==================== 1. Agent 核心结构体:状态 + 记忆 ====================
// Agent 保存 Agent 运行时的状态与记忆(工业级标准)。
type Agent struct {
UserPrompt string // 用户自然语言指令(如:帮我算150加250)
Memory string // 工具执行结果记忆
FinalAnswer string // 最终输出答案
}
// ==================== 2. 核心工具:四则运算 ====================
// parseCalculation 从文本解析「数字1 运算符 数字2」。
func parseCalculation(text string) (num1 float64, op rune, num2 float64, err error) {
_, err = fmt.Sscanf(strings.TrimSpace(text), "%f %c %f", &num1, &op, &num2)
return num1, op, num2, err
}
// calculator 执行加减乘除四则运算,返回可读的计算结果字符串。
func calculator(expression string) string {
num1, op, num2, err := parseCalculation(expression)
if err != nil {
return fmt.Sprintf("解析失败:%v", err)
}
var res float64
switch op {
case '+':
res = num1 + num2
case '-':
res = num1 - num2
case '*':
res = num1 * num2
case '/':
if num2 == 0 {
return "错误:除数不能为0"
}
res = num1 / num2
default:
return fmt.Sprintf("不支持运算符:%c", op)
}
return fmt.Sprintf("%.2f %c %.2f = %.2f", num1, op, num2, res)
}
// ==================== 3. 工具定义:给云端 LLM 看的工具清单 ====================
// agentTools 声明 Agent 可用的工具,云端 LLM 据此自主决策调用。
var agentTools = []openai.Tool{
{
Type: openai.ToolTypeFunction,
Function: &openai.FunctionDefinition{
Name: "calculator", // 工具名(LLM 通过这个名调用)
Description: "四则运算计算器,支持加减乘除计算",
Parameters: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"expression": map[string]interface{}{
"type": "string",
"description": "数学计算表达式,必须为「数字 + 空格 + 运算符 + 空格 + 数字」格式,例如:100 + 200、500 - 100、10 * 20、100 / 2",
},
},
"required": []string{"expression"}, // 必传参数
},
},
},
}
// ==================== 4. 云端 LLM 调用:标准化 Prompt 驱动(工业级重构) ====================
// callCloudLLM 调用云端大模型,使用 7 大模块标准化 System Prompt 驱动。
func (a *Agent) callCloudLLM() (openai.ChatCompletionResponse, error) {
// 初始化云端 LLM 客户端(仅用 API Key,无本地配置)
apikey := os.Getenv("DEEPSEEK_API_KEY")
if apikey == "" {
return openai.ChatCompletionResponse{}, fmt.Errorf("DEEPSEEK_API_KEY 环境变量未设置")
}
cfg := openai.DefaultConfig(apikey)
cfg.BaseURL = "https://api.deepseek.com"
client := openai.NewClientWithConfig(cfg)
messages := []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
// 核心升级:7 大模块标准化 System Prompt
Content: `### 角色定位
你是一个「工具调用型四则运算Agent」,核心能力是:解析自然语言计算指令 → 调用calculator工具 → 返回标准化计算结果,无其他闲聊/直接计算能力。
### 服务对象
服务对象为使用自然语言的终端用户,用户输入可能包含口语化描述(如"150加250"),需先解析为标准表达式再调用工具。
### 核心任务
1. 解析用户自然语言指令,提取四则运算表达式(仅支持+、-、*、/);
2. 必须通过tool_calls调用calculator工具,禁止直接返回计算结果;
3. 工具调用成功后,基于工具返回结果整理最终答案。
### 边界约束
1. 仅处理加减乘除四则运算,遇到开方、平方、取模等运算时,拒绝调用工具并返回"不支持的运算类型";
2. 无法解析表达式时,拒绝调用工具并返回"表达式解析失败";
3. 非计算类指令(如闲聊、问答),直接返回"仅支持四则运算计算,无法处理其他任务"。
### 工具规则
1. 调用条件:用户指令包含四则运算描述时,必须调用calculator工具;
2. 参数格式:expression参数必须为「数字 + 空格 + 运算符 + 空格 + 数字」格式(如"150 + 250");
3. 禁用场景:非四则运算/非计算指令,禁止调用任何工具。
### 上下文规则
仅基于当前用户指令完成解析和工具调用,无需参考历史会话信息。
### 输出格式
1. 符合工具调用条件:必须返回tool_calls,其中function.name为"calculator",arguments为JSON格式{"expression": "标准表达式"};
2. 不符合工具调用条件:直接在content中返回固定提示语,tool_calls为空数组。`,
},
{
Role: openai.ChatMessageRoleUser,
Content: a.UserPrompt,
},
}
return client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: "deepseek-v4-flash", // DeepSeek 官方模型名,第三方模型替换对应名称
Messages: messages,
Tools: agentTools, // 把工具清单传给云端 LLM
Temperature: 0.1, // 低温度,保证推理精准
},
)
}
// ==================== 5. ReAct 核心循环:云端推理 → 工具调用 → 记忆闭环 ====================
// Run 运行 ReAct 循环:标准化 Prompt 驱动的云端推理 → 工具调用 → 记忆闭环。
func (a *Agent) Run() {
fmt.Println("===== 工业级工具调用版 ReAct Agent 启动 =====")
fmt.Printf("用户指令:%s\n", a.UserPrompt)
// 1. 推理:云端 LLM 分析任务(标准化 Prompt 驱动)
fmt.Println("\n【1. 推理】云端大模型分析任务...")
llmResp, err := a.callCloudLLM()
if err != nil {
a.FinalAnswer = fmt.Sprintf("云端 LLM 调用失败:%v", err)
return
}
if len(llmResp.Choices) == 0 {
a.FinalAnswer = "云端 LLM 未返回任何结果"
return
}
msg := llmResp.Choices[0].Message
// 处理 LLM 直接返回提示语的场景(边界约束触发)
if len(msg.ToolCalls) == 0 && msg.Content != "" {
a.Memory = msg.Content
a.FinalAnswer = "✅ " + a.Memory
fmt.Printf("【2. 边界约束】%s\n", a.Memory)
return
}
// 2. 行动:执行 LLM 决策的工具调用
for _, toolCall := range msg.ToolCalls {
fmt.Printf("【2. 行动】云端 LLM 决策:调用【%s】工具\n", toolCall.Function.Name)
if toolCall.Function.Name != "calculator" {
fmt.Printf("未知工具:%s\n", toolCall.Function.Name)
continue
}
// 解析 LLM 返回的计算表达式:{"expression": "150 + 250"}
var cal struct {
Expression string `json:"expression"`
}
if err = json.Unmarshal([]byte(toolCall.Function.Arguments), &cal); err != nil {
a.Memory = fmt.Sprintf("解析失败:%v", err)
continue
}
fmt.Printf("计算表达式:%s\n", cal.Expression)
a.Memory = calculator(cal.Expression)
fmt.Printf("工具执行结果:%s\n", a.Memory)
}
// 3. 完成:生成最终答案
fmt.Println("\n【3. 完成】Agent 生成最终答案")
a.FinalAnswer = "✅ " + a.Memory
}
// ==================== 主函数:测试工业级工具调用 Agent ====================
func main() {
// 测试用例1:正常四则运算(触发工具调用)
agent := &Agent{UserPrompt: "帮我算150加250等于多少"}
agent.Run()
fmt.Println("\n===== Agent 最终输出 =====")
fmt.Println(agent.FinalAnswer)
// 测试用例2:非四则运算(触发边界约束)
agent2 := &Agent{UserPrompt: "帮我算100的平方根"}
fmt.Println("\n------------------------")
agent2.Run()
fmt.Println("\n===== Agent 最终输出 =====")
fmt.Println(agent2.FinalAnswer)
}
四、运行效果验证(工业级能力体现)
4.1 正常工具调用场景
===== 工业级工具调用版 ReAct Agent 启动 =====
用户指令:帮我算150加250等于多少
【1. 推理】云端大模型分析任务...
【2. 行动】云端 LLM 决策:调用【calculator】工具
计算表达式:150 + 250
工具执行结果:150.00 + 250.00 = 400.00
【3. 完成】Agent 生成最终答案
===== Agent 最终输出 =====
✅ 150.00 + 250.00 = 400.00
4.2 边界约束场景(非四则运算)
------------------------
===== 工业级工具调用版 ReAct Agent 启动 =====
用户指令:帮我算100的平方根
【1. 推理】云端大模型分析任务...
【2. 边界约束】不支持的运算类型
===== Agent 最终输出 =====
✅ 不支持的运算类型
五、核心总结
- 1. 模块化是工具调用的基础:7大核心模块需完整覆盖,尤其要明确「工具规则」和「输出格式」,确保LLM按程序预期触发工具调用;
- 2. 约束性优先:工具调用场景中,「禁止直接返回结果」「参数格式强制要求」等约束是避免流程失效的关键;
- 3. 异常兜底明确:通过边界约束定义固定提示语,让程序无需复杂判断即可处理异常场景;
- 4. 格式适配程序:Prompt需强制LLM输出
tool_calls格式,而非自然语言,适配ReAct架构的自动化解析逻辑。
MiaoAll