大模型LLM 应用+AI Agents框架,为我们提供了非常便利的自动化执行任务的能力。微信公众号(订阅号) 是非常适合落地各种AI Agents的场景,我们可以利用微信公众号提供的文本、图像、语音的输入,在自己服务器上部署一套API框架,把自己感兴趣的一些对话、图文、语音等能力的API封装为Agents。这里给大家介绍一个拆箱即用的微信公众号服务端框架 Flask+tencent代码库来实现,并且会利用一个简单的金融智能助理(Finance Agent)的例子来实现一个根据用户输入来查询实时股价,并且返回给微信公众号用户的功能,支持更加复杂定制的AI Agents业务逻辑。
一键部署图文回复的Demo
AI Agents API调用实现查询股价功能的Demo
开发一个微信公众号(订阅号)的自动回复和AI Agents需要下列准备,包括:
安装环境可以执行下列命令
pip install flask tencent
微信开发平台上例子,第一次部署可能要花比较长时间,中间缺少debug信息需要尝试很多次。
https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html
这里提供了封装好亲自测试一分钟可以成功跑通的基础类和Flask Server的执行脚本,复杂应用也可以在这个基础类上进行修改。从github上下载例子拆箱即用 main.py文件地址
地址:https://github.com/AI-Hub-Admin/tencent/blob/main/examples/wechat/main.py
wget https://github.com/AI-Hub-Admin/tencent/blob/main/examples/wechat/main.py
python main.py
部署好服务之后,可以通过浏览器访问 http://127.0.0.1:80/wx_home 查看是否部署成功。如果可以看到Hello World的一个html页面就代表服务部署成功了。给微信提供验证的服务入口在 (http://127.0.0.1:80/wx)。
下一步就要在微信官方平台,验证你的服务器可以给公众号提供服务了。
需要保存好
1. 你对外提供的URL: http://{your_ip_address}/wx (80端口从URL里省去)
2. 一个验证用的token,例子代码中 token="dummy",需要填写在下一端的对应位置,你可以修改wechat_constants.py 文件中对应变量
详细的注册和开发流程参考微信公众号开发文档(https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html),但是因为自己第一次部署很容易配置失败,这里给大家分享一些拆箱即用的可以直接上手跑的例子。
官方网址 (https://mp.weixin.qq.com/) 个人开发者可以先选择订阅号,服务号和企业号都需要公司营业执照等材料。
在导航栏选择 "设置与开发-基本配置",在"服务器" 配置项选择修改配置。这里的对话框可以选择填写你的服务端信息。
URL:填写你对外暴露服务的地址 http://{your_ip_address}/wx,token:这里先填写 dummy (对应我们的 python例子,可以后续再修改)
最后保存。当你点击保存按钮的时候,微信服务端会给你的地址发一个 GET请求来验证你拥有服务器,这里如果验证失败了,可以看看python 后台的日志如下图中 (hashcode和signature是否一致).这里验证逻辑被封装到 tencent库的 WechatServerVeriAPI.static_api函数内,感兴趣可以查看 tencent.contrib.wechat.wechat_api 这个模块。保存后点击"启用"就可以从公众号上发消息验证了。
如果部署成功了,你发送文本消息,公众号回复 "hello",如果你发送图片,公众号会把相同图片的mediaid 返回给你,达到回复用户相同图片效果。参考例子main.py文件中对基础文本回复 和 对图像回复,封装在了 WechatTextReplyBaseAPI.static_api 和 WechatImageReplyBaseAPI.static_api 这两个函数里。初次上手微信后台开发的开发者可以不用纠结于request的XML请求的格式细节,只用关注最核心的业务逻辑,获取用户输入,得到输出并返回给用户就好了。
因为填写配置错误导致 hash_code和signature计算不同,注意点:
1. URL:不能带端口,一定是固定 服务器, 不能是 http://{your_ip_address}:80/wx 或者是 https://{your_ip_address}:443/wx,这样填写是不行的。
2. token: 只能英文数字,不能有下划线,或者别的符号,这个很容易被忽略。必须为英文或数字,长度为3-32字符。 具体错误原因微信后台没有提供,我们可以从我们 python服务端日志来看出端倪。查看下列flask打印的日志,看看 hashcode 和 signature是否一致不一致就是哪里填错了。
可以参考代码库(https://github.com/AI-Hub-Admin/tencent)中 examples/tests/ 目录下的 main_finance_agent.py 例子。 微信公众号开发很多对 服务端request的输入输出格式都很复杂,为了简单上手,可以直接继承 WechatTextReplyBaseAPI 基础类,然后主要关心获取用户输入和返回给用户的核心业务逻辑就可以了。
这里金融智能助理为例,我们希望做一个可以查询股票价格的 AI Agents,我们只用自己实现核心业务逻辑就好。完整代码参考例子:
地址:https://github.com/AI-Hub-Admin/tencent/blob/main/examples/wechat/main_finance_agent.py
这个 WechatTextReplyFinanceAPI 类继承 WechatTextReplyBaseAPI 基类,我们只用关系和修改入口静态方法 static_api(args, kwargs) 和 process(self, msg) 函数实现业务逻辑就好了。
这个类代码如下,实现了查询股票代码和组装自动回复的功能,我们使用了 FinanceAgent 库(包含了港股A股美国等api请求股价的函数,也支持Agents式的 tools自动化调用):
class WechatTextReplyFinanceAPI(WechatTextReplyBaseAPI):
@staticmethod
def static_api(args, kwargs):
return WechatTextReplyFinanceAPI(None).api(args, kwargs)
def process(self, msg):
"""
input: msg is a class of Wechat sent Msg, TextMsg, ImageMsg defined in receive.py file, you can also access other input information
toUser = msg.FromUserName
fromUser = msg.ToUserName
output: str, the outer api method will process and wrap the Message Object
"""
input_text = msg.Content
# parse user intent and query stock code from input text, This example, we will use 700 for tencent as example
## implement_your_code_here
stock_info_list = fa.api(symbol_list=['700'], market="HK")
response_list = []
for stock_info in stock_info_list:
response= "%s,股价: %s, 最高价: %s, 最低价: %s, 数据更新时间: %s, 数据源: %s" % (stock_info["symbol"], stock_info["avg_price"], stock_info["high"], stock_info["low"], stock_info["update_time"], stock_info["source"])
response_list.append(response)
output_text = ";".join(response_list)
return output_text
需要重写的函数:
在Flask对应的 /wx方法的Flask 函数主入口,把原先的 WechatTextReplyBaseAPI.static_api(args=[recMsg], kwargs={}) 替换为你实现的金融服务的函数就好了。WechatTextReplyFinanceAPI.static_api(args=[recMsg], kwargs={})。点击运行,再给你的公众号发送消息。如果成功你就可以看到查询的腾讯的最新股价了。
AI智能体借助大模型LLM能力,执行流程简单描述就是:LLM 输入用户的prompt和可以执行的函数 tools (tools的概念就是把函数统一schema化让模型可以理解),返回 可以执行的函数和填充好的parameters参数。我们再根据LLM返回决策结果来直接执行这段函数代码。
首先,AI智能体借助大模型和prompt来给函数填充参数,输入给LLM的信息包括:
1. 函数的schema(包括函数名,函数参数列表,每个参数取值类型,哪些是required参数等等),
2. 用户自然语言输入的prompt。
大模型还是十分智能的,会把prompt中的相关文本抽取,结合自己知识来对参数改写 (比如 hongkong 改为HK再填充到函数里)对应的数据填充到函数的schema中。OpenAI的API 返回信息包含了function 和 对应参数 params。以openai的函数填充为例。
输入 prompt
## You can fill the function with json format, the schema for the function is {'type': 'function', 'function': {'name': 'tencent_api_base', 'description': '', 'parameters': {'type': 'object', 'properties': {'arg1': {'type': 'string'}, 'arg2': {'type': 'string'}, 'arg3': {'type': 'string'}, 'arg4': {'type': 'string'}, 'arg5': {'type': 'string'}}, 'required': ['arg1', 'arg2', 'arg3']}}}, the user inputs include arg1=10, arg2=20, arg3=30, please output the executable function values in json format, with key as 'function'
输出prompt
{
"function": {
"name": "tencent_api_base",
"parameters": {
"arg1": "10",
"arg2": "20",
"arg3": "30",
"arg4": "",
"arg5": ""
}
}
}
API调用毕竟相当于人工写死的逻辑,只能接受固定输入好的参数格式。
借助大模型我们将API直接调用转化为基于大模型的AI Agent范式。
完整的金融智能助理 AI Agents执行例子可以参考这个Tutorial 的例子。
地址:https://github.com/AI-Hub-Admin/tencent/blob/main/examples/agents/run_finance_agent_api_tools.py
a. Tool的定义函数function和参数类型
定义AI Agents执行流程,首先需要告诉大模型任务有哪些 Tools(函数or工具) 可以选择,以及用户的输入是什么。以我们构造金融助理Agent为例子,需要大模型解析的一个函数function finance_stock_price_api,明确入参类型: symbol_list 是 list类型,market 市场是string 类型。
def finance_stock_price_api(symbol_list: list, market: str):
"""
symbol_list is list of json
market is str
"""
import FinanceAgent as fa
stock_info_json = fa.api(symbol_list=symbol_list, market=market)
return stock_info_json
b. 函数function转换为LLM理解的Schema格式
利用tencent.utils.agent_utils 中的 function_to_schema 将函数转化为统一的OpenAI训练的 schema,这里不同大模型数据格式不同,具体schema需要和大模型训练时保持一致才能达到最佳效果。
from tencent.utils.agent_utils import function_to_schema
tools = [finance_stock_price_api]
tool_schemas = [function_to_schema(tool) for tool in tools]
schema是一个json格式如下
{
"type": "function",
"function": {
"name": "finance_stock_price_api",
"description": "symbol_list is list of json\n market is str",
"parameters": {
"type": "object",
"properties": {
"symbol_list": {
"type": "array"
},
"market": {
"type": "string"
}
},
"required": [
"symbol_list",
"market"
]
}
}
}
c. 输入给LLM进行Tools的决策
将可以执行的函数 Schema 和用户输入prompt 传给大模型让大模型产出需要执行函数,本质上是大模型预测了一下函数执行的最大概率并且输出最大概率的文本(相当于给函数填充了参数的槽位,得到了一个可以执行的 "字符串“)
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": instruction}],
tools=tool_schemas,
)
假设用户输入prompt是:希望查询腾讯(700) 和 快手(1024) 的港股股价
合并得到给LLM的输入为:
You can fill the function with json format, the schema for the function is {'type': 'function', 'function': {'name': 'finance_stock_price_api', 'description': 'symbol_list is list of json\n market is str', 'parameters': {'type': 'object', 'properties': {'symbol_list': {'type': 'array'}, 'market': {'type': 'string'}}, 'required': ['symbol_list', 'market']}}}, the inputs includes I am interested in Tencent(code:700) and Kuaishou (code:1024) stock price,please output the executable function values in json format, with key as 'function'
如果本地执行没有OpenAI的Key,可以尝试web端看看大模型产出结果如下,有的时候产出的Json也是有可能是错误的(大模型产出不准确有错误和幻觉),这个时候就需要业务后处理了。
{
"function": {
"name": "finance_stock_price_api",
"description": "symbol_list is list of json\n market is str",
"parameters": {
"symbol_list": [
"700",
"1024"
],
"market": "Hong Kong"
}
}
}
如何没有大模型调用环境可以把这个字符串输入然后让Agent 程序继续跑下去。
[{"function":{"name":"finance_stock_price_api","parameters":{"symbol_list":["700","1024"],"market":"HK"}}}]
最后就是执行 execute_tool_call_from_json 来具体执行返回的函数和参数值,然后保存结果到 messages 里面,我们就根据用户自然语言处理的输入,决策调用股价查询API 并且获得了结果。
def execute_tool_call_from_json(tool_call, tools_map):
"""
tool_call: json format of
{'functions': {'name': 'tencent_api_base',
'parameters': {'arg1': '10',
'arg2': '20',
'arg3': '30',
'arg4': '',
'arg5': ''}}}
"""
name = tool_call["function"]["name"]
parameters = tool_call["function"]["parameters"]
# args = json.loads(tool_call.function.arguments)
print(f"Assistant: {name}({parameters})")
# call corresponding function with provided arguments
return tools_map[name](**parameters)
这样我们就把API调用重构为了一个 AI Agents调用的范式,可以看出几点区别:
1. API调用的确定性强,缺点就是参数处理和解析定制化,都需要根据query的NLP技术理解来处理。
2.AI Agents 调用支持用户输入灵活性更强,但是输出准确性不够高。
从AI Agents 根据用户输入和备选Tools的Schema,决策可以执行函数的字符串返回流程中,执行哪个参数和执行哪个函数都是LLM根据概率模型来预测的一段可以执行代码。不用NLP解析槽位再填写到API里。但是缺点就是LLM产出的字符串可能有各种bug,需要后处理,比如json格式不对,参数填写错误等。
在这个Tutorial 我们把API封装为 tools 让LLM调用过程中,tencent包提供了API函数方便封装,以及 function_to_schema 和 execute_tool_call 的一些utils的函数方便调用。具体业务下Agents执行还要结合各自业务,来智能地来对用户提供相应服务。
https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html
https://github.com/AI-Hub-Admin/tencent
https://github.com/AI-Hub-Admin/FinanceAgent
https://github.com/AI-Hub-Admin/HealthcareAgent
https://github.com/AI-Hub-Admin/AI-Agents-Visualization
https://github.com/rockingdingo/text2video
https://github.com/rockingdingo/image2video
https://github.com/rockingdingo/text2audio
https://github.com/rockingdingo/SuperIntelligence
https://github.com/rockingdingo/SuperAlignment
http://www.deepnlp.org/store/pub
http://www.deepnlp.org/blog?category=tencent
http://www.deepnlp.org/blog?category=agent
http://www.deepnlp.org/blog/dialogue-agent-multimodal-visualization-tools-for-ai-systems
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。