Files
agent_test/chat_bot.py

233 lines
9.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()