虽然大语言模型具备完成很多任务的能力,但是在专业细分领域并不擅长。此外,大模型本身的幻觉问题也很难通过模型自身的能力来解决,需要引入额外的组件。
因此,我们需要通过一些工具辅助来帮助大模型来完成相关任务。
在DB-GPT所支持的模型列表中,绝大多数都具备工具调用的能力。在开源模型中也有相当一部分模型表现出色,比如glm-4-9b-chat、 Yi-1.5-34B-Chat、Qwen2-72B-Instruct等
工具编写
在有些情况下,大模型没有能力直接完成任务的计算,所以我们需要编写一些计算工具,来辅助大模型完成对应的目标。
from dbgpt.agent.resource import tool
@tool
def simple_calculator(first_number: int, second_number: int, operator: str) -> float:
"""Simple calculator tool. Just support +, -, *, /."""
if isinstance(first_number, str):
first_number = int(first_number)
if isinstance(second_number, str):
second_number = int(second_number)
if operator == "+":
return first_number + second_number
elif operator == "-":
return first_number - second_number
elif operator == "*":
return first_number * second_number
elif operator == "/":
return first_number / second_number
else:
raise ValueError(f"Invalid operator: {operator}")
为了测试多工具使用,我们继续编写一个工具来帮助LLM计算目录中的文件数量。
import os
from typing_extensions import Annotated, Doc
@tool
def count_directory_files(path: Annotated[str, Doc("The directory path")]) -> int:
"""Count the number of files in a directory."""
if not os.path.isdir(path):
raise ValueError(f"Invalid directory path: {path}")
return len(os.listdir(path))
将工具打包到ToolPack中
绝大多数情况下,尤其是在生产使用中。我们我要具备多工具的能力,所以需要由ToolPack
来进行工具的管理。 ToolPack
是一组工具的集合,你可以使用它来进行工具管理。 智能体可以根据具体的任务从工具包中选择对应的工具来完成任务。
from dbgpt.agent.resource import ToolPack
tools = ToolPack([simple_calculator, count_directory_files])
在Agent中使用工具
import asyncio
import os
from dbgpt.agent import AgentContext, AgentMemory, LLMConfig, UserProxyAgent
from dbgpt.agent.expand.tool_assistant_agent import ToolAssistantAgent
from dbgpt.model.proxy import OpenAILLMClient
async def main():
llm_client = OpenAILLMClient(
model_alias="gpt-3.5-turbo", # or other models, eg. "gpt-4o"
api_base=os.getenv("OPENAI_API_BASE"),
api_key=os.getenv("OPENAI_API_KEY"),
)
context: AgentContext = AgentContext(
conv_id="test123", language="en", temperature=0.5, max_new_tokens=2048
)
agent_memory = AgentMemory()
user_proxy = await UserProxyAgent().bind(agent_memory).bind(context).build()
tool_man = (
await ToolAssistantAgent()
.bind(context)
.bind(LLMConfig(llm_client=llm_client))
.bind(agent_memory)
.bind(tools)
.build()
)
await user_proxy.initiate_chat(
recipient=tool_man,
reviewer=user_proxy,
message="Calculate the product of 10 and 99",
)
await user_proxy.initiate_chat(
recipient=tool_man,
reviewer=user_proxy,
message="Count the number of files in /tmp",
)
# dbgpt-vis message infos
print(await agent_memory.gpts_memory.one_chat_completions("test123"))
if __name__ == "__main__":
asyncio.run(main())
输出如下
--------------------------------------------------------------------------------
User (to LuBan)-[]:
"Calculate the product of 10 and 99"
--------------------------------------------------------------------------------
un_stream ai response: {
"thought": "To calculate the product of 10 and 99, we need to use a tool that can perform multiplication operation.",
"tool_name": "simple_calculator",
"args": {
"first_number": 10,
"second_number": 99,
"operator": "*"
}
}
--------------------------------------------------------------------------------
LuBan (to User)-[gpt-3.5-turbo]:
"{\n \"thought\": \"To calculate the product of 10 and 99, we need to use a tool that can perform multiplication operation.\",\n \"tool_name\": \"simple_calculator\",\n \"args\": {\n \"first_number\": 10,\n \"second_number\": 99,\n \"operator\": \"*\"\n }\n}"
>>>>>>>>LuBan Review info:
Pass(None)
>>>>>>>>LuBan Action report:
execution succeeded,
990
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
User (to LuBan)-[]:
"Count the number of files in /tmp"
--------------------------------------------------------------------------------
un_stream ai response: {
"thought": "To count the number of files in /tmp directory, we should use a tool that can perform this operation.",
"tool_name": "count_directory_files",
"args": {
"path": "/tmp"
}
}
--------------------------------------------------------------------------------
LuBan (to User)-[gpt-3.5-turbo]:
"{\n \"thought\": \"To count the number of files in /tmp directory, we should use a tool that can perform this operation.\",\n \"tool_name\": \"count_directory_files\",\n \"args\": {\n \"path\": \"/tmp\"\n }\n}"
>>>>>>>>LuBan Review info:
Pass(None)
>>>>>>>>LuBan Action report:
execution succeeded,
19
--------------------------------------------------------------------------------
在上面的代码中,我们使用了ToolAssistantAgent
工具助手智能体来选择并且调用工具,你可以将相关的能力应用到自己的业务当中。
更多细节
在上面代码中,我们用到了tool这个装饰器来定义工具函数。它将函数包装到FunctionTool
对象,而FunctionTool
是BaseTool
的子类,BaseTool
是所有工具的基类。
事实上,工具也是DB-GPT中Agent的一类特殊资源。如果想了解更多细节,可以查看资源介绍。