import time from prompt_toolkit import prompt from openai import OpenAI from get_tianqi import get_tianqi_data from cha_xianglaing import search1 from weixin import weix import json tool_list = [ {"name":"tainqi","description":"查询天气"}, {"name":"sousuo","description":"网页搜索"}, {"name":"export_video","description":"导出视频片段"}, ] toole_details = { "tianqi":{ "type":"function", "function":{ "name":"tianqi", "description":"查询天气状况(温度、湿度、风力、天气....)时使用此tool", "strict": True, "parameters": { "type":"object", "properties":{ "city":{"type": "string", "description": "要获取天气的城市名称"} }, "required": ["city"], "additionalProperties": False } } }, } def get_tools_details(): # 获取工具详情 pass class send_message: def __init__(self, system_content: str ,tool_choice="auto"): self.ai_return = [] self.tool_choice1 = tool_choice self.messages_1 = [ {"role": "system", "content": system_content}, ] def test_openai(self): # print("111",self.messages_1) client = OpenAI(api_key="tp-cj0x379me5rqk198qnnt4n1spcdbx986jjr163gu2iiw1s7w", base_url="https://token-plan-cn.xiaomimimo.com/v1") response = client.chat.completions.create( model="mimo-v2.5-pro", messages=self.messages_1, top_p=0.5, tools=[ {"type": "function", "function": { "name": "get_tianqi", "description": "获取天气信息。当你需要回答任何与天气、气温、冷暖有关的问题时调用此工具;判断用户是否是询问温度而不是出现冷热就调用此工具,例如用户说:你这个笑话好冷,则无需调用。**必须**使用此工具来获取实时、真实的天气数据。", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称"} }, "required": ["city"], "additionalProperties": False } } },{"type": "function", "function": { "name": "get_donghua_images", "description": "用户需要查询具体动画场景时调用此工具。例如:用户说这个场景不错帮我找下,调用此工具;", "parameters": { "type": "object", "properties": { "donghua": {"type": "string", "description": "动画场景描述,必须为英文;例如:Tom is tired"}, "xiangsidu": {"type": "integer", "description": "图片与场景的相似度要求,例如:'给我相似度大于50%的图片 则传值0.5'"}, "tupianshuliang": {"type": "integer", "description": "返回图片数量,例如:'给我返回10张图片 则传值10'"}, }, "required": ["donghua"], "additionalProperties": False }} }, {"type": "function", "function": { "name": "export_video", "description": "当用户确认某张图片并要求导出视频时调用此工具。例如:'这张图不错,给我前后30秒的视频'、'导出这个场景后面5分钟'、'我要整个视频'、'帮我截取这个片段'", "parameters": { "type": "object", "properties": { "image_name": { "type": "string", "description": "用户确认的图片文件名,例如 '001 Puss Gets the Boot [1940]_05m23s_456.jpg'" }, "mode": { "type": "string", "enum": ["around", "after", "before", "total"], "description": "导出模式:around=前后各N秒,after=后N秒,before=前N秒,total=整个视频" }, "seconds": { "type": "integer", "description": "秒数,total模式下可省略,默认300秒。例如用户说'前后30秒'则传30,'前后5分钟'则传300", "default": 300 } }, "required": ["image_name", "mode","seconds"], "additionalProperties": False }} } ], tool_choice=self.tool_choice1, ) return response.choices[0].message def test_json_format(json_string): try: return json.loads(json_string) except json.JSONDecodeError: return False def get_tianqi(ai_json): print(f"正在获取{ai_json['city']}的天气信息...") return f"{get_tianqi_data(ai_json['city'])}" # m = send_message('') cont = 1 # m = send_message('你是一个个人助手,会适当使用工具') class get_ai_message: def __init__(self): self.system_content = open("猫和老鼠分镜.md", "r", encoding="utf-8").read() self.m = send_message(self.system_content) self.wx = weix() async def _handle_donghua(self, args): """处理动画图片搜索工具""" donghua = args["donghua"] xiangsidu = args.get("xiangsidu", 0) tupianshuliang = args.get("tupianshuliang", 5) re_donghua_image = search1(query_text=donghua, top_k=tupianshuliang) result_str = "" for result in re_donghua_image: if result.score < xiangsidu: continue result_str += f"相似度:{result.score},图片路径:{result.payload}\n" print(result) await self.wx.send_images(result.payload["image_path"]) return result_str if result_str else "未找到符合条件的图片" async def _handle_export_video(self, args): """处理视频导出工具""" from video_cutter import export_video_clip export_result = export_video_clip( image_name=args["image_name"], mode=args["mode"], seconds=args.get("seconds", 300) ) if export_result["success"]: await self.wx.send_video(export_result["video_path"]) return ( f"✅ 视频已导出并发送!\n" f"⏱️ 时间范围:{export_result['start_time']} -> {export_result['end_time']}\n" f"🎬 时长:{export_result['duration']}" ) else: return f"❌ 视频导出失败:{export_result['error']}" async def sen_mess(self, s_input_text): # 拼接用户消息 self.m.messages_1.append({"role": "user", "content": s_input_text}) while True: out_text = self.m.test_openai() if out_text.tool_calls: # 将 assistant 的 tool_calls 消息整体追加到 messages(转为 dict) self.m.messages_1.append({ "role": "assistant", "content": out_text.content, "tool_calls": [ { "id": tc.id, "type": "function", "function": { "name": tc.function.name, "arguments": tc.function.arguments } } for tc in out_text.tool_calls ] }) for tool_call in out_text.tool_calls: args = test_json_format(tool_call.function.arguments) tool_name = tool_call.function.name print("M调用了工具:", tool_name) tool_result = "" if tool_name == "get_tianqi": tool_result = get_tianqi(args) elif tool_name == "get_donghua_images": tool_result = await self._handle_donghua(args) elif tool_name == "export_video": tool_result = await self._handle_export_video(args) # 工具结果以 tool role 追加到 messages self.m.messages_1.append({ "role": "tool", "tool_call_id": tool_call.id, "content": tool_result }) print(f"工具 {tool_name} 返回: {tool_result[:100]}...") # 循环继续,让 LLM 看到工具结果后继续推理 elif out_text.content: # 没有工具调用,发送最终文本给用户 self.m.messages_1.append({"role": "assistant", "content": out_text.content}) await self.wx.send_text(out_text.content) print(f"小爱:{out_text.content}") return out_text.content gm = get_ai_message() bot = gm.wx.bot @bot.on_message async def echo_handler(msg): print(f"收到来自 {msg.user_id} 的消息: {msg.text}") await gm.sen_mess(msg.text) # await bot.reply(msg, f"你说了: {msg.text}") bot.run()