提示词库/任务指令/search 工具的具体实现,这里我们只需要返回参数即可 search 工具的具体实现,这里我们只需要返回参数即可
中文exp-2446未验证
def search_impl(arguments: Dict[str, Any]) -> Any:
"""
在使用 Moonshot AI 提供的 search 工具的场合,只需要原封不动返回 arguments 即可,
不需要额外的处理逻辑。
但如果你想使用其他模型,并保留联网搜索的功能,那你只需要修改这里的实现(例如调用搜索
和获取网页内容等),函数签名不变,依然是 work 的。
这最大程度保证了兼容性,允许你在不同的模型间切换,并且不需要对代码有破坏性的修改。
"""
return arguments
def chat(messages) -> Choice:
completion = client.chat.completions.create(
model="kimi-k3",
messages=messages,
max_tokens=32768,
tools=[
{
"type": "builtin_function", # <-- 使用 builtin_function 声明 $web_search 函数,请在每次请求都完整地带上 tools 声明
"function": {
"name": "$web_search",
},
}
]
)
return completion.choices[0]
def main():
messages = [
{"role": "system", "content": "你是 Kimi。"},
]
# 初始提问
messages.append({
"role": "user",
"content": "请搜索 Moonshot AI Context Caching 技术,并告诉我它是什么。"
})
finish_reason = None
while finish_reason is None or finish_reason == "tool_calls":
choice = chat(messages)
finish_reason = choice.finish_reason
if finish_reason == "tool_calls": # <-- 判断当前返回内容是否包含 tool_calls
messages.append(choice.message) # <-- 我们将 Kimi 大模型返回给我们的 assistant 消息也添加到上下文中,以便于下次请求时 Kimi 大模型能理解我们的诉求
for tool_call in choice.message.tool_calls: # <-- tool_calls 可能是多个,因此我们使用循环逐个执行
tool_call_name = tool_call.function.name
tool_call_arguments = json.loads(tool_call.function.arguments) # <-- arguments 是序列化后的 JSON Object,我们需要使用 json.loads 反序列化一下
if tool_call_name == "$web_search":
tool_result = search_impl(tool_call_arguments)
else:
tool_result = f"Error: unable to find tool by name '{tool_call_name}'"
# 使用函数执行结果构造一个 role=tool 的 message,以此来向模型展示工具调用的结果;
# 注意,我们需要在 message 中提供 tool_call_id 和 name 字段,以便 Kimi 大模型
# 能正确匹配到对应的 tool_call。
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": tool_call_name,
"content": json.dumps(tool_result), # <-- 我们约定使用字符串格式向 Kimi 大模型提交工具调用结果,因此在这里使用 json.dumps 将执行结果序列化成字符串
})
print(choice.message.content) # <-- 在这里,我们才将模型生成的回复返回给用户
if __name__ == '__main__':
main()
const openai = require('openai'); // 需要安装 openai 库
const client = new openai.OpenAI({
apiKey: process.env.MOONSHOT_API_KEY,
baseURL: "https://api.moonshot.cn/v1",
});
const tools = [
{
"type": "builtin_function",
"function": {
"name": "$web_search",
},
}
];
function search_impl(args) {
return args
}
const messages = [
{ "role": "system", "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。" },
{ "role": "user", "content": "请搜索2024年10月8日的中國A股指数是多少?" } // 在提问中要求 Kimi 大模型联网搜索
];
let finishReason = null;
async function main() {
while (finishReason === null || finishReason === "tool_calls") {
const completion = await client.chat.completions.create({
model: "kimi-k3",
messages: messages,
tools: tools // <-- 我们通过 tools 参数,将定义好的 tools 提交给 Kimi 大模型
});
const choice = completion.choices[0];
console.log(choice);
finishReason = choice.finish_reason;
console.log(finishReason);
if (finishReason === "tool_calls") { // <-- 判断当前返回内容是否包含 tool_calls
messages.push(choice.message); // <-- 我们将 Kimi 大模型返回给我们的 assistant 消息也添加到上下文中,以便于下次请求时 Kimi 大模型能理解我们的诉求
for (const toolCall of choice.message.tool_calls) { // <-- tool_calls 可能是多个,因此我们使用循环逐个执行
const tool_call_name = toolCall.function.name;
const tool_call_arguments = JSON.parse(toolCall.function.arguments); // <-- arguments 是序列化后的 JSON Object,我们需要使用 JSON.parse 反序列化一下
let tool_result;
if (tool_call_name == "$web_search") {
tool_result = search_impl(tool_call_arguments)
} else {
tool_result = 'no tool found'
}
// 使用函数执行结果构造一个 role=tool 的 message,以此来向模型展示工具调用的结果;
// 注意,我们需要在 message 中提供 tool_call_id 和 name 字段,以便 Kimi 大模型
// 能正确匹配到对应的 tool_call。
console.log("toolCall.id");
console.log(toolCall.id);
console.log("tool_call_name");
console.log(tool_call_name);
console.log("tool_result");
console.log(tool_result);
messages.push({
"role": "tool",
"tool_call_id": toolCall.id,
"name": tool_call_name,
"content": JSON.stringify(tool_result), // <-- 我们约定使用字符串格式向 Kimi 大模型提交工具调用结果,因此在这里使用 JSON.stringify 将执行结果序列化成字符串
});
}
}
console.log(choice.message.content); // <-- 在这里,我们才将模型生成的回复返回给用户
}
}
main();
为什么 search_impl 不需要任何搜索、解析、获取网页内容的逻辑?正如 builtin_function 的名称所示,$web_search 是 Kimi 大模型内置的函数,由 Kimi 大模型定义,也由 Kimi 大模型执行:
当 Kimi 大模型生成了 finish_reason=tool_calls 的响应时,表明它已经意识到需要执行 $web_search,并且已经做好执行 $web_search 的一切准备工作;
Kimi 大模型会将执行函数所必须的参数以 tool_call.function.arguments 的形式返回给调用方,但这些参数并不由调用方执行,调用方只需要将 tool_call.function.arguments 原封不动地提交给 Kimi 大模型,即可由 Kimi 大模型执行对应的联网搜索流程;
当你将 tool_call.function.arguments 使用 role=tool 的 message 提交时,Kimi 大模型随即开始执行联网搜索流程,并根据搜索和阅读结果生成可供用户阅读的消息,即 finish_reason=stop 的 message。
复制后粘贴到 AI 对话框发送,本次对话全程生效
出处:Kimi/Moonshot 官方提示词指南 · platform.moonshot.cn/docs/guide/use-web-search · 可信度 S · 标签:中文 / 提示词工程 / 防幻觉 / Kimi / 联网搜索 怎么用(对话型)复制后粘贴到对话框发送,本次对话全程生效。想长期用:支持自定义指令的产品(设置→个性化)可设为默认。