lobe-chat icon indicating copy to clipboard operation
lobe-chat copied to clipboard

[Request] tool_calls改为role=tool

Open hackiey opened this issue 1 year ago • 9 comments

🥰 需求描述

目前的tool_calls机制仅在调用工具的时候使用了tools参数,拿到工具返回后仍使用role=function继续调用。看代码似乎没有实现当tool_calls数组有多个时分别调用多个function。

🧐 解决方案

应参考OpenAI的官方案例,在遇到tool_calls的assistant消息时,将该消息插入在历史messages中,并将tool_calls数组中的每个tool进行调用,得到结果后同样插入历史messages中。

原工具调用链 调用时:

[
    {"role": "user", "content": "北京和上海天气怎么样"}, 
    {"role": "assistant", "content": "请稍等,我将为您查询天气", "tool_calls": [
        {"id": "xxx", "type": "function", "function": {"name": "get_weather", "arguments": "{\n  "location": "北京"\n }"}},
        {"id": "yyy", "type": "function", "function": {"name": "get_weather", "arguments": "{\n  "location": "上海"\n }"}},
    ]},
]

调用工具后:

[
    {"role": "user", "content": "北京和上海天气怎么样"}, 
     {"role": "function", "name": "get_weather", "content": "北京天气晴朗"},
]

调整后的工具调用链:

[
    {"role": "user", "content": "北京和上海天气怎么样"}, 
    {"role": "assistant", "content": "请稍等,我将为您查询天气", "tool_calls": [
        {"id": "xxx", "type": "function", "function": {"name": "get_weather", "arguments": "{\n  "location": "北京"\n }"}},
        {"id": "yyy", "type": "function", "function": {"name": "get_weather", "arguments": "{\n  "location": "上海"\n }"}},
    ]},
    {"role": "tool", "tool_call_id": "xxx", "name": "get_weather", "content": "北京天气晴朗"},
    {"role": "tool", "tool_call_id": "yyy", "name": "get_weather", "content": "上海天气晴朗"}
]

📝 补充信息

No response

hackiey avatar Jan 10 '24 08:01 hackiey

👀 @hackiey

Thank you for raising an issue. We will investigate into the matter and get back to you as soon as possible. Please make sure you have given us as much context as possible.
非常感谢您提交 issue。我们会尽快调查此事,并尽快回复您。 请确保您已经提供了尽可能多的背景信息。

lobehubbot avatar Jan 10 '24 08:01 lobehubbot

我调研过,目前看没有太大必要,OpenAI 现在这个能力有点鸡肋的。https://github.com/lobehub/lobe-chat/discussions/551#discussioncomment-7948718

arvinxx avatar Jan 10 '24 09:01 arvinxx

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


I have done some research, and it seems that it is not necessary at the moment. OpenAI’s current capabilities are a bit useless. https://github.com/lobehub/lobe-chat/discussions/551#discussioncomment-7948718

lobehubbot avatar Jan 10 '24 09:01 lobehubbot

✅ @hackiey

This issue is closed, If you have any questions, you can comment and reply.
此问题已经关闭。如果您有任何问题,可以留言并回复。

lobehubbot avatar Jan 10 '24 09:01 lobehubbot

把assistant 的tool_calls拼进messages的目的是告诉gpt自己调用过哪些tools以及调用时传入的参数,理论上能避免工具调用失败时多次重复调用。 另外role=function也是deprecated状态了。 image

hackiey avatar Jan 10 '24 09:01 hackiey

把assistant 的tool_calls拼进messages的目的是告诉gpt自己调用过哪些tools以及调用时传入的参数,理论上能避免工具调用失败时多次重复调用。

这个避免重复调用的原理是什么样的? 用 role=function 应该一样能达到这个效果吧?

另外role=function也是deprecated状态了。

这个是需要升级的,但涉及到已有数据的迁移升级,准备找一个更合适的时间做个统一的升级。

arvinxx avatar Jan 11 '24 01:01 arvinxx

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The purpose of spelling assistant's tool_calls into messages is to tell gpt which tools it has called and the parameters passed in when calling. In theory, it can avoid repeated calls when the tool call fails.

What is the principle of avoiding repeated calls? Using role=function should be able to achieve the same effect, right?

In addition, role=function is also in deprecated state.

This needs to be upgraded, but it involves the migration and upgrade of existing data. We are ready to find a more suitable time to do a unified upgrade.

lobehubbot avatar Jan 11 '24 01:01 lobehubbot

官方案例中function_call和tool_calls的最大区别是,tool_calls会把调用信息当做一条message放入上下文中,相比于function_call会多一条调用参数的信息。 如果function调用失败,function_call的messages是

[
    {"role": "user", "content": "http://www.example.com里有什么内容"}, 
    {"role": "function", "name": "web_crawler", "content": ""},
    {"role": "function", "name": "web_crawler", "content": ""},
    {"role": "function", "name": "web_crawler", "content": ""},
    {"role": "function", "name": "web_crawler", "content": ""},
]

tool_calls的messages是

[
    {"role": "user", "content": "http://www.example.com里有什么内容"}, 
    {"role": "assistant", "content": null, "tool_calls": [{"id": "xxx", "type": "function", "function": {"name": "web_crawler", "arguments": "{\n  "url": "http://www.example.com"\n }"}},]},
    {"role": "tool", "tool_call_id": "xxx", "name": "web_crawler", "content": ""},
    {"role": "assistant", "content": null, "tool_calls": [{"id": "yyy", "type": "function", "function": {"name": "web_crawler", "arguments": "{\n  "url": "http://www.example.com"\n }"}},]},
    {"role": "tool", "tool_call_id": "yyy", "name": "web_crawler", "content": ""},
    {"role": "assistant", "content": null, "tool_calls": [{"id": "zzz", "type": "function", "function": {"name": "web_crawler", "arguments": "{\n  "url": "http://www.example.com"\n }"}},]},
    {"role": "tool", "tool_call_id": "zzz", "name": "web_crawler", "content": ""},

tool_calls比function_call多了url的信息,在做下一步决策时会更可靠。本质上是降低模型的单次思考的猜测程度,猜的越少,智能程度就越高。

更合理的结果应该是tool_calls拿到content=""时,因为知道自己已经调用过了web_crawler(" http://www.example.com "),会更可能直接输出该网页是空内容,而function_call只知道content="",认为自己并没有解决问题,会反复调用web_crawler

hackiey avatar Jan 11 '24 03:01 hackiey

官方案例中function_call和tool_calls的最大区别是,tool_calls会把调用信息当做一条message放入上下文中,相比于function_call会多一条调用参数的信息。

你这么说我倒是明白了,之前我在研究接入 function call 的时候就发现如果消息编排是下面这样的:

"role": "assistant", "content": null, "function_call":{"name": "web_crawler", "arguments": "{\n  "url": "http://www.example.com"\n }"

只要第二次发送的消息里带有这种结构,接口就报错,导致无法重复请求。

所以我最后的折中方案就是把函数调用这一条消息去掉,换成 role=funtcion ,才能确保可以重复执行不报错:

    {"role": "function", "name": "web_crawler", "content": ""},

但相应的问题就是会丢失执行过函数调用的这一条记录。

这么看来 openai 是意识到了这个问题,然后在 tool calls 里解决了呀

arvinxx avatar Jan 11 '24 05:01 arvinxx

✅ @hackiey

This issue is closed, If you have any questions, you can comment and reply.
此问题已经关闭。如果您有任何问题,可以留言并回复。

lobehubbot avatar May 11 '24 15:05 lobehubbot

:tada: This issue has been resolved in version 0.157.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

lobehubbot avatar May 11 '24 15:05 lobehubbot