函数调用(Function Call)
功能描述(Description)
在对话生成基础上增加函数调用功能,支持用户接入自有函数。该功能可实现模型自主判断是否调用外部函数,并将函数调用返回的结果送入模型辅助对话生成。
请求地址(Request URL)
[POST] https://api.sensenova.cn/v1/llm/chat-completions
请求头(Request Header)
无特殊Header,请参考接口鉴权
请求体(Request Body)
在使用对话生成(无会话历史)接口基础功能参数的同时,可额外添加以下参数实现函数调用功能。
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
model | string | 是 | - | 参考模型清单 | 模型ID |
stream | boolean | 否 | false | 开启:true 关闭: false | 是否使用流式传输,如果开启,数据将按照data-only SSE (server-sent events)返回中间结果,并以 data: [DONE] 结束 |
messages | object[] | 是 | - | - | 输入给模型的对话上下文,数组中的每个对象为聊天的上下文信息 |
tools | object[] | 否 | - | - | 期望模型在本次请求中调用的工具定义 |
tool_choice | object | 否 | - | - | 期望模型在本次请求中调用的工具选择及配置 |
messages
部分参数如下(基础功能参数请参考对话生成(无会话历史)接口):
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
role | string | 是 | - | 新增一个tool ,代表外部函数调用的结果 | 消息作者的角色,枚举值。请注意数组中最后一项必须为 user 或 tool |
content | string | 否 | - | - | 消息的内容,外部函数调用得到的结果也放在该字段里 |
tool_call_id | string | 否 | - | - | 函数调用ID(注意,tool_call_id 必须和content 同时传入,对应的role 为tool ,以实现将外部函数的调用结果传入模型) |
tool_calls | object[] | 否 | - | - | 函数调用的内容(模型在历次请求中输出的,所选择的要调用的函数及具体信息,对应的role 为assistant ) |
tool_calls
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
id | string | 是 | - | - | 函数调用ID |
type | string | 是 | - | 函数调用:function | 工具类型,枚举值,目前仅支持function |
function | object | 是 | - | - | 调用外部函数时的具体信息 |
function
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
name | string | 是 | - | - | 函数名称 |
arguments | json string | 是 | - | - | 函数的入参,格式为json序列化后的string,表达该如何调用该函数 |
tools
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
type | string | 是 | - | 函数调用:function | 工具类型,枚举值,目前仅支持function |
function | object | 否(type 值为function 时必须) | - | - | 外部函数定义 |
function
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
name | string | 是 | - | - | 函数名称,长度不超过100个字符 |
description | string | 否 | - | - | 函数描述,长度不超过500个字符 |
parameters | object | 是 | - | - | 函数的请求参数定义 |
parameters
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
type | string | 是 | - | object | 函数的请求数据类型 |
properties | object | 是 | - | 符合json标准的schema语法,参考:JSON Schema | 函数的各个请求参数说明,包括每个参数的名称、类型和描述,每个参数设定的具体格式为: "additionalProp1":{//参数名;必须;100个字符以内 "type": "string", //参数类型;必须;500个字符以内 "description": "string" //参数描述;必须;500个字符以内 } |
required | string[] | 否 | 空(所有参数都非必须) | - | 函数的各个参数的必须校验说明(填写必须的参数名) |
tool_choice
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
mode | string | 否 | auto | 不调用任何工具:none 模型自由选择调用哪个工具: auto 手动指定调用哪些工具: manual | 调用工具的模式 |
tools | object[] | 当mode 值为manual 时必须 | - | 从已定义的工具列表中选择 | manual 模式时具体需要强制调用的工具列表,目前限制队列长度<=1,即只能指定调用其中1个 |
tools
部分参数如下:
名称 | 类型 | 必须 | 默认值 | 可选值 | 描述 |
---|---|---|---|---|---|
type | string | 否 | function | 函数调用:function | 工具类型,枚举值,目前仅支持function |
name | string | 否 | - | 从已定义的工具名称中选择 | 工具名称 |
请求示例(Request Example)
curl --request POST "https://api.sensenova.cn/v1/llm/chat-completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
-d '{
"model": "string",
"messages": [
{
"role": "string",
"content": "string",
"tool_call_id": "string",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_current_weather",
"arguments": "{\n\"location\": \"Boston, MA\"\n}"
}
}
]
}
],
"tools":[
{
"type": "string",
"function":{
"name": "string",
"description": "string",
"parameters": {
"type": "object",
"properties": {
"string":{
"type": "string",
"description": "string"
}
},
"required": [
"string"
]
}
}
}
],
"tool_choice":{
"mode": "string",
"tools":[
{
"type": "string",
"name": "string"
}
]
}
}'
响应(Response)
名称 | 类型 | 描述 |
---|---|---|
data | object | 生成内容 |
data
部分参数如下:
名称 | 类型 | 描述 |
---|---|---|
id | string | 消息ID |
choices | object[] | 生成的回复列表 |
usage | object | token使用量 |
choices
部分参数如下:
名称 | 类型 | 描述 |
---|---|---|
message | string | 非流式请求时,生成的回复内容 |
tool_calls | object[] | 函数调用的内容,若本次请求最终执行的是生成消息内容,则该字段为空 |
finish_reason | string | 停止生成的原因,新增枚举值 调用函数: tool_calls |
index | int | 生成的回复序号 |
role | string | 回复消息的角色 |
tool_calls
部分参数如下:
名称 | 类型 | 描述 |
---|---|---|
id | string | 函数调用ID |
type | string | 工具类型,枚举值,目前仅支持function (函数调用) |
function | object | 函数调用的具体信息,包括要调用的函数名称和入参 |
function
部分参数如下:
名称 | 类型 | 描述 |
---|---|---|
name | string | |
arguments | json string |
usage
部分参数如下:
名称 | 类型 | 描述 |
---|---|---|
prompt_tokens | int | 用户输入内容的token数 |
knowledge_tokens | int | 知识库内容输入模型的token数 |
completion_tokens | int | 生成消息对应的token数 |
total_tokens | int | 总token数 |
响应示例(Response Example)
- 非流式
{
"data": {
"id": "4b44cd86cd2c000",
"choices": [
{
"message": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_current_weather",
"arguments": "{\n\"location\": \"Boston, MA\"\n}"
}
}
],
"finish_reason": "tool_calls",
"index": 0,
"role": "assistant"
}
],
"usage": {
"prompt_tokens": 6,
"knowledge_tokens": 0,
"completion_tokens": 6,
"total_tokens": 12
}
}
}
- 流式
// 第一次请求对应的流式返回(模型输出函数调用以及具体参数)
data:{"data":{"id":"172a4446-e733-4fc6-9cef-ed6746cd2f68","usage":{"prompt_tokens":12,"completion_tokens":0,"knowledge_tokens":0,"total_tokens":12},"choices":[{"index":0,"role":"assistant","type":"tool_calls","delta":"","finish_reason":""}],"plugins":null},"status":{"code":0,"message":"ok"}}
data:{"data":{"id":"172a4446-e733-4fc6-9cef-ed6746cd2f68","usage":{"prompt_tokens":12,"completion_tokens":31,"knowledge_tokens":0,"total_tokens":43},"choices":[{"index":0,"role":"assistant","type":"tool_calls","delta":"","tool_calls":[{"id":"47d6238c-33a8-457a-a4de-e48fd48916d6","type":"function","function":{"name":"get_temperature","arguments":"{\"location\":\"北京\",\"time\":\"2023-01-15\"}"},"code_block":null}],"finish_reason":"tool_calls"}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:[DONE]
// 第二次请求对应的流式返回(将外部函数调用结果输入模型,模型输出回复)
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":1,"knowledge_tokens":0,"total_tokens":22},"choices":[{"index":0,"role":"assistant","delta":"20","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":2,"knowledge_tokens":0,"total_tokens":23},"choices":[{"index":0,"role":"assistant","delta":"23","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":3,"knowledge_tokens":0,"total_tokens":24},"choices":[{"index":0,"role":"assistant","delta":"年","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":4,"knowledge_tokens":0,"total_tokens":25},"choices":[{"index":0,"role":"assistant","delta":"1","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":5,"knowledge_tokens":0,"total_tokens":26},"choices":[{"index":0,"role":"assistant","delta":"月","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":6,"knowledge_tokens":0,"total_tokens":27},"choices":[{"index":0,"role":"assistant","delta":"15","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":7,"knowledge_tokens":0,"total_tokens":28},"choices":[{"index":0,"role":"assistant","delta":"日","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":8,"knowledge_tokens":0,"total_tokens":29},"choices":[{"index":0,"role":"assistant","delta":",","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":9,"knowledge_tokens":0,"total_tokens":30},"choices":[{"index":0,"role":"assistant","delta":"北京的","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":10,"knowledge_tokens":0,"total_tokens":31},"choices":[{"index":0,"role":"assistant","delta":"气温","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":11,"knowledge_tokens":0,"total_tokens":32},"choices":[{"index":0,"role":"assistant","delta":"是","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":12,"knowledge_tokens":0,"total_tokens":33},"choices":[{"index":0,"role":"assistant","delta":"38","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":13,"knowledge_tokens":0,"total_tokens":34},"choices":[{"index":0,"role":"assistant","delta":"摄氏度","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":14,"knowledge_tokens":0,"total_tokens":35},"choices":[{"index":0,"role":"assistant","delta":"。","finish_reason":""}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:{"data":{"id":"d66aa0bd-784c-420c-9db1-cac963f87b44","usage":{"prompt_tokens":21,"completion_tokens":15,"knowledge_tokens":0,"total_tokens":36},"choices":[{"index":0,"role":"assistant","delta":"","finish_reason":"stop"}],"plugins":{}},"status":{"code":0,"message":"OK"}}
data:[DONE]
具体调用示例
Step1 用户第一次请求
- 请求体
{
"model": "SenseChat-FunctionCall",
"messages": [
{
"role": "user",
"content": "北京在2023年1月15号的气温是多少"
}
],
"tools":[
{
"type": "function",
"function":{
"name": "get_temperature",
"description": "根据地点和时间,获取当日气温",
"parameters": {
"type": "object",
"properties": {
"location":{
"type": "string",
"description": "地点"
},
"time":{
"type": "string",
"description": "时间,符合年-月-日的格式"
}
},
"required": [
"location", "time"
]
}
}
}
],
"tool_choice": {
"mode": "auto"
}
}
- 返回体
{
"data": {
"id": "4b44cd86cd2c000",
"choices": [
{
"tool_calls": [
{
"id": "call_GetTemperature_1",
"type": "function",
"function": {
"name": "get_temperature",
"arguments": "{\n\"location\": \"中国北京\",\n\"time\":\"2023-01-15\"\n}"
}
}
],
"message": "",
"finish_reason": "tool_calls",
"index": 0,
"role": "assistant"
}
],
"usage": {
"prompt_tokens": 6,
"knowledge_tokens": 0,
"completion_tokens": 6,
"total_tokens": 12
}
}
}
Step2 用户获得第一次请求结果,去调用外部函数,并获得函数返回
假设函数返回为:{"temperature": "38摄氏度"}
Step3 用户第二次请求
- 请求体
{
"model": "SenseChat-FunctionCall",
"messages": [
{
"role": "user",
"content": "北京在2023年1月15号的气温是多少"
},
{
"role": "assistant",
"tool_calls": [
{
"id": "call_GetTemperature_1",
"type": "function",
"function": {
"name": "get_temperature",
"arguments": "{\n\"location\": \"中国北京\",\n\"time\":\"2023-01-15\"\n}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_GetTemperature_1",
"content": "{\n\"temperature\": \"38摄氏度\"\n}"
}
],
"tools":[
{
"type": "function",
"function":{
"name": "get_temperature",
"description": "根据地点和时间,获取当日气温",
"parameters": {
"type": "object",
"properties": {
"location":{
"type": "string",
"description": "地点"
},
"time":{
"type": "string",
"description": "时间,符合年-月-日的格式"
}
},
"required": [
"location", "time"
]
}
}
}
],
"tool_choice": {
"mode": "auto"
}
}
- 返回体
{
"data": {
"id": "4b44cd86cd2c000",
"choices": [
{
"message": "你好,2023年1月15号,北京的气温是38摄氏度",
"finish_reason": "stop",
"index": 0,
"role": "assistant"
}
],
"usage": {
"prompt_tokens": 6,
"knowledge_tokens": 0,
"completion_tokens": 6,
"total_tokens": 12
}
}
}
Step4 用户第三次请求
- 请求体
{
"model": "SenseChat-FunctionCall",
"messages": [
{
"role": "user",
"content": "北京在2023年1月15号的气温是多少"
},
{
"role": "assistant",
"tool_calls": [
{
"id": "call_GetTemperature_1",
"type": "function",
"function": {
"name": "get_temperature",
"arguments": "{\n\"location\": \"中国北京\",\n\"time\":\"2023-01-15\"\n}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_GetTemperature_1",
"content": "{\n\"temperature\": \"38摄氏度\"\n}"
},
{
"role": "assistant",
"content": "你好,2023年1月15号,北京的气温是38摄氏度"
},
{
"role": "user",
"content": "那一天上海的是多少?"
}
],
"tools":[
{
"type": "function",
"function":{
"name": "get_temperature",
"description": "根据地点和时间,获取当日气温",
"parameters": {
"type": "object",
"properties": {
"location":{
"type": "string",
"description": "地点"
},
"time":{
"type": "string",
"description": "时间,符合年-月-日的格式"
}
},
"required": [
"location", "time"
]
}
}
}
],
"tool_choice": {
"mode": "auto"
}
}
- 返回体
{
"data": {
"id": "4b44cd86cd2c000",
"choices": [
{
"tool_calls": [
{
"id": "call_GetTemperature_2",
"type": "function",
"function": {
"name": "get_temperature",
"arguments": "{\n\"location\": \"中国上海\",\n\"time\":\"2023-01-15\"\n}"
}
}
],
"message": "",
"finish_reason": "tool_calls",
"index": 0,
"role": "assistant"
}
],
"usage": {
"prompt_tokens": 6,
"knowledge_tokens": 0,
"completion_tokens": 6,
"total_tokens": 12
}
}
}
Step5 用户获得第三次请求结果,去调用外部函数,并获得函数返回
假设函数返回为:{"temperature": "40摄氏度"}
Step6 用户第四次请求
- 请求体
{
"model": "SenseChat-FunctionCall",
"messages": [
{
"role": "user",
"content": "北京在2023年1月15号的气温是多少"
},
{
"role": "assistant",
"tool_calls": [
{
"id": "call_GetTemperature_1",
"type": "function",
"function": {
"name": "get_temperature",
"arguments": "{\n\"location\": \"中国北京\",\n\"time\":\"2023-01-15\"\n}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_GetTemperature_1",
"content": "{\n\"temperature\": \"38摄氏度\"\n}"
},
{
"role": "assistant",
"content": "你好,2023年1月15号,北京的气温是38摄氏度"
},
{
"role": "user",
"content": "那一天上海的是多少?"
},
{
"role": "assistant",
"tool_calls": [
{
"id": "call_GetTemperature_2",
"type": "function",
"function": {
"name": "get_temperature",
"arguments": "{\n\"location\": \"中国上海\",\n\"time\":\"2023-01-15\"\n}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_GetTemperature_2",
"content": "{\n\"temperature\": \"40摄氏度\"\n}"
}
],
"tools":[
{
"type": "function",
"function":{
"name": "get_temperature",
"description": "根据地点和时间,获取当日气温",
"parameters": {
"type": "object",
"properties": {
"location":{
"type": "string",
"description": "地点"
},
"time":{
"type": "string",
"description": "时间,符合年-月-日的格式"
}
},
"required": [
"location", "time"
]
}
}
}
],
"tool_choice": {
"mode": "auto"
}
}
- 返回体
{
"data": {
"id": "4b44cd86cd2c000",
"choices": [
{
"message": "你好,2023年1月15号,上海的气温是40摄氏度",
"finish_reason": "stop",
"index": 0,
"role": "assistant"
}
],
"usage": {
"prompt_tokens": 6,
"knowledge_tokens": 0,
"completion_tokens": 6,
"total_tokens": 12
}
}
}
Step7 结束
至此,用户完成了一个典型的函数调用场景的封装和使用。
错误信息
参考错误码