成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一日一技:如何快速生成大模型工具調用的JSON Schema

人工智能
在使用大模型的工具調用時,我們需要編寫JSON Schema,例如下圖的tools字段的值:這個Schema寫起來非常麻煩,括號太多了,看著眼花。不信你肉眼看看,你需要幾秒鐘才能分清楚type: "object"跟哪個字段在同一層級?這個Schema有沒有什么辦法自動生成呢?

在使用大模型的工具調用時,我們需要編寫JSON Schema,例如下圖的tools字段的值:

圖片圖片

這個Schema寫起來非常麻煩,括號太多了,看著眼花。不信你肉眼看看,你需要幾秒鐘才能分清楚type: "object"跟哪個字段在同一層級?這個Schema有沒有什么辦法自動生成呢?

LangChain提供了一個@tool裝飾器來簡化工具調用的JSON Schema,直接裝飾函數就能使用了。例如:

import json
from langchain_core.tools.convert import tool


@tool(parse_docstring=True)
def parse_user_info(name: str, age: int, salary: float) -> bool:
    """
    保存用戶的個人信息
 
    Args:
        name: 用戶名
        age: 用戶的年齡
        salary: 用戶的工資
    """
    return True

然后,我們可以通過打印函數名的.args_schema.model_json_schema()來獲取到類似于Tool Calling的JSON Schema,如下圖所示:

圖片圖片

這種方式有兩個問題:

1. Tool Calling需要的JSON Schema中,參數名對應的字段應該是name,但這里導出來的是title。

2. 函數的docstring使用的是Google Style,跟Python的不一樣。

在Python里面,我們寫docstring時,一般這樣寫::param 參數名: 參數解釋,例如下面這樣:

import json
from langchain_core.tools.convert import tool


@tool
def parse_user_info(name: str, age: int, salary: float) -> bool:
    """
    保存用戶的個人信息
 
    :param name: 用戶名 
    :param age: 用戶的年齡
    :param salary: 用戶的工資
    :return: bool,成功返回True,失敗返回False
    """
    return True

schema = parse_user_info.args_schema.model_json_schema()
print(json.dumps(schema, ensure_ascii=False, indent=2))

但使用這種方式定義的時候,@tool裝飾器不能加參數parse_docstring=True,否則會報錯。可如果不加,提取的信息里面,字段沒有描述。效果如下圖所示:

圖片圖片

這兩個問題,其實有一個通用的解決辦法,那就是直接使用`Pydantic`。實際上,LangChain本身使用的也是Pydantic。如下圖所示:

圖片圖片

我之前寫過一篇文章:一日一技:如何使用大模型提取結構化數據,介紹了一個第三方庫,名叫`instructor`。它本質上就是把Pydantic定義的類轉成Tool Calling需要的JSON Schema,然后通過大模型的Tool Calling來提取參數。使用使用它,我們可以非常容易的實現本文的目的。

使用Pydantic定義我們要提取的數據并轉換為JSON Schema格式:

import json
from pydantic import BaseModel, Field

class UserInfo(BaseModel):
    """
    用戶個人信息
    """
    name: str = Field(..., descriptinotallow='用戶的姓名')
    age: int = Field(default=None, descriptinotallow='用戶的年齡')
    salary: float = Field(default=None, descriptinotallow='用戶的工資')

schema = UserInfo.model_json_schema()
print(json.dumps(schema, indent=2, ensure_ascii=False))

Field的第一個參數如果是三個點...,表示這個字段是必填字段。如果想把一個字段設定為可選字段,那么Field加上參數default=None。

運行效果如下圖所示:

圖片圖片

參數描述直接寫到參數字段定義里面,根本不需要擔心注釋格式導致參數沒有描述,管他是Google Style還是Python Style。

接下來,我們要把Pydantic輸出的這個格式轉換為Tool Calling需要的JSON Schema格式。我們來看一下Instructor的源代碼:

圖片圖片

把他這個代碼復制出來,用來處理剛剛Pydantic生成的JSON Schema:

from docstring_parser import parse


def generate_tool_calling_schema(cls):
    schema = cls.model_json_schema()
    docstring = parse(cls.__doc__ or'')
    parameters = {
        k: v for k, v in schema.items() if k notin ("title", "description")
    }
    for param in docstring.params:
        if (name := param.arg_name) in parameters["properties"] and (
            description := param.description
        ):
            if"description"notin parameters["properties"][name]:
                parameters["properties"][name]["description"] = description
    
    parameters["required"] = sorted(
        k for k, v in parameters["properties"].items() if"default"notin v
    )
    
    if"description"notin schema:
        if docstring.short_description:
            schema["description"] = docstring.short_description
        else:
            schema["description"] = (
                f"Correctly extracted `{cls.__name__}` with all "
                f"the required parameters with correct types"
            )
    
    return {
        "name": schema["title"],
        "description": schema["description"],
        "parameters": parameters,
    }

這里依賴一個第三方庫,叫做docstring_parser,這個庫的原理非常簡單,就是正則表達處理docstring而已。大家甚至可以看一下他的源代碼然后自己實現。

運行以后效果如下圖所示。

圖片圖片

注意在參數信息里面,會有'default': null和title字段,這兩個字段即使傳給大模型也沒有關系,它會自動忽略。如果大家覺得他們比較礙眼,也可以改動一下代碼,實現跟Tool Calling 的JSON Schema完全一樣:

from docstring_parser import parse


def generate_tool_calling_schema(cls):
    schema = cls.model_json_schema()
    docstring = parse(cls.__doc__ or'')
    parameters = {
        k: v for k, v in schema.items() if k notin ("title", "description")
    }
    for param in docstring.params:
        if (name := param.arg_name) in parameters["properties"] and (
            description := param.description
        ):
            if"description"notin parameters["properties"][name]:
                parameters["properties"][name]["description"] = description

    parameters["required"] = sorted(
        k for k, v in parameters["properties"].items() if"default"notin v
    )

    for prop_name, prop_schema in parameters["properties"].items():
        prop_schema.pop("default", None)
        prop_schema.pop('title', None)

    if"description"notin schema:
        if docstring.short_description:
            schema["description"] = docstring.short_description
        else:
            schema["description"] = (
                f"Correctly extracted `{cls.__name__}` with all "
                f"the required parameters with correct types"
            )

    # 按 Tool Calling 規(guī)范封裝:
    return {
        "type": "function",
        "function": {
            "name": schema["title"],
            "description": schema["description"],
            "parameters": parameters,
        }
    }

運行效果如下圖所示:

圖片圖片

最后給大家出個思考題:如果函數的參數包含嵌套參數,應該怎么處理?

責任編輯:武曉燕 來源: 未聞Code
相關推薦

2024-02-20 22:13:48

Python項目Java

2024-08-27 22:08:13

2024-05-24 09:07:06

JSONprint字符串

2021-10-15 21:08:31

PandasExcel對象

2021-09-13 20:38:47

Python鏈式調用

2021-03-12 21:19:15

Python鏈式調用

2021-07-27 21:32:57

Python 延遲調用

2025-05-28 03:15:00

Scrapy數據sleep

2022-06-28 09:31:44

LinuxmacOS系統(tǒng)

2022-03-12 20:38:14

網頁Python測試

2021-04-27 22:15:02

Selenium瀏覽器爬蟲

2023-10-28 12:14:35

爬蟲JavaScriptObject

2024-07-30 08:16:18

Python代碼工具

2024-07-30 08:11:16

2024-10-16 21:47:15

2024-11-11 00:38:13

Mypy靜態(tài)類型

2021-05-08 19:33:51

移除字符零寬

2022-03-07 09:14:04

Selenium鼠標元素

2021-02-14 22:22:18

格式圖片 HTTP

2022-06-09 21:34:41

Python代碼函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品欧美乱码久久久久久 | 亚洲精品在线免费 | 中文字幕日韩在线 | 成人免费观看男女羞羞视频 | 久久国产一区二区 | 91精品导航 | 少妇精品久久久久久久久久 | 超碰在线免费 | 久久国产电影 | 亚洲三区视频 | 在线观看第一页 | 一二三在线视频 | 国产精品视频播放 | 亚洲一区二区不卡在线观看 | av在线一区二区三区 | 精品国产一区二区三区久久久四川 | 午夜电影一区二区 | 欧美视频在线免费 | 成人欧美 | 亚洲成人999 | 亚洲国产aⅴ成人精品无吗 国产精品永久在线观看 | 在线观看成人精品 | 亚洲视频中文字幕 | 亚洲精品久久久久久久久久吃药 | 91精品国产乱码麻豆白嫩 | 天天干夜夜操视频 | 欧美精品在线一区二区三区 | 亚洲免费在线 | 国产精品久久久久久久久久了 | 五月激情婷婷网 | 久草院线 | www.精品国产 | 免费一区二区 | av永久| 激情视频一区 | 国产精品一区二区久久久久 | 久久高清| 99久久精品国产毛片 | 国产精品视频网站 | 成人毛片视频免费 | 男人视频网站 |