总结:
来到国创学到了很多,遇到了很多温暖厉害的人,非常幸运,希望项目越做越好,大家开开心心,事业顺利~
本周知识清单:
- 大模型多意图识别和functioning call
- api调用大模型测试
- 工具调用助手探索
- 问题总结
关键记录:
大模型多意图识别和functioning call
多意图识别
dify上创建了一个agent
如果用lamma3.1,提示词换了很多种,效果都不太好,而且右上角的agent设置里面有提示词,并且页面改不了,换成gpt4o效果就好很多,能实现多意图识别。
以下是工具:
输出结果,并且显示调用的工具:
下面是做的一些尝试,效果一般,仅供参考:
1. 开始,输入场景参数:text
车型架构意图识别:
根据
要知道顾客的意图是什么,并询问具体细节
下面是示例:
输入:开发一个动力性的车型架构,请给我一个参考模板
输出:请问你的车型架构是什么类型?
2.灵敏度参数选择:你是一个参数选择模型。根据
的内容对应的场景,找到对应的10-20个敏感性参数,并提取最重要的3个参数并得到取值范围,即上下界。
3.工况表输入设计:你是一个表格生成大模型,根据
内的参数和取值范围,等差地生成10-50次对应试验的参数列表
4.仿真api:
5.二次报表内容生成:你是一个报表加工和生成的大模型。根据输入的报表进行二次加工得到新的列,并生成新的报表文本。
根据
中输出的报表和
对应的场景进行二次加工,得到新有助于该场景分析的列,并生成新的报表文本。
报表第一行发动机功率的值是60千瓦,车重的值是4吨。第2行发动机功率的值是80千瓦,车重的值是5吨。这2个参数如何处理能生成新的有用的参数作为新的列。输出新的报表,以表格的形式展示。
6.代码-实现文本转报表
7.结束
完成下列目标的提示词怎么写:输入是:开发一个动力性的车型架构,请给我一个参考模板。这类的话语,期望输出的是:请问你的车型架构是什么类型?需要筛选出几个参数?
比如输入:开发一个动力性的车型架构,请给我一个参考模板。输出:请问你的车型架构是什么类型?需要筛选出几个参数?
下面是示例:
<example>
输入:开发一个动力性的车型架构,请给我一个参考模板
输出:请问你的车型架构是什么类型?需要筛选出几个参数?
</example>
用户查询的意图一共有2类,具体的意图如下:
<intent_list>
• api名称,以及对应api链接和 url密钥查询:
1.根据输入文本查找对应api名称:api_name
2.根据api名称:api_name查找上面数据库的对应api链接:api_url和 url密钥:url_key
即输出的格式是:api_name-api_url-url_key
• 未知意图:other。根据当前问题判断不出相关意图。
</intent_list>
现在请先对用户的问题进行问题意图分类以及信息抽取。根据用户问题生成一个json格式的结果。意图判断的要求要求如下:
<instructions>• 最终的输出采用json格式,intent是必须的字段• 在判断意图的同时,需要抽取问题中根数据库字段相关的属性,只输出能抽取到的相关属性• 如果你判断不出具体的意图,返回other• 最后只返回json结果,不需要返回其他说明,包裹在``json``中• 如果意图是search_name_with_attribute,返回结果中必须有,intent和name
</instructions>
这里是相关的示例:
<example>
question : 上海第一人民医院。
answer : {{ "intent":"search_name", "name" : "上海第一人民医院"}}
question : 延安西路上的中山医院有哪家。
answer : {{ "intent":"search_name_with_attribute", "address":"延安西路", "name": "中山医院"}}
question : 杨浦区的门诊部有哪些。
answer : {{ "intent": "search_with_attribute", "organization_type_name" : "门诊部", "county_name" : "杨浦区"}}question : HOSPITAL_JS。answer : {{ "intent": "ohter"}}question : 龙华春都路药店。answer : {{ "intent":"search_with_attribute", "county_name" : "龙华区", "address": "春都路", "root_organization_type_name" : "药店"}}question : 静安柳营路。answer : {{ "intent":"search_with_attribute", "address": "柳营路", "county_name" : "静安区",}}
</example>
请根据用户的问题,判断用户的意图并抽取相关信息,最终的输出只输出json结果,包裹在``json``中。
示例1:
<example>
输入:北京天气怎么样
执行步骤:
1.调用工具: 天气查询-gaode
2.在gaode工具中输入要查询的城市:北京
输出:北京天气晴、风力4级,温度在15-24摄氏度。调用了gaode工具。
</example>
示例2:
<example>
输入:hanyan huang的论文有哪些?
执行步骤:
1.调用工具: 论文查询-arxiv
2.在arxiv工具中输入要查询的论文的作者参数:hanyan huang
输出:hanyan huang的论文一共有3篇,分别是:1.dhiufahbhdak2.fhkdhfa3.ask you 。调用了arxiv工具。
</example>
示例3:
<example>
输入:2+3的结果是多少?
执行步骤:
1.调用工具: 数学表达式计算-maths
输出:2+3=5 。调用了maths工具。
</example>
工具名称列表如下:
<table>
• api_name : api名称, # values: arxiv | yahoo | webscarper | code | maths | gaode |
• api_fun : api功能,# values: 论文查询 | 查询股票 | 网页搜索 |代码解释 | 数学表达式运算 | 天气查询 |
</table>
步骤为:
<step>
step1:根据用户的输入查询上面表格的api_fun : api功能这一行,是否有匹配的功能;
step2:如果有则查询相关的 api_name : api名称,并调用工具栏中对应的工具,输出“action_result”的结果;
step3:如果没有,则返回这是未知意图,请输入更准确的描述。
</step>
你可以使用以下工具:
[{"name": "arxiv_search", "description": "A tool for searching scientific papers and articles from the Arxiv repository. Input can be an Arxiv ID or an author's name.", "parameters": {"type": "object", "properties": {"query": {"type": "string", "description": "The Arxiv ID or author's name used for searching."}}, "required": ["query"]}}, {"name": "yahoo_finance_ticker", "description": "A tool for search ticker information from Yahoo Finance. Input should be the ticker symbol like AAPL.", "parameters": {"type": "object", "properties": {"symbol": {"type": "string", "description": "The ticker symbol of the company you want to search."}}, "required": ["symbol"]}}, {"name": "webscraper", "description": "A tool for scraping webpages. Input should be a URL.", "parameters": {"type": "object", "properties": {"url": {"type": "string", "description": "url for scraping"}}, "required": ["url"]}}, {"name": "simple_code", "description": "A tool for running code and getting the result back. Only native packages are allowed, network/IO operations are disabled. and you must use print() or console.log() to output the result or result will be empty.", "parameters": {"type": "object", "properties": {"language": {"type": "string", "description": "language of the code, only "python3" and "javascript" are supported"}, "code": {"type": "string", "description": "code to be executed, only native packages are allowed, network/IO operations are disabled."}}, "required": ["language", "code"]}}, {"name": "eval_expression", "description": "A tool for evaluating an math expression.", "parameters": {"type": "object", "properties": {"expression": {"type": "string", "description": ""}}, "required": ["expression"]}}, {"name": "gaode_weather", "description": "A tool when you want to ask about the weather or weather-related question.", "parameters": {"type": "object", "properties": {"city": {"type": "string", "description": "If you don't know you can extract the city name from the question or you can replyʒPlease tell me your city. You have to extract the Chinese city name from the question."}}, "required": ["city"]}}]
Respond to the human as helpfully and accurately as possible. {{instruction}} You have access to the following tools: {{tools}} Use a json blob to specify a tool by providing an {{TOOL_NAME_KEY}} key (tool name) and an {{ACTION_INPUT_KEY}} key (tool input). Valid "{{TOOL_NAME_KEY}}" values: "Final Answer" or {{tool_names}} Provide only ONE action per $JSON_BLOB, as shown: ``` { "{{TOOL_NAME_KEY}}": $TOOL_NAME, "{{ACTION_INPUT_KEY}}": $ACTION_INPUT } ``` Follow this format: Question: input question to answer Thought: consider previous and subsequent steps Action: ``` $JSON_BLOB ``` Observation: action result ... (repeat Thought/Action/Observation N times) Thought: I know what to respond Action: ``` { "{{TOOL_NAME_KEY}}": "Final Answer", "{{ACTION_INPUT_KEY}}": "Final response to human" } ``` Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.
使用一个 JSON 数据块来指定一个工具,通过提供一个“{{TOOL_NAME_KEY}}”键(工具名称)和一个“{{ACTION_INPUT_KEY}}”键(工具输入)。
有效的“{{TOOL_NAME_KEY}}”值为:“最终答案”或{{tool_names}}。
在每个 JSON 数据块中仅提供一个行动,如下所示:
开始!提醒始终以单个行动的有效 JSON 数据块进行回应。如果有必要,请使用工具。如果合适,直接回应。格式为行动:$JSON_BLOB,然后观察:
你是一个回答问题和调用工具的中文机器人,目的是根据用户的问题,从工具中使用相应的工具回答用户的查询问题。
只需要输出使用完工具的输出结果就行,不要显示中间过程。
-------------------------------
问题1: 北京天气怎么样
思考:考虑先前和后续步骤
行动:
{
"action": gaode_weather,
"action_input": 北京
}
观察:行动结果
...(重复思考/行动/观察 3次)
思考:我知道要如何回应
行动:
{
"tool_name": "最终答案",
"answer": "给人类的最终回应"
}
回答:北京天气晴、风力4级,温度在15-24摄氏度
------------------------------------------------------
问题2: hanyan huang的论文有哪些?
思考:考虑先前和后续步骤
行动:
{
"action": arxiv_search,
"action_input": hanyan huang的论文有哪些?
}
观察:行动结果
...(重复思考/行动/观察 3次)
思考:我知道要如何回应
行动:
{
"tool_name": "最终答案",
"answer": "给人类的最终回应"
}
回答:hanyan huang的论文有3篇分别是。。。。
---------------------------------------------------
问题3: 2+3的结果是多少?
思考:考虑先前和后续步骤
行动:
{
"action": eval_expression,
"action_input": 2+3的结果是多少?
}
观察:行动结果
...(重复思考/行动/观察 3次)
思考:我知道要如何回应
行动:
{
"tool_name": "最终答案",
"answer": "给人类的最终回应"
}
回答:2+3=5
---------------------------------------------------
但是输进去效果不是很好,可能是大模型的问题,用的llama3.1。
functioning call函数调用实例
以智谱为例,ChatGLM 的函数调用功能可以增强模型推理效果或进行其他外部操作,包括信息检索、数据库操作、知识图谱搜索与推理、操作系统、触发外部操作等工具调用场景。
(1)外部函数工具tools,包含了2个函数介绍:
假设我们要创建一个具备查询航班功能的聊天机器人。我们定义如下两个外部函数供模型选择调用:
- 1. 查询两地之间某日航班号函数:get_flight_number(departure: str, destination: str, date: str)
- 2. 查询某航班某日票价函数:get_ticket_price(flight_number: str, date: str)
tools = [
{
"type": "function",
"function": {
"name": "get_flight_number",
"description": "根据始发地、目的地和日期,查询对应日期的航班号",
"parameters": {
......
},
}
},
{
"type": "function",
"function": {
"name": "get_ticket_price",
"description": "查询某航班在某日的票价",
"parameters": {
......
},
}
},
]
(2)函数输入参数格式:
上面的parameters字段需要传入一个 Json Schema 对象,以准确地定义函数所接受的参数。
- description :说明函数方法的用途。
- type :定义 JSON 数据的数据类型约束。
- properties:一个Object,其中的每个属性代表要定义的 JSON 数据中的一个键。
- required:指定哪些属性在数据中必须被包含。
- enum:如果一个属性是枚举类型,则此字段应当设置为枚举值的数组。
则完整的tools字段设置为:
tools = [
{
"type": "function",
"function": {
"name": "get_flight_number",
"description": "根据始发地、目的地和日期,查询对应日期的航班号",
"parameters": {
"type": "object",
"properties": {
"departure": {
"description": "出发地",
"type": "string"
},
"destination": {
"description": "目的地",
"type": "string"
},
"date": {
"description": "日期",
"type": "string",
}
},
"required": [ "departure", "destination", "date" ]
},
}
},
{
"type": "function",
"function": {
"name": "get_ticket_price",
"description": "查询某航班在某日的票价",
"parameters": {
"type": "object",
"properties": {
"flight_number": {
"description": "航班号",
"type": "string"
},
"date": {
"description": "日期",
"type": "string",
}
},
"required": [ "flight_number", "date"]
},
}
},
]
在 tools 参数中,如果填写了 functions 参数,则默认情况下模型将决定何时适合使用其中一个函数。 如果要控制模型如何选择函数调用,需要设置 tool_choice 参数。参数默认值为auto,此时模型根据上下文信息自行选择是否返回函数调用。将其设置为 {"name": "your_function_name"} 时,可以强制 API 返回特定函数的调用。还可以通过将 tool_choice 参数设置为 "none" 来强制 API 不返回任何函数的调用。目前智谱函数调用仅支持 auto 模式。
下面是gpt可以调用的的参数
none
:告诉模型不要调用我们自己任何的函数auto
:让模型自行决定是否调用、调用什么函数具体函数名
:让gpt只考虑是否调用xx具体函数
(3)具体函数设置
def get_flight_number(date:str , departure:str , destination:str):
flight_number = {
"北京":{
"上海" : "1234",
"广州" : "8321",
},
"上海":{
"北京" : "1233",
"广州" : "8123",
}
}
return { "flight_number":flight_number[departure][destination] }
def get_ticket_price(date:str , flight_number:str):
return {"ticket_price": "1000"}
(4)定义处理 Function call 的函数
def parse_function_call(model_response,messages):
# 处理函数调用结果,根据模型返回参数,调用对应的函数。
# 调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型
# 模型会将函数调用结果以自然语言格式返回给用户。
if model_response.choices[0].message.tool_calls:
tool_call = model_response.choices[0].message.tool_calls[0]
args = tool_call.function.arguments
function_result = {}
if tool_call.function.name == "get_flight_number":
function_result = get_flight_number(**json.loads(args))
if tool_call.function.name == "get_ticket_price":
function_result = get_ticket_price(**json.loads(args))
messages.append({
"role": "tool",
"content": f"{json.dumps(function_result)}",
"tool_call_id":tool_call.id
})
response = client.chat.completions.create(
model="glm-4", # 填写需要调用的模型名称
messages=messages,
tools=tools,
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())
(5)查询北京到广州的航班:
# 清空对话
messages = []
messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"})
messages.append({"role": "user", "content": "帮我查询1月23日,北京到广州的航班"})
response = client.chat.completions.create(
model="glm-4", # 填写需要调用的模型名称
messages=messages,
tools=tools,
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())
parse_function_call(response,messages)
返回
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8282666790542042140', function=Function(arguments='{"date":"2023-01-23","departure":"北京","destination":"广州"}', name='get_flight_number'), type='function')]
content='根据您的要求,我已经查询到了1月23日从北京到广州的航班号,航班号为8321。' role='assistant' tool_calls=None
(6)查询1234航班票价:
messages.append({"role": "user", "content": "这趟航班的价格是多少?"})
response = client.chat.completions.create(
model="glm-4", # 填写需要调用的模型名称
messages=messages,
tools=tools,
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())
parse_function_call(response,messages)
返回
content=None role='assistant' tool_calls=[CompletionMessageToolCall(id='call_8282666893621289712', function=Function(arguments='{"date":"2023-01-23","flight_number":"8321"}', name='get_ticket_price'), type='function')]
content='这趟航班的票价为1000元。' role='assistant' tool_calls=None
api调用大模型测试
dify对话中通过写提示词看能否识别正确的api,并给出满意的回答。以下是我的主观评分:
大模型 | 数学表达式计算 | 查论文 | 编写代码 | 查股票 | 查天气 | 查《劳动法》知识库 |
千问2-72B | 8 | 1 | 1 | 3 | 5 | 9(但是没显示引用) |
智谱glm-9B | 1 | 9 | 5 | 2 | 9 | 7(默认英文,翻译之后内容变化) |
gpt4o | 9 | 9 | 9 | 9 | 9 | 9(但是没显示引用) |
llama3.1 | 3 | 1 | 5 | 2 | 2 | 1(只能引用,回答离谱) |
千问查论文一直在迭代:
写代码不行,识别不出来编写代码的意图:
智谱:查论文可以:
代码不行:
要指定语言:
运行代码,结果是错的:
工具调用助手探索
AIPC:
AIPC/README_ZH.md at master · mMrBun/AIPC (github.com)
Chat2BI:
xiaowuzicode/Chat2BI: 大佬写的可以参考 (github.com)
在linux服务器上运行,由于没有建虚拟环境,各种包版本冲突,后面在windows本地在pycharm运行,显示有个包没安装对
按照要求运行还是报错,还有2个警告;
发现可能是rust环境没配置
参考:
rust前需要安装MinGW-w64,参考,可能又部分步骤不太一样,但是大致是一致的
MinGW-w64的安装及配置教程_mingw64-CSDN博客
总之大概下了这么多东西(有的可能不用下):
下载之后结果:
C:\Users\admin\PycharmProjects\api\.venv\Lib\site-packages\pydantic\_internal\_fields.py:163: UserWarning: Field "model_type" has conflict with protected namespace "model_".
You may be able to resolve this warning by setting `model_config['protected_namespaces'] = ()`.
warnings.warn(
INFO: Started server process [34772]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:7861 (Press CTRL+C to quit)
注意是post请求,具体请求的格式还需要学习一下。
问题总结
- dify代码编写模块导入python自带的包是可以的,但是新的包在前端无法导入,需要改后端代码。
- dify编写模块经常运行不了的原因是函数输出类型必须跟下面”输出变量“的类型一样,输出的是json格式,那个"result"后面不要改。
- 生成文档的,路径在哪
直接打开打不开,应该在搭dify的服务器中
3.知识库上传一直显示“排队中”
参考下载后按文档部署,运行了前后端,对话无问题,但是知识库添加后一直是排队中 · Issue #229 · langgenius/dify (github.com)不知道能不能解决。
实际上把embedding模型换成llama就好了