像写Python一样写JSON | intc: 专为人类设计的Python Config管理工具

像python代码一样,写json config也有补全文档和跳转功能

我们在开发时经常使用JSON或其衍生格式对我们的python代码进行配置,但是这些JSON格式的配置既难写又难读,难写是因为不像python一样有补全很容易忘记参数名,难读是由于我们经常忘记参数的含义以及约束是什么。这些痛点现在都将被intc解决

intc是一个功能强大的智能config配置管理工具,它不仅为我们的配置文件提供模块继承、模块嵌套、参数引用、超参搜索,还支持基于lambda表达式的复杂参数动态计算等功能。

而intc的配套Language Server Protocol(intc-lsp)则让我们的编辑浏览体验更加丝滑,它将配置文件与python代码紧密联合,intc-lsp可以帮助你在书写和阅读intc文件时方便的获取python的语义信息,提供错误提示、参数补全、智能跳转和参数帮助文档展示的功能。

除了用于config,intc还可以直接作为dataclass使用,它可以将我们使用intc定义的dataclass转化为json schema用于如LLM的数据类型约束,还可以对如LLM返回值在内的json数据进行数据检查并生成错误提示用于LLM的迭代优化。

Intc基础用法

python 复制代码
from intc import (
    MISSING,            # MISSING是一个常量(在intc中的值为`???`)表示参数缺失,需要在实例化config时提供
    Base,               # 所有的intc dataclass 都继承该类(可以隐式继承)
    BoolField,          # 这些bool field
    DictField,          # dict field
    FloatField,         # ...
    IntField,
    AnyField,
    ListField,
    NestField,          # 嵌套field,相比dict可以提供更多的类型检查、智能补全等功能
    StrField,
    SubModule,
    cregister,          # cregister注册intc实例(支持二级命名, <module_type, module_name> ),用于实例的索引(通过<module_type, module_name>直接获取对应的model类,config中也会使用注册名来定位对应的model类
)


@cregister("model", "simple_cls")  # cregister将Model注册为intc类,`module_type`为`model`, `module_name`为`simple_cls`
class Model(Base):                 # 显式继承自Base,这里也可以不显式继承,register过程会自动执行这个过程,显式的继承可以提供更好的语义补全
    embedding_combine_method = StrField( # dataclass的属性定义
        value="concat",                  # 默认值
        options=["concat", "concat_linear"], # options 表示值必须是这几个里面的一个
        help="the combine method, just `concat` or use `linear` on the concated embedding",
    )
    embedding_size = IntField(
        value=MISSING, help="the sum of bert and glove embedding size" # 这里的default value为MISSING,需要在实例化时提供
    )
    active = StrField(
        value="relu",
        options=["relu", "tanh", "sigmoid", "none"],
        help="the activation function",
    )
    submodule = SubModule(   # 子模型,可以嵌套其他模型的定义,这里的子模型可以有多个,引用子模型需要用到这些子模型的注册名
        value={},
        suggestions=[        # suggestions 表示推荐的一些值, 对于代码阅读和intc-lsp的语义解析有帮助
            "embedding",
            "decode",
        ],
        help="submodules for basic model",
    )

@cregister("embedding", "bert")
class BertEmbedding:
    hidden_size = IntField(
        value=MISSING,
        minimum=1,
        help="the input/output/hidden size for bert, must >= 1",
    )
    dropout_rate = FloatField(
        value=0.0, minimum=0.0, maximum=1.0, help="the dropout rate for bert"  #
    )
....

// 文件 config/model.jsonc
{
    "@model@simple_cls": {  // 表明是对谁进行配置,格式为@module_type@module_name @model@simple_cls 对应被注册为这个名称的`Model`
        "active": "none",
        "embedding_size": "@$.@glove.hidden_size, @$.@bert.hidden_size @lambda x, y: x+y", // 这里的值为动态的lambda计算的,喊一声 embedding_size的值为@embedding@glove.hidden_size和@embedding@bert.hidden_size 的和, 关于lambda的语法请看本说明里面关于lambda的介绍
        "@embedding@glove": { // submodule, submodule 同样以@module_type@module_name作为标识
            "hidden_size": 300,
            "vocab_size": 5000
        },
        "@embedding@bert": {
            "hidden_size": 768
        }
    }
}

DataClass 转化为Json Schema

python 复制代码
import json

from intc import MISSING, Base, IntField, NestField, StrField, dataclass


@dataclass
class LLMOutput(Base):
    """The output of the LLM model"""

    user_name = StrField(value=MISSING, help="Name of the person")

    class Info:
        age = IntField(value=MISSING, minimum=1, maximum=150, help="Age of the person")
        blood_type = StrField(
            value=MISSING, options=["A", "B", "AB", "O"], help="Blood type"
        )

    user_info = NestField(value=Info, help="User information")
    lines = IntField(value=MISSING, help="Number of lines in the output")
print(json.dumps(LLMOutput._json_schema(), indent=4))

Output:

json 复制代码
{
    "properties": {
        "user_name": {
            "description": "Name of the person",
            "type": "string",
            "deprecated": false
        },
        "user_info": {
            "description": "User information",
            "type": "object",
            "properties": {
                "age": {
                    "description": "Age of the person",
                    "type": "integer",
                    "deprecated": false,
                    "minimum": 1,
                    "maximum": 150
                },
                "blood_type": {
                    "description": "Blood type",
                    "type": "string",
                    "enum": [
                        "A",
                        "B",
                        "AB",
                        "O"
                    ],
                    "deprecated": false
                }
            }
        }
    },
    "type": "object",
    "description": "The output of the LLM model",
    "$schema": "https://json-schema.org/draft/2020-12/schema"
}

编写Config时的LSP支持展示(这里展示使用VSCODE和neovim时的效果)

More

这里只是对这个项目进行简单的介绍,更详细的文档和用法请参考Github项目

Github INTC

这个项目花费了我好多个周末的时间,欢迎大家提Issue和PR,如果有帮助也希望能帮忙点一下Star 谢谢

相关推荐
不染_是非7 分钟前
Django学习实战篇六(适合略有基础的新手小白学习)(从0开发项目)
后端·python·学习·django
star数模10 分钟前
2024“华为杯”中国研究生数学建模竞赛(E题)深度剖析_数学建模完整过程+详细思路+代码全解析
python·算法·数学建模
跟着大数据和AI去旅行35 分钟前
使用肘部法则确定K-Means中的k值
python·机器学习·kmeans
WinterXJujube1 小时前
人话学Python-循环语句
python
神即道 道法自然 如来1 小时前
Python+Pytest框架,“api_key.py文件怎么编写“?
python·pytest
kuiini2 小时前
python学习-10【模块】
python·学习
她最爱橘了2 小时前
AppStore评论爬虫
爬虫·python·gui·pyside6
没枕头我咋睡觉2 小时前
【大语言模型_1】VLLM部署Qwen模型
python·语言模型
lkasi2 小时前
python文字转wav音频
开发语言·python
Bruce小鬼2 小时前
最新版本TensorFlow训练模型TinyML部署到ESP32入门实操
人工智能·python·tensorflow