Plugins和function-call 使用自然语言连接一切

Plugins 是什么

学习 plugin 之前,先要了解 ChatGPT 及所有大模型都有两大缺陷:

划重点:
  1. 没有最新信息。大模型的训练周期很长,且更新一次耗资巨大,所以它的知识都是过去的。GPT-3.5 和 GPT-4 的知识截至 2021 年 9 月。
  2. 没有「真逻辑」。它表现出的逻辑、推理,是训练文本的统计规律,而不是真正的逻辑。

比如把 100 以内所有加法算式都训练给大模型,它就能回答 100 以内的加法算式。但如果问它更大数字的加法算式,它就不一定答对了。因为它并不懂「加法」,只是记住了 100 以内的加法算式的统计规律。它是用字面意义来做数学。

Plugin 能一定程度解决这两个问题。

演示:

  1. 用天气插件查询天气
  2. 用 Wolfram Alpha 插件做数学题

如果你对 Wolfram Alpha 做数学的能力感到惊讶,想了解它和 ChatGPT 原理的不同,推荐阅读这篇文章:《Wolfram|Alpha as the Way to Bring Computational Knowledge Superpowers to ChatGPT》

Plugins 的工作原理

思考:它怎么把我们的 prompt 和插件功能做匹配?

Plugins 开发

可能是史上最容易开发的 plugin。只需要定义两个文件:

  1. yourdomain.com/.well-known/ai-plugin.json,描述插件的基本信息
  2. openai.yaml,描述插件的 API

**而 OpenAI 那边,更简单,没有任何人和你对接。是 AI 和你对接!**AI 阅读上面两个文件,就知道该怎么调用你了。

看个官方例子。

ai-plugin.json

{
  "schema_version": "v1",
  "name_for_human": "Sport Stats",
  "name_for_model": "sportStats",
  "description_for_human": "Get current and historical stats for sport players and games.",
  "description_for_model": "Get current and historical stats for sport players and games. Always display results using markdown tables.",
  "auth": {
    "type": "none"
  },
  "api": {
    "type": "openapi",
    "url": "PLUGIN_HOSTNAME/openapi.yaml"
  },
  "logo_url": "PLUGIN_HOSTNAME/logo.png",
  "contact_email": "support@example.com",
  "legal_info_url": "https://example.com/legal"
}

openapi.yaml

openapi: 3.0.1
info:
  title: Sport Stats
  description: Get current and historical stats for sport players and games.
  version: "v1"
servers:
  - url: PLUGIN_HOSTNAME
paths:
  /players:
    get:
      operationId: getPlayers
      summary: Retrieves all players from all seasons whose names match the query string.
      parameters:
        - in: query
          name: query
          schema:
            type: string
          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.
      responses:
        "200":
          description: OK
  /teams:
    get:
      operationId: getTeams
      summary: Retrieves all teams for the current season.
      responses:
        "200":
          description: OK
  /games:
    get:
      operationId: getGames
      summary: Retrieves all games that match the filters specified by the args. Display results using markdown tables.
      parameters:
        - in: query
          name: limit
          schema:
            type: string
          description: The max number of results to return.
        - in: query
          name: seasons
          schema:
            type: array
            items:
              type: string
          description: Filter by seasons. Seasons are represented by the year they began. For example, 2018 represents season 2018-2019.
        - in: query
          name: team_ids
          schema:
            type: array
            items:
              type: string
          description: Filter by team ids. Team ids can be determined using the getTeams function.
        - in: query
          name: start_date
          schema:
            type: string
          description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or after this date.
        - in: query
          name: end_date
          schema:
            type: string
          description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or before this date.
      responses:
        "200":
          description: OK
  /stats:
    get:
      operationId: getStats
      summary: Retrieves stats that match the filters specified by the args. Display results using markdown tables.
      parameters:
        - in: query
          name: limit
          schema:
            type: string
          description: The max number of results to return.
        - in: query
          name: player_ids
          schema:
            type: array
            items:
              type: string
          description: Filter by player ids. Player ids can be determined using the getPlayers function.
        - in: query
          name: game_ids
          schema:
            type: array
            items:
              type: string
          description: Filter by game ids. Game ids can be determined using the getGames function.
        - in: query
          name: start_date
          schema:
            type: string
          description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or after this date.
        - in: query
          name: end_date
          schema:
            type: string
          description: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or before this date.
      responses:
        "200":
          description: OK
  /season_averages:
    get:
      operationId: getSeasonAverages
      summary: Retrieves regular season averages for the given players. Display results using markdown tables.
      parameters:
        - in: query
          name: season
          schema:
            type: string
          description: Defaults to the current season. A season is represented by the year it began. For example, 2018 represents season 2018-2019.
        - in: query
          name: player_ids
          schema:
            type: array
            items:
              type: string
          description: Filter by player ids. Player ids can be determined using the getPlayers function.
      responses:
        "200":
          description: OK

description 的内容非常重要,决定了 ChatGPT 会不会调用你的插件,调用得是否正确。

思考:为什么不干脆整个描述文件都用自然语言写?非要用结构化的 JSON 和 YAML?

Plugins 的市场表现

  1. 时间线:
    1. 3 月 24 日发布, 提供 11 个插件,可以申请加入 waitlist 获得使用权
    2. 5 月 15 日开始向 Plus 用户全量开放插件和 Browsing, 插件数 70 多个
    3. 7 月 5 日因安全原因,关闭 Browsing(用户可通过此功能访问付费页面)
    4. 7 月 11 日开始全量开放 Code Interpreter。插件数已超 400
  2. 媒体将其类比为 App Store,获得鼓吹
  3. 6 月 7 日(全面放开后三星期)一篇应 OpenAI 要求而被删除的帖子中透露,Sam Altman 在一个闭门会中说:「插件的实际使用情况表明,除了 Browsing 以外,还没有达到理想的产品市场契合点。他表示,很多人认为他们希望自己的应用程序位于 ChatGPT 中,但他们真正想要的是应用程序中的 ChatGPT。」(被删内容这里可以看到:https://web.archive.org/web/20230531203946/https://humanloop.com/blog/openai-plans)
思考:未来使用 AI 的入口,是有类似 ChatGPT 这样的超级入口,还是每个场景都有自己的 AI 入口(比如 Copilot)?

Plugins 失败分析

它暂时歇菜了,主要原因:

  1. 缺少「强 Agent」调度,只能手工选三个 plugin,使用成本太高。(解决此问题,相当于 App Store + Siri,可挑战手机操作系统地位)
  2. 不在「场景」中,不能提供端到端一揽子服务。(解决此问题,就是全能私人助

理)

Function Calling 的机制

Function Calling 示例 1:加法计算器

需求:用户输入任意可以用加法解决的问题,都能得到计算结果。

# 加载环境变量
import openai
import os
import json

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())  # 读取本地 .env 文件,里面定义了 OPENAI_API_KEY

openai.api_key = "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"
def get_completion(messages, model="gpt-3.5-turbo"):
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0,  # 模型输出的随机性,0 表示随机性最小
        functions=[{  # 用 JSON 描述函数。可以定义多个,但是只有一个会被调用,也可能都不会被调用
            "name": "sum",
            "description": "计算数组中所有数字的和",
            "parameters": {
                "type": "object",
                "properties": {
                    "numbers": {
                        "type": "array",
                        "items": {
                            "type": "number"
                        }
                    }
                }
            },
        }],
    )
    return response.choices[0].message
# 示例运行
messages = [
    {"role": "user", "content": "桌上有2个苹果和4个橙子,一共有几个水果?"}
]

response = get_completion(messages)
print(response)

# 处理函数调用结果
if response.get("function_call"):
    function_name = response["function_call"]["name"]
    arguments = json.loads(response["function_call"]["arguments"])
    
    if function_name == "sum":
        result = sum(arguments["numbers"])
        print(result)
        print(f"桌上有 {result} 个水果。")

输出:

{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "sum",
    "arguments": "{\"numbers\":[2,4]}"
  }
}
6
桌上有 6 个水果。

总结

OpenAI 的 Plugins 和 Function Calling 两种方式均旨在扩展和增强模型的能力。Plugins 允许模型与外部服务和数据库进行互动,从而提供更丰富和实时的数据访问能力。而 Function Calling 则是在对话过程中,模型能够识别特定的用户需求并调用预定义的函数,以提供更准确和定制化的回答。Function Calling 更注重在对话中直接调用代码逻辑处理特定任务,而 Plugins 更侧重于通过外部集成来扩展模型的功能范围。

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值