Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Request] tool_calls改为role=tool #999

Closed
hackiey opened this issue Jan 10, 2024 · 11 comments · Fixed by #2414
Closed

[Request] tool_calls改为role=tool #999

hackiey opened this issue Jan 10, 2024 · 11 comments · Fixed by #2414
Assignees
Labels
🌠 Feature Request New feature or request | 特性与建议 Inactive No response in 30 days | 超过 30 天未活跃 released
Milestone

Comments

@hackiey
Copy link

hackiey commented Jan 10, 2024

🥰 需求描述

目前的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

@lobehubbot
Copy link
Member

👀 @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。我们会尽快调查此事,并尽快回复您。 请确保您已经提供了尽可能多的背景信息。

@arvinxx
Copy link
Contributor

arvinxx commented Jan 10, 2024

我调研过,目前看没有太大必要,OpenAI 现在这个能力有点鸡肋的。#551 (comment)

@arvinxx arvinxx closed this as not planned Won't fix, can't repro, duplicate, stale Jan 10, 2024
@lobehubbot
Copy link
Member

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. #551 (comment)

@lobehubbot
Copy link
Member

@hackiey

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

@hackiey
Copy link
Author

hackiey commented Jan 10, 2024

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

@hackiey hackiey changed the title [Request] [Request] tool_calls改为role=tool Jan 10, 2024
@arvinxx
Copy link
Contributor

arvinxx commented Jan 11, 2024

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

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

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

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

@arvinxx arvinxx reopened this Jan 11, 2024
@lobehubbot
Copy link
Member

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.

@hackiey
Copy link
Author

hackiey commented Jan 11, 2024

官方案例中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

@arvinxx
Copy link
Contributor

arvinxx commented Jan 11, 2024

官方案例中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 里解决了呀

@lobehubbot
Copy link
Member

@hackiey

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

@lobehubbot
Copy link
Member

🎉 This issue has been resolved in version 0.157.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌠 Feature Request New feature or request | 特性与建议 Inactive No response in 30 days | 超过 30 天未活跃 released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants