BuildInstructions 生成 system prompt 块,教导模型按 {...} 协议输出工具调用。tools 为空时返回 ""。 协议文本与 保持一致,但使用英语(目标用户以英文/中文为主)。
(tools []official.Tool, toolChoice *official.ToolChoice)
| 13 | // 协议输出工具调用。tools 为空时返回 ""。 |
| 14 | // 协议文本与 保持一致,但使用英语(目标用户以英文/中文为主)。 |
| 15 | func BuildInstructions(tools []official.Tool, toolChoice *official.ToolChoice) string { |
| 16 | if len(tools) == 0 { |
| 17 | return "" |
| 18 | } |
| 19 | var sb strings.Builder |
| 20 | sb.WriteString("# TOOLS AVAILABLE\n") |
| 21 | sb.WriteString("You have access to the following tools. Use the EXACT tool name from the list below — do NOT rename, abbreviate or invent names.\n\n") |
| 22 | sb.WriteString(compactToolsPrompt(tools)) |
| 23 | sb.WriteString("\n\n# TOOL CALLING FORMAT (MANDATORY)\n") |
| 24 | sb.WriteString("To call a tool, output a JSON object wrapped EXACTLY in these tags:\n") |
| 25 | sb.WriteString("<tool_call>\n") |
| 26 | sb.WriteString(`{"name": "tool_name", "arguments": {"param_name": "value"}}`) |
| 27 | sb.WriteString("\n</tool_call>\n\n") |
| 28 | sb.WriteString("EXAMPLE OF MULTIPLE TOOL CALLS (replace <tool_name> with a REAL name from the list above):\n") |
| 29 | sb.WriteString("<tool_call>\n") |
| 30 | sb.WriteString(`{"name": "<tool_name>", "arguments": {"arg1": "value1"}}`) |
| 31 | sb.WriteString("\n</tool_call>\n") |
| 32 | sb.WriteString("<tool_call>\n") |
| 33 | sb.WriteString(`{"name": "<tool_name>", "arguments": {"arg1": "value2"}}`) |
| 34 | sb.WriteString("\n</tool_call>\n\n") |
| 35 | sb.WriteString("CRITICAL RULES:\n") |
| 36 | sb.WriteString("0. Use ONLY the EXACT tool names listed under TOOLS AVAILABLE. Never rename, abbreviate or invent names. If the available tool is \"read\", do NOT call \"read_file\". Copy the name character-for-character.\n") |
| 37 | sb.WriteString("1. ONLY use the tags above for tool calling. NEVER output raw JSON without tags.\n") |
| 38 | sb.WriteString("2. You can call multiple tools by emitting multiple <tool_call> blocks consecutively.\n") |
| 39 | sb.WriteString("3. Do NOT output any other text after your <tool_call> blocks. Wait for the tool response.\n") |
| 40 | sb.WriteString("4. The JSON inside the tags MUST be valid and include the 'arguments' field.\n") |
| 41 | sb.WriteString("5. If you need to use a tool, do it IMMEDIATELY without preamble.\n") |
| 42 | sb.WriteString("6. DO NOT use your internal/native Python tool, Advanced Data Analysis, or Code Interpreter. They run in a remote sandbox on your servers and have NO access to the user's workspace. You MUST use ONLY the custom tools listed under TOOLS AVAILABLE (like 'glob', 'read', 'grep', or 'bash').\n") |
| 43 | if forced := toolChoice.ForcedFunctionName(); forced != "" { |
| 44 | fmt.Fprintf(&sb, "\nCRITICAL: You MUST call the tool %q in this response. Do not call any other tool, and do not produce a final answer without calling it first.\n", forced) |
| 45 | } else if toolChoice != nil && toolChoice.IsForcedNone() { |
| 46 | sb.WriteString("\nCRITICAL: The user has DISABLED tool calling in this request. Do not emit any <tool_call> blocks. Just answer in plain text.\n") |
| 47 | } |
| 48 | return sb.String() |
| 49 | } |
| 50 | |
| 51 | // compactToolsPrompt 把工具列表渲染成人可读的多行描述。 |
| 52 | func compactToolsPrompt(tools []official.Tool) string { |