用工具调用让模型学会联网搜索
中文exp-2499未验证
用工具调用让模型学会联网搜索
Kimi 大模型的知识来源于训练数据,无法回答时效性强的问题。下面用“搜索引擎”和“网页浏览器”两个工具,演示如何让模型自己搜索最新知识并据此作答。
###
用 JSON Schema 定义工具
人在网上查资料时,通常先打开搜索引擎(例如百度或必应)搜索内容、浏览搜索结果,再打开一个或多个结果网页获取需要的知识。把这两个动作抽象成工具,就是“搜索引擎”和“网页浏览器”——用 JSON Schema 描述后提交给 Kimi 大模型,它就能和人一样搜索并浏览网页。
工具定义使用 JSON Schema 格式编写:
JSON Schema is a vocabulary that you can use to annotate and validate JSON documents.
JSON Schema 是一种用于描述 JSON 数据格式的 JSON 文档。
我们定义以下 JSON Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
这个 JSON Schema 定义了一个 JSON Object,这个 JSON Object 中包含了一个名为 name 的字段,并且该字段的类型为 string,例如:
{
"name": "Hei"
}
通过 JSON Schema 来描述我们的工具定义,能让 Kimi 大模型更清晰和直观地知道我们的工具需要哪些参数,以及每个参数的类型和介绍。接下来让我们来定义前文提到的“搜索引擎”和“网页浏览器”这两个工具:
python
node.js
tools = [
{
"type": "function", # 约定的字段 type,目前支持 function 作为值
"function": { # 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "search", # 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": """
通过搜索引擎搜索互联网上的内容。
当你的知识无法回答用户提出的问题,或用户请求你进行联网搜索时,调用此工具。请从与用户的对话中提取用户想要搜索的内容作为 query 参数的值。
搜索结果包含网站的标题、网站的地址(URL)以及网站简介。
""", # 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { # 使用 parameters 字段来定义函数接收的参数
"type": "object", # 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["query"], # 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { # properties 中是具体的参数定义,你可以定义多个参数
"query": { # 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", # 使用 type 定义参数类型
"description": """
用户搜索的内容,请从用户的提问或聊天上下文中提取。
""" # 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
},
{
"type": "function", # 约定的字段 type,目前支持 function 作为值
"function": { # 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "crawl", # 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": """
根据网站地址(URL)获取网页内容。
""", # 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { # 使用 parameters 字段来定义函数接收的参数
"type": "object", # 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["url"], # 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { # properties 中是具体的参数定义,你可以定义多个参数
"url": { # 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", # 使用 type 定义参数类型
"description": """
需要获取内容的网站地址(URL),通常情况下从搜索结果中可以获取网站的地址。
""" # 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
}
]
const tools = [
{
"type": "function", // 约定的字段 type,目前支持 function 作为值
"function": { // 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "search", // 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": ""/*
通过搜索引擎搜索互联网上的内容。
当你的知识无法回答用户提出的问题,或用户请求你进行联网搜索时,调用此工具。请从与用户的对话中提取用户想要搜索的内容作为 query 参数的值。
搜索结果包含网站的标题、网站的地址(URL)以及网站简介。
*/, // 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { // 使用 parameters 字段来定义函数接收的参数
"type": "object", // 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["query"], // 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { // properties 中是具体的参数定义,你可以定义多个参数
"query": { // 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", // 使用 type 定义参数类型
"description": ""/*
用户搜索的内容,请从用户的提问或聊天上下文中提取。
*/ // 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
},
{
"type": "function", // 约定的字段 type,目前支持 function 作为值
"function": { // 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "crawl", // 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": ""/*
根据网站地址(URL)获取网页内容。
*/, // 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { // 使用 parameters 字段来定义函数接收的参数
"type": "object", // 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["url"], // 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { // properties 中是具体的参数定义,你可以定义多个参数
"url": { // 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", // 使用 type 定义参数类型
"description": ""/*
需要获取内容的网站地址(URL),通常情况下从搜索结果中可以获取网站的地址。
*/ // 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
}
]
在使用 JSON Schema 定义工具时,我们使用以下固定的格式来定义一个工具:
{
"type": "function",
"function": {
"name": "NAME",
"description": "DESCRIPTION",
"parameters": {
"type": "object",
"properties": {
}
}
}
}
其中,name、description、parameters.properties 由工具提供方定义,其中 description 描述了工具的具体作用、以及在什么场合需要使用工具,parameters 描述了成功调用工具所需要的具体参数,包括参数类型、参数介绍等;最终,Kimi 大模型会根据 JSON Schema 的定义,生成一个满足定义要求的 JSON Object 作为工具调用的参数(arguments)。
###
把工具注册给模型
把 search 工具提交给 Kimi 大模型,看看它能否正确调用工具:
本页示例默认使用最新模型 kimi-k3。K3 使用请求顶层 reasoning_effort 配置推理强度(支持 "low" / "high" / "max",默认 "max")。换用 kimi-k2.6 等其他模型时,只需替换 model 字段,但各模型的参数配置存在差异,详见模型参数参考。
python
node.js
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"], # 运行前请设置 MOONSHOT_API_KEY 环境变量
base_url="https://api.moonshot.cn/v1",
)
tools = [
{
"type": "function", # 约定的字段 type,目前支持 function 作为值
"function": { # 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "search", # 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": """
通过搜索引擎搜索互联网上的内容。
当你的知识无法回答用户提出的问题,或用户请求你进行联网搜索时,调用此工具。请从与用户的对话中提取用户想要搜索的内容作为 query 参数的值。
搜索结果包含网站的标题、网站的地址(URL)以及网站简介。
""", # 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { # 使用 parameters 字段来定义函数接收的参数
"type": "object", # 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["query"], # 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { # properties 中是具体的参数定义,你可以定义多个参数
"query": { # 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", # 使用 type 定义参数类型
"description": """
用户搜索的内容,请从用户的提问或聊天上下文中提取。
""" # 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
},
# {
# "type": "function", # 约定的字段 type,目前支持 function 作为值
# "function": { # 当 type 为 function 时,使用 function 字段定义具体的函数内容
# "name": "crawl", # 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
# "description": """
# 根据网站地址(URL)获取网页内容。
# """, # 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
# "parameters": { # 使用 parameters 字段来定义函数接收的参数
# "type": "object", # 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
# "required": ["url"], # 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
# "properties": { # properties 中是具体的参数定义,你可以定义多个参数
# "url": { # 在这里,key 是参数名称,value 是参数的具体定义
# "type": "string", # 使用 type 定义参数类型
# "description": """
# 需要获取内容的网站地址(URL),通常情况下从搜索结果中可以获取网站的地址。
# """ # 使用 description 描述参数以便 Kimi 大模型更好地生成参数
# }
# }
# }
# }
# }
]
completion = client.chat.completions.create(
model="kimi-k3",
messages=[
{"role": "system", "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。"},
{"role": "user", "content": "请联网搜索 Context Caching,并告诉我它是什么。"} # 在提问中要求 Kimi 大模型联网搜索
],
tools=tools, # <-- 我们通过 tools 参数,将定义好的 tools 提交给 Kimi 大模型
)
print(completion.choices[0].model_dump_json(indent=4))
const OpenAI = require("openai")
const client = new OpenAI({
apiKey: process.env.MOONSHOT_API_KEY, // 运行前请设置 MOONSHOT_API_KEY 环境变量
baseURL: "https://api.moonshot.cn/v1",
})
const tools = [
{
"type": "function", // 约定的字段 type,目前支持 function 作为值
"function": { // 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "search", // 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": ""/*
通过搜索引擎搜索互联网上的内容。
当你的知识无法回答用户提出的问题,或用户请求你进行联网搜索时,调用此工具。请从与用户的对话中提取用户想要搜索的内容作为 query 参数的值。
搜索结果包含网站的标题、网站的地址(URL)以及网站简介。
*/, // 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { // 使用 parameters 字段来定义函数接收的参数
"type": "object", // 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["query"], // 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { // properties 中是具体的参数定义,你可以定义多个参数
"query": { // 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", // 使用 type 定义参数类型
"description": ""/*
用户搜索的内容,请从用户的提问或聊天上下文中提取。
*/ // 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
},
// {
// "type": "function", // 约定的字段 type,目前支持 function 作为值
// "function": { // 当 type 为 function 时,使用 function 字段定义具体的函数内容
// "name": "crawl", // 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
// "description": """
// 根据网站地址(URL)获取网页内容。
// """, // 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
// "parameters": { // 使用 parameters 字段来定义函数接收的参数
// "type": "object", // 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
// "required": ["url"], // 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
// "properties": { // properties 中是具体的参数定义,你可以定义多个参数
// "url": { // 在这里,key 是参数名称,value 是参数的具体定义
// "type": "string", // 使用 type 定义参数类型
// "description": """
// 需要获取内容的网站地址(URL),通常情况下从搜索结果中可以获取网站的地址。
// """ // 使用 description 描述参数以便 Kimi 大模型更好地生成参数
// }
// }
// }
// }
// }
]
async function main() {
const completion = await client.chat.completions.create({
model: "kimi-k3",
messages: [
{role: "system", content: "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。"},
{role: "user", content: "请联网搜索 Context Caching,并告诉我它是什么。"} // 在提问中要求 Kimi 大模型联网搜索
],
tools: tools, // <-- 我们通过 tools 参数,将定义好的 tools 提交给 Kimi 大模型
})
console.log(JSON.stringify(completion.choices[0], null, 4))
}
main()
代码运行成功后,模型返回如下内容:
{
"finish_reason": "tool_calls",
"message": {
"content": "",
"role": "assistant",
"tool_calls": [
{
"id": "search:0",
"function": {
"arguments": "{\n \"query\": \"Context Caching\"\n}",
"name": "search"
},
"type": "function"
}
]
}
}
finish_reason 为 tool_calls 表示本次返回的不是模型回复,而是模型选择执行工具——可以通过 finish_reason 的值判断当前回复是否是一次工具调用。
此时 message 中的 content 为空,因为模型还在执行 tool_calls,尚未生成面向用户的回复;新增的 tool_calls 字段是一个列表,包含本次需要调用的所有工具调用信息——这说明 模型可以一次性选择多个工具进行调用,可以是多个不同的工具,也可以是相同工具使用不同参数进行调用 。tool_calls 中每个元素都代表一次工具调用:模型为每次调用生成唯一的 id,用 function.name 表明工具函数名称,把执行参数放在 function.arguments 中(arguments 是合法的、被序列化的 JSON Object;type 目前是固定值 function)。
接下来,用模型生成的工具调用参数去执行具体的工具。
###
执行工具并回传结果
Kimi 大模型不会替你执行工具——收到模型生成的参数后,需要由你的应用自行执行。为什么模型不自己执行工具?设想一个典型场景: 你向用户提供一个基于 Kimi 大模型的智能机器人,在这个场景有三个角色:用户、机器人、Kimi 大模型。用户向机器人提问,机器人调用 Kimi 大模型 API,并将 API 的结果返回给用户。当使用 tool_calls 时,用户向机器人提问,机器人带着 tools 调用 Kimi API,Kimi 大模型返回 tool_calls 参数,机器人执行完 tool_calls,将结果再次提交给 Kimi API,Kimi 大模型生成返回给用户的消息(finish_reason=stop),此时机器人才会把消息返回给用户。 整个 tool_calls 过程对用户而言是透明、隐式的:用户并不直接“看到”工具调用,只看到机器人返回的最终回复。
下面的完整示例以“机器人”的视角执行模型返回的 tool_calls,演示工具执行循环:
python
node.js
from typing import *
import json
import httpx
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"], # 运行前请设置 MOONSHOT_API_KEY 环境变量
base_url="https://api.moonshot.cn/v1",
)
tools = [
{
"type": "function", # 约定的字段 type,目前支持 function 作为值
"function": { # 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "search", # 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": """
通过搜索引擎搜索互联网上的内容。
当你的知识无法回答用户提出的问题,或用户请求你进行联网搜索时,调用此工具。请从与用户的对话中提取用户想要搜索的内容作为 query 参数的值。
搜索结果包含网站的标题、网站的地址(URL)以及网站简介。
""", # 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { # 使用 parameters 字段来定义函数接收的参数
"type": "object", # 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["query"], # 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { # properties 中是具体的参数定义,你可以定义多个参数
"query": { # 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", # 使用 type 定义参数类型
"description": """
用户搜索的内容,请从用户的提问或聊天上下文中提取。
""" # 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
},
{
"type": "function", # 约定的字段 type,目前支持 function 作为值
"function": { # 当 type 为 function 时,使用 function 字段定义具体的函数内容
"name": "crawl", # 函数的名称,请使用英文大小写字母、数据加上减号和下划线作为函数名称
"description": """
根据网站地址(URL)获取网页内容。
""", # 函数的介绍,在这里写上函数的具体作用以及使用场景,以便 Kimi 大模型能正确地选择使用哪些函数
"parameters": { # 使用 parameters 字段来定义函数接收的参数
"type": "object", # 固定使用 type: object 来使 Kimi 大模型生成一个 JSON Object 参数
"required": ["url"], # 使用 required 字段告诉 Kimi 大模型哪些参数是必填项
"properties": { # properties 中是具体的参数定义,你可以定义多个参数
"url": { # 在这里,key 是参数名称,value 是参数的具体定义
"type": "string", # 使用 type 定义参数类型
"description": """
需要获取内容的网站地址(URL),通常情况下从搜索结果中可以获取网站的地址。
""" # 使用 description 描述参数以便 Kimi 大模型更好地生成参数
}
}
}
}
}
]
def search_impl(query: str) -> List[Dict[str, Any]]:
"""
search_impl 使用搜索引擎对 query 进行搜索,目前主流的搜索引擎(例如 Bing)都提供了 API 调用方式,你可以自行选择
你喜欢的搜索引擎 API 进行调用,并将返回结果中的网站标题、网站链接、网站简介信息放置在一个 dict 中返回。
这里只是一个简单的示例,你可能需要编写一些鉴权、校验、解析的代码。
"""
r = httpx.get("https://your.search.api", params={"query": query})
return r.json()
def search(arguments: Dict[str, Any]) -> Any:
query = arguments["query"]
result = search_impl(query)
return {"result": result}
def crawl_impl(url: str) -> str:
"""
crawl_url 根据 url 获取网页上的内容。
这里只是一个简单的示例,在实际的网页抓取过程中,你可能需要编写更多的代码来适配复杂的情况,例如异步加载的数据等;同时,在获取
网页内容后,你可以根据自己的需要对网页内容进行清洗,只保留文本或移除不必要的内容(例如广告信息等)。
"""
r = httpx.get(url)
return r.text
def crawl(arguments: dict) -> str:
url = arguments["url"]
content = crawl_impl(url)
return {"content": content}
复制后粘贴到 AI 对话框发送,本次对话全程生效
出处:Kimi/Moonshot 官方提示词指南 · platform.moonshot.cn/docs/guide/use-kimi-api-to-complete-tool-calls · 可信度 S · 标签:中文 / 提示词工程 / 防幻觉 / 角色扮演 / 少样本 怎么用(对话型)复制后粘贴到对话框发送,本次对话全程生效。想长期用:支持自定义指令的产品(设置→个性化)可设为默认。