当前位置:   article > 正文

AI大模型全栈工程师|Function Calling笔记

ai大模型全栈工程师

目录

action

ActionsGPT

ai-plugin.json

tool参数

计算加法

获取位置和查找位置,多fuction

配置函数功能

nl2sql

tool代码

函数

流式输出

代码

ChatGLM3-6B

NLP算法工程师视角:


action

这个功能非常强大,让GPT的使用方式变得更加多样化。通过Actions,我们可以访问各种API,比如天气查询和日历查询等。但今天,我要介绍的不只是这些小功能。 Zapier的官方介绍中提到,GPT的Zapier AI Actions可以让您在超过6,000个应用程序中进行超过20K次的搜索和操作,这赋予了GPT超能力。也就是说,这个功能非常强大,有很多种玩法!

ActionsGPT

第一次使用此功能,你需要转到“Create a GPT”部分。选择“Configure”-“Create new action”,然后你可以从 ActionsGPT 获得帮助。

点击“Keep in sidebar”将ActionsGPT保持在左侧,方便后续直接进入。

主要它的功能:

1. 解析cURL命令:我可以从提供的cURL命令中提取信息,并根据这些信息创建一个OpenAPI规范。

2. 理解代码片段:如果你提供一个关于如何与一个URL交互的代码片段,我可以从中提炼出必要的信息,以创建一个对应的OpenAPI规范。

3. 处理API描述:即便没有具体的代码或命令,只要你能描述如何与一个API交互(比如HTTP方法、路径、请求和响应的结构等),我也能据此创建一个OpenAPI规范。

4. 浏览和解析在线API文档:如果有在线的API文档,我可以浏览这些文档来理解API的细节,并据此创建一个OpenAPI规范。

5. 创建和调整OpenAPI规范:我可以为每个API操作创建规范,包括operationId(操作ID,用于唯一标识每个操作),并确保规范的有效性。

6. 调试和修改规范:在创建规范后,如果需要进行调整或解决问题,我可以帮助修改和调试OpenAPI规范。

7. 提供详细说明:我会详细阐述创建的OpenAPI规范的每个部分,以帮助用户理解和使用它。

ai-plugin.json

  1. "schema_version": "v1", //配置文件版本
  2. "name_for_human": "Sport Stats", //插件名字,给用户看的名字
  3. "name_for_model": "sportStats", //插件名字,给ChatGPT模型看的名字,需要唯一
  4. "description_for_human": "Get current and historical stats for sport players and games.", //描述插件的功能,这个字段是在插件市场展示给用户看的
  5. "description_for_model": "Get current and historical stats for sport players and games. Always display results using markdown tables.", //描述插件的功能,ChatGPT会分析这个字段,确定什么时候调用你的插件
  6. "auth": {
  7. "type": "none" //这个是API认证方式,none 代表不需要认证
  8. },
  9. "api": {
  10. "type": "openapi",
  11. "url": "PLUGIN_HOSTNAME/openapi.yaml" //这个是Swagger API文档地址,ChatGPT通过这个地址访问我们的api文档
  12. },
  13. "logo_url": "PLUGIN_HOSTNAME/logo.png", //插件logo地址
  14. "contact_email": "support@example.com", //插件官方联系邮件
  15. "legal_info_url": "https://example.com/legal" //与该插件相关的legal information

openapi.yaml

  1. openapi: 3.0.1
  2. info:
  3. title: Sport Stats
  4. description: Get current and historical stats for sport players and games.
  5. version: "v1"
  6. servers:
  7. - url: PLUGIN_HOSTNAME
  8. paths:
  9. /players:
  10. get:
  11. operationId: getPlayers
  12. summary: Retrieves all players from all seasons whose names match the query string.
  13. parameters:
  14. - in: query
  15. name: query
  16. schema:
  17. type: string
  18. description: Used to filter players based on their name. For example, ?query=davis will return players that have 'davis' in their first or last name.
  19. responses:
  20. "200":
  21. description: OK
  22. /teams:
  23. get:
  24. operationId: getTeams
  25. summary: Retrieves all teams for the current season.
  26. responses:
  27. "200":
  28. description: OK
  29. /games:
  30. get:
  31. operationId: getGames
  32. summary: Retrieves all games that match the filters specified by the args. Display results using markdown tables.
  33. parameters:
  34. - in: query
  35. name: limit
  36. schema:
  37. type: string
  38. description: The max number of results to return.
  39. - in: query
  40. name: seasons
  41. schema:
  42. type: array
  43. items:
  44. type: string
  45. description: Filter by seasons. Seasons are represented by the year they began. For example, 2018 represents season 2018-2019.
  46. - in: query
  47. name: team_ids
  48. schema:
  49. type: array
  50. items:
  51. type: string
  52. description: Filter by team ids. Team ids can be determined using the getTeams function.
  53. - in: query
  54. name: start_date
  55. schema:
  56. type: string
  57. description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or after this date.
  58. - in: query
  59. name: end_date
  60. schema:
  61. type: string
  62. description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or before this date.
  63. responses:
  64. "200":
  65. description: OK
  66. /stats:
  67. get:
  68. operationId: getStats
  69. summary: Retrieves stats that match the filters specified by the args. Display results using markdown tables.
  70. parameters:
  71. - in: query
  72. name: limit
  73. schema:
  74. type: string
  75. description: The max number of results to return.
  76. - in: query
  77. name: player_ids
  78. schema:
  79. type: array
  80. items:
  81. type: string
  82. description: Filter by player ids. Player ids can be determined using the getPlayers function.
  83. - in: query
  84. name: game_ids
  85. schema:
  86. type: array
  87. items:
  88. type: string
  89. description: Filter by game ids. Game ids can be determined using the getGames function.
  90. - in: query
  91. name: start_date
  92. schema:
  93. type: string
  94. description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or after this date.
  95. - in: query
  96. name: end_date
  97. schema:
  98. type: string
  99. description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or before this date.
  100. responses:
  101. "200":
  102. description: OK
  103. /season_averages:
  104. get:
  105. operationId: getSeasonAverages
  106. summary: Retrieves regular season averages for the given players. Display results using markdown tables.
  107. parameters:
  108. - in: query
  109. name: season
  110. schema:
  111. type: string
  112. description: Defaults to the current season. A season is represented by the year it began. For example, 2018 represents season 2018-2019.
  113. - in: query
  114. name: player_ids
  115. schema:
  116. type: array
  117. items:
  118. type: string
  119. description: Filter by player ids. Player ids can be determined using the getPlayers function.
  120. responses:
  121. "200":
  122. description: OK

tool参数

计算加法

  1. tools=[{ # 用 JSON 描述函数。可以定义多个。由大模型决定调用谁。也可能都不调用
  2. "type": "function",
  3. "function": {
  4. "name": "sum",
  5. "description": "加法器,计算一组数的和",
  6. "parameters": {
  7. "type": "object",
  8. "properties": {
  9. "numbers": {
  10. "type": "array",
  11. "items": {
  12. "type": "number"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }],

获取位置和查找位置,多fuction

  1. tools=[{
  2. "type": "function",
  3. "function": {
  4. "name": "get_location_coordinate",
  5. "description": "根据POI名称,获得POI的经纬度坐标",
  6. "parameters": {
  7. "type": "object",
  8. "properties": {
  9. "location": {
  10. "type": "string",
  11. "description": "POI名称,必须是中文",
  12. },
  13. "city": {
  14. "type": "string",
  15. "description": "POI所在的城市名,必须是中文",
  16. }
  17. },
  18. "required": ["location", "city"],
  19. }
  20. }
  21. },
  22. {
  23. "type": "function",
  24. "function": {
  25. "name": "search_nearby_pois",
  26. "description": "搜索给定坐标附近的poi",
  27. "parameters": {
  28. "type": "object",
  29. "properties": {
  30. "longitude": {
  31. "type": "string",
  32. "description": "中心点的经度",
  33. },
  34. "latitude": {
  35. "type": "string",
  36. "description": "中心点的纬度",
  37. },
  38. "keyword": {
  39. "type": "string",
  40. "description": "目标poi的关键字",
  41. }
  42. },
  43. "required": ["longitude", "latitude", "keyword"],
  44. }
  45. }
  46. }],

根据格式,找到重要变量,中文描述

配置函数功能

  1. import requests
  2. amap_key = "6d672e6194caa3b639fccf2caf06c342"
  3. def get_location_coordinate(location, city="北京"):
  4. url = f"https://restapi.amap.com/v5/place/text?key={amap_key}&keywords={location}&region={city}"
  5. print(url)
  6. r = requests.get(url)
  7. result = r.json()
  8. if "pois" in result and result["pois"]:
  9. return result["pois"][0]
  10. return None
  11. def search_nearby_pois(longitude, latitude, keyword):
  12. url = f"https://restapi.amap.com/v5/place/around?key={amap_key}&keywords={keyword}&location={longitude},{latitude}"
  13. print(url)
  14. r = requests.get(url)
  15. result = r.json()
  16. ans = ""
  17. if "pois" in result and result["pois"]:
  18. for i in range(min(3, len(result["pois"]))):
  19. name = result["pois"][i]["name"]
  20. address = result["pois"][i]["address"]
  21. distance = result["pois"][i]["distance"]
  22. ans += f"{name}\n{address}\n距离:{distance}米\n\n"
  23. return ans

其中涉及了key,也可以单纯用python工具,学会判断json中的值

nl2sql

tool代码

  1. tools=[{ # 摘自 OpenAI 官方示例 https://github.com/openai/openai-cookbook/blob/main/examples/How_to_call_functions_with_chat_models.ipynb
  2. "type": "function",
  3. "function": {
  4. "name": "ask_database",
  5. "description": "Use this function to answer user questions about business. \
  6. Output should be a fully formed SQL query.",
  7. "parameters": {
  8. "type": "object",
  9. "properties": {
  10. "query": {
  11. "type": "string",
  12. "description": f"""
  13. SQL query extracting info to answer the user's question.
  14. SQL should be written using this database schema:
  15. {database_schema_string}
  16. The query should be returned in plain text, not in JSON.
  17. The query should only contain grammars supported by SQLite.
  18. """,
  19. }
  20. },
  21. "required": ["query"],
  22. }
  23. }
  24. }],
  25. database_schema_string = """
  26. CREATE TABLE orders (
  27. id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
  28. customer_id INT NOT NULL, -- 客户ID,不允许为空
  29. product_id STR NOT NULL, -- 产品ID,不允许为空
  30. price DECIMAL(10,2) NOT NULL, -- 价格,不允许为空
  31. status INT NOT NULL, -- 订单状态,整数类型,不允许为空。0代表待支付,1代表已支付,2代表已退款
  32. create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间,默认为当前时间
  33. pay_time TIMESTAMP -- 支付时间,可以为空
  34. );
  35. """

函数

  1. def ask_database(query):
  2. cursor.execute(query)
  3. records = cursor.fetchall()
  4. return records
  5. prompt = "上个月的销售额"
  6. # prompt = "统计每月每件商品的销售额"
  7. # prompt = "哪个用户消费最高?消费多少?"
  8. messages = [
  9. {"role": "system", "content": "基于 order 表回答用户问题"},
  10. {"role": "user", "content": prompt}
  11. ]
  12. response = get_sql_completion(messages)
  13. if response.content is None:
  14. response.content = ""
  15. messages.append(response)
  16. print("====Function Calling====")
  17. print(response)
  18. if response.tool_calls is not None:
  19. tool_call = response.tool_calls[0]
  20. if tool_call.function.name == "ask_database":
  21. arguments = tool_call.function.arguments
  22. args = json.loads(arguments)
  23. print("====SQL====")
  24. print(args["query"])
  25. result = ask_database(args["query"])
  26. print("====DB Records====")
  27. print(result)
  28. messages.append({
  29. "tool_call_id": tool_call.id,
  30. "role": "tool",
  31. "name": "ask_database",
  32. "content": str(result)
  33. })
  34. response = get_sql_completion(messages)
  35. print("====最终回复====")
  36. print(response.content)

流式输出

stream参数=true  与tool参数同级

ChatGPT 流式输出是指 ChatGPT 在处理输入时,可以逐步生成回复,而不是一次性返回整个回复。这种输出方式对于处理长输入或复杂问题特别有用,因为它可以让我们更快地得到初步的回复,而不是等待整个回复生成完成。

流式输出的一个主要优点是它可以提高用户体验,让用户感觉系统响应更快。此外,对于一些应用场景,如实时对话或交互式应用程序,流式输出可以提供更自然的交互方式。

总的来说,ChatGPT 流式输出是一个有用的功能,可以让用户更快地得到初步回复,提高用户体验,适用于实时对话和交互式应用程序。

如果进行流式输出,必须对token进行拼接,拼接完毕才能去做后面的事情

代码

  1. # 需要把 stream 里的 token 拼起来,才能得到完整的 call
  2. for msg in response:
  3. delta = msg.choices[0].delta
  4. if delta.tool_calls:
  5. if not function_name:
  6. function_name = delta.tool_calls[0].function.name
  7. args_delta = delta.tool_calls[0].function.arguments
  8. print(args_delta)
  9. args = args + args_delta
  10. elif delta.content:
  11. text_delta = delta.content
  12. print(text_delta)
  13. text = text + text_delta

ChatGLM3-6B

官方文档:https://github.com/THUDM/ChatGLM3/blob/main/tool_using/README.md

- 最著名的国产开源大模型,生态最好

- 早就使用 `tools` 而不是 `function` 来做参数,其它和 OpenAI 1106 版之前完全一样


NLP算法工程师视角:


<li>模型砍大面,规则修细节</li>
<li>一个模型搞不定的问题,拆成多个解决</li>
<li>评估算法的准确率(所以要先有测试集,否则别问「能不能做」)</li>
<li>评估 bad case 的影响面</li>
<li>算法的结果永远不是100%正确的,建立在这个假设基础上推敲产品的可行性</li>


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/910552
推荐阅读
相关标签
  

闽ICP备14008679号