Closed macoli closed 10 months ago
这个问题看起来像是由于工具的声明有误导致的,也有小概率可能是模型的 Bad Case。 可以麻烦你把编写工具和调用 agent 的代码贴上来吗?
这是我编写的工具和调用agent。我是想通过自然自然语言像工具传递json格式的字符串'{"user": "root", "ip": "1.1.1.1"}',但是似乎并没有生效。而我使用openapi的接口,是可以的
def ldap_user_lock_check_data_retriever(
ip: str = None,
user: str = None,
) -> str:
'''
该函数是用于从第三方api接口获取数据
给定参数:method、ip 和user,这个自定义函数以数据结构(JSON 格式)返回结果。
参数:
ip: 指定机器的ip地址, 示例: '127.0.0.1'
user: 指定用户名, 示例: 'root'
返回结果:
JSON格式的结果描述, 示例:
{ 'result': 'Login Failures Latest failure From\nroot 0 \n'}
'''
if not ip:
return json.dumps({'result': 'ip未指定,请问您要查看机器的ip是多少呢?'})
if not user:
return json.dumps({'result': 'user未指定,请问您要查看机器上的哪个user呢?'})
url = 'http://localhost:5000/api/v1'
data = {
'method': 'ldap_user_lock_check',
'ip': ip,
'user': user
}
headers = {'Content-Type': 'application/json'} # 设置请求头,指定使用 JSON 格式
# requests = TextRequestsWrapper()
response = requests.post(url, data=json.dumps(data), headers=headers)
if response.status_code == 200:
# 处理响应数据
data = response.json()
return json.dumps({'result': data['response']})
else:
return json.dumps({'result': 'POST request failed'})
def ldap_user_lock_check(json_request: str) -> str:
'''
对 ldap_user_lock_check_data_retriever 函数进行封装,
将输入 JSON 转换为分隔的参数。
参数:
json_request(str):JSON字典输入字符串。
采用 JSON 字典作为表单的输入:
{ "ip":"<ip>", "user":"user"}
示例:
{ "ip":"127.0.0.1", "user":"root" }
返回结果:
JSON类型的结果。
'''
print(json_request)
arguments = json.loads(json_request)
ip = arguments.get('ip', None)
user = arguments.get('user', None)
return ldap_user_lock_check_data_retriever(ip=ip, user=user)
name = 'ldap_user_lock_check'
request_format = '{{ "ip": "<ip>", "user": "<user>"}}'
result_format = '{{"result": "<result>"}}'
description = f'''
帮助获取在指定机器上的用户账号登录失败次数。
输入应为以下格式的JSON格式的字符串: {request_format}
输出应为以下格式的JSON: {result_format}
'''
# create an instance of the custom langchain tool
Ldap_user_lock_check = Tool(
name=name,
func=ldap_user_lock_check,
description=description,
return_direct=False
)```
******************************************************************************************
```import os
os.environ['QIANFAN_AK'] = "xxx"
os.environ['QIANFAN_SK'] = "xxx"
from langchain.chat_models import QianfanChatEndpoint
qianfan_chat_model = QianfanChatEndpoint(model="ERNIE-Bot-4")
# import custom tools
from ldap_user_lock_check_qianfan import Ldap_user_lock_check
tools = [
Ldap_user_lock_check
]
from langchain.agents import AgentExecutor
from qianfan.extensions.langchain.agents import QianfanSingleActionAgent
qianfan_agent = QianfanSingleActionAgent.from_system_prompt(tools, qianfan_chat_model)
excutor = AgentExecutor(agent=qianfan_agent, tools=tools, verbose=True)
ret = excutor.run("我想要查询ip为10.1.1.1的机器上user为root的登录失败次数")
print(ret)```
QianfanSingleActionAgent 内部使用的 Tool 格式化函数会检查传入的工具对象中是否设置了 args_schema
这一参数,并且在设置了这一参数的情况下按 schema 填充工具的入参格式信息;否则全部统一使用 {"__arg1": {"title": "__arg1", "type": "string"}}
作为入参的字典列表,这点与 OpenAI 的逻辑是一致的。如果你需要传递自定义的入参列表信息,请设置该字段,或者使用 langchain 提供的 tool 装饰器。在 description 中描述工具的入参大概率无法获得所期望的结果,OpenAI 在使用工具时可能对 description 有着更好的理解。针对你的 case,以下代码是可行的:
class Model(pydantic.v1.BaseModel):
'''
对 ldap_user_lock_check_data_retriever 函数进行封装,
将输入 JSON 转换为分隔的参数。
参数:
json_request(str):JSON字典输入字符串。
采用 JSON 字典作为表单的输入:
{ "ip":"<ip>", "user":"user"}
示例:
{ "ip":"127.0.0.1", "user":"root" }
返回结果:
JSON类型的结果。
'''
json_request: str = pydantic.v1.Field(desctiption="需要以 json 格式传递的入参字典")
@tool(args_schema=Model)
def ldap_user_lock_check(json_request: str) -> str:
'''
使用参数规定的 json 格式,帮助获取在指定机器上的用户账号登录失败次数。
'''
print(json_request)
arguments = json.loads(json_request)
ip = arguments.get('ip', None)
user = arguments.get('user', None)
return ldap_user_lock_check_data_retriever(ip=ip, user=user)
原来是没有指定args_schema,完全依赖大模型的自然语言理解是不科学的。我设置了args_schema之后,可以运行了。非常感谢!
Issue you'd like to raise.
我给自定义工具指定的输入格式为json格式的字符串
在我问出问题时,无法将问题中的数据转换成指定的json格式,似乎只能识别输入一个参数
我的自定义tool在使用openai时是正常的,但是使用千帆function_call_agent就会报错
Suggestion:
No response