diff --git a/llmagent/__init__.py b/llmagent/__init__.py index d8f37da..42577c1 100644 --- a/llmagent/__init__.py +++ b/llmagent/__init__.py @@ -34,12 +34,13 @@ PROMPT_TEMPLATE = { 4. 确保每个操作都正确地基于前面的操作。 通过等待并仔细考虑用户在每次使用工具后的回应,你可以相应地做出反应并做出关于如何继续任务的明智决定。这个迭代过程有助于确保你工作的整体成功和准确性。 用户的指令是:{user_input} + 今天的日期是:{today} """ }, 'TOOL_CALLER': { 'description': '工具调用器', 'template': """ - 你是工具调用器,用户将会告诉你一条指令 {user_input}, 请根据指令推理出需要调用哪个工具。 + 你是工具调用器,用户将会告诉你一条指令 {user_input}, 请根据指令推理出需要调用哪个工具。今天的日期是:{today}。 # 要求 1.根据指令和提供的工具描述选择最合适的工具,并仔细阅读工具参数说明。 2.你需要根据工具参数说明进行参数校验,评估用户输入的参数是否满足条件,如果不满足需要返回参数校验错误信息。 diff --git a/llmagent/llm_agent.py b/llmagent/llm_agent.py index 783e6bc..0677d48 100644 --- a/llmagent/llm_agent.py +++ b/llmagent/llm_agent.py @@ -19,6 +19,7 @@ from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_core.messages import HumanMessage from log_conf import log from llmagent.llm_config import base_conf +from datetime import datetime # debug模式,有更多输出 set_debug(base_conf.debug) @@ -55,6 +56,14 @@ def get_session_history(session_id: str) -> BaseChatMessageHistory: return his_store[session_id] +def get_today(): + """ + 获取今天日期 + :return: + """ + return datetime.now().strftime('%Y-%m-%d') + + class BaseChatAgent(ABC): """ 抽象Agent类 @@ -135,11 +144,12 @@ class BaseChatAgent(ABC): """ config = {"configurable": {"session_id": session_id}} # 总体任务描述及提示词 - user_msg = PROMPT_TEMPLATE.get('VOICE_ASSISTANT')['template'].format(user_input=user_input) + user_msg = PROMPT_TEMPLATE.get('VOICE_ASSISTANT')['template'].format(user_input=user_input, + today=get_today()) messages = [HumanMessage(user_msg)] llm_with_tools = llm.bind_tools(STRUCT_TOOLS, tool_choice='auto') # 判断使用哪个工具,需要加提示词让模型判断参数是否符合规则 - user_input = PROMPT_TEMPLATE.get('TOOL_CALLER')['template'].format(user_input=user_input) + user_input = PROMPT_TEMPLATE.get('TOOL_CALLER')['template'].format(user_input=user_input, today=get_today()) # 工具chain加入历史对话 too_chain = self.multi_round_prompt | llm_with_tools with_message_history = RunnableWithMessageHistory(too_chain, get_session_history, input_messages_key="messages") diff --git a/llmtools/tool_impl.py b/llmtools/tool_impl.py index 102a401..246bc5f 100644 --- a/llmtools/tool_impl.py +++ b/llmtools/tool_impl.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # @Time : 2025/3/16 16:38 # @Author : old-tom -# @File : basic_tool +# @File : tool_impl # @Project : llmFunctionCallDemo # @Desc : 工具实现, @tool 装饰器是langchain提供的,包含了invoke方法可以直接调用。并且会自动返回ToolMessage,缺点是没有自定义异常处理 # 此外还有其他定义tool方法,参考 https://www.langchain.com.cn/docs/how_to/custom_tools/ @@ -38,7 +38,8 @@ def split_screen(split_n: Annotated[int, "要切换的分屏数量,整数并且 def play_video_record(camera_name: Annotated[str, "相机名称,例如:南卡口1号相机"], start_time: Annotated[str, "录像开始时间,格式为yyyy-MM-dd hh:mm:ss,例 2025-03-16 01:00:00"], end_time: Annotated[str, "录像结束时间,格式为yyyy-MM-dd hh:mm:ss,例 2025-03-16 02:09:31"]) -> str: - pass + log.info('【function】play_video_record 输入 [{},{},{}]', camera_name, start_time, end_time) + return f"正在打开{camera_name}的录像,请等待操作完成" @tool("switch_page", description="打开、跳转页面") @@ -58,6 +59,7 @@ def view_flight_details( str, "航班编号,由字母+数字组成的完整编号,若编号包含多余字符(如标点符号),需过滤后保留有效部分"], flight_date: Annotated[str, "提取完整日期(年月日),自动补零至标准格式 yyyy-MM-dd, 例:2025-03-16"], ie_type: Annotated[str, "出入境类型,仅识别'入境'或'出境'两种类型"]) -> str: + log.info('【function】view_flight_details 输入 [{},{},{},{}]', airport_name, flight_code, flight_date,ie_type) return f"{airport_name}航班号{flight_code}{flight_date}{ie_type}数据,共100人乘机,起飞准时,晚点降落" diff --git a/main.py b/main.py index d3736ae..f2119ba 100644 --- a/main.py +++ b/main.py @@ -11,36 +11,18 @@ from llmagent.llm_agent import ChatAgent dsr = ChatAgent() if __name__ == '__main__': - ########## 测试 多轮对话 ######### - dsr.multi_with_stream('你是什么模型', 1) - dsr.multi_with_stream('你能做什么', 1) - dsr.multi_with_stream('我的上一个问题是什么?请直接返回问题,不要有多余输出及思考过程', 1) - dsr.multi_with_stream('我的第一个问题是什么?请直接返回问题,不要有多余输出及思考过程', 1) - - ########## 测试 多轮对话-相机选择 ######### - dsr.multi_with_tool_call_stream('播放南卡口相机', 1) - dsr.multi_with_tool_call_stream('1', 1) - - - # print(dsr.invoke_with_tool_call('今天昆明天怎么样')) - ########## 测试 function call ######### - # print(dsr.invoke_with_tool_call('播放南卡口相机')) - ## [{'name': 'play_video', 'args': {'camera_name': '北卡口1号道相机'}, 'id': 'call_apnb8fiqdkaz313katcs3tjf', 'type': 'tool_call'}] + # 1.参数提取 + dsr.multi_with_tool_call_stream('播放北卡口入境1号道录像,从今天凌晨1点到2点', 1) + # dsr.multi_with_tool_call_stream('查看成都天府k00航班2004年1月1日入境预报航班人员明细', 1) + # 2.参数修正 # dsr.multi_with_tool_call_stream('将大屏切换为-1分屏', 1) - ## [{'name': 'split_screen', 'args': {'split_n': 2}, 'id': 'call_2o7c94f591xag8p6lcyice9q', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool('播放北卡口入境1号道录像,从今天到2025-03-16 02:09:31')) - ## 由于大模型没有联网,所以无法判断‘今天’ - ## [{'name': 'play_video_record', 'args': {'camera_name': '北卡口入境1号道', 'start_time': '2023-10-25 00:00:00', 'end_time': '2025-03-16 02:09:31'}, 'id': 'call_6gllr9wofeaoomgiz13bgnk6', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool('播放北卡口入境1号道录像,从25年3月1号到2号')) - ## [{'name': 'play_video_record', 'args': {'camera_name': '北卡口入境1号道', 'start_time': '2025-03-01 00:00:00', 'end_time': '2025-03-02 23:59:59'}, 'id': 'call_qj78jpep6k5wjwo90dkrz4qt', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool('播放北卡口入境1号从25年3月1号到2号的录像')) - ## [{'name': 'play_video_record', 'args': {'camera_name': '北卡口入境1号相机', 'start_time': '2025-03-01 00:00:00', 'end_time': '2025-03-02 23:59:59'}, 'id': 'call_ixpyke880tdhopv27c6moci0', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool('跳转到首页')) - ## [{'name': 'switch_page', 'args': {'page_name': '首页'}, 'id': 'call_3ev11bjkyrqyzxaman3402az', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool('打开日志')) - ## [{'name': 'switch_page', 'args': {'page_name': '系统日志'}, 'id': 'call_acwy2yk7xz3bgpt28suujca2', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool('放大地图到2级')) - ## [{'name': 'zoom_in', 'args': {'level_n': 2}, 'id': 'call_ip1kang0lbr63y8gya8nrpwc', 'type': 'tool_call'}] - # print(dsr.invoke_with_tool_call('查看成都天府k00航班2004年1月1日入境预报航班人员明细')) - ## [{'name': 'view_flight_details', 'args': {'airport_name': '成都天府机场', 'flight_code': 'K00', 'flight_date': '2004-01-01', 'ie_type': '入境'}, 'id': 'call_igummeorjq4r2pqjyr9tq6xq', 'type': 'tool_call'}] + # 3.多轮对话 + # dsr.multi_with_stream('你是什么模型?请简要回答', 1) + # dsr.multi_with_stream('你能做什么?请简要回答', 1) + # dsr.multi_with_stream('我的上一个问题是什么?请直接返回问题,不要有多余输出及思考过程', 1) + # dsr.multi_with_stream('我的第一个问题是什么?请直接返回问题,不要有多余输出及思考过程', 1) + + # 多轮对话-多个相机 + # dsr.multi_with_tool_call_stream('播放南卡口相机', 1) + # dsr.multi_with_tool_call_stream('1', 1)