• ChatGPT Plugin开发setup - Java(Spring Boot) Python(fastapi)


    记录一下快速模板,整体很简单,如果不接auth,只需要以下:

    • 提供一个/.well-known/ai-plugin.json接口,返回openAI所需要的格式
    • 提供openAPI规范的文档
    • CORS设置

    其他的和普通的web开发类似.

    本地开发就直接使用localhost即可,前几天官方localhost无法联通,最近应该修复了.

    要让GPT更好理解接口内容,接口需要写详细的文档,在文档内写清楚各个参数作用和可选值以及示例.

    Spring Boot

    增加对文档的依赖

    <dependency>
        <groupId>org.springdocgroupId>
        <artifactId>springdoc-openapi-starter-webmvc-uiartifactId>
        <version>2.1.0version>
    dependency>
    

    增加一个bean配置:

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info().title("html fetcher")
                                .description("get content from url")
                                .version("1.0"));
    }
    

    文档的地址为/v3/api-docs

    增加ai-plugin.json接口

    @GetMapping(value = "/.well-known/ai-plugin.json", produces = "application/json")
    public String aiPlugin() {
        return """
                {
                        "schema_version": "v1",
                        "name_for_human": "html fetcher Plugin",
                        "name_for_model": "html_fetcher",
                        "description_for_human": "Plugin for getting content from url",
                        "description_for_model": "Plugin for getting content from url",
                        "auth": {
                            "type": "none"
                        },
                        "api": {
                            "type": "openapi",
                            "url": "http://localhost:8080/v3/api-docs",
                            "is_user_authenticated": false
                        },
                        "logo_url": "http://localhost:8080/logo.png",
                        "contact_email": "support@example.com",
                        "legal_info_url": "http://www.example.com/legal"
                    }
        """;
    }
    

    logo直接放到\resources\static
    内容根据自己插件修改,本地开发直接写localhost,部署写对应的网站地址.

    CORS设置

    测试的时候允许可以写*, 后续上线更改为openai.com:

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
    

    要写自定义文档可以用spring-doc的相关注解.
    比如写在接口上用@Operation, 字段上使用@Schema注解.
    @Schema内可以用allowableValuesexample等来约束openai的查询.

    fastapi

    fastapi自带openAPI集成,只需要把json dump成yaml即可, setup比较简单, 这里直接全部放一起了:

    app = FastAPI()
    
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    # static 文件夹用来做静态资源host 放logo
    app.mount("/static", StaticFiles(directory="static"), name="static")
    
    # json -> yaml
    @app.get("/openapi.yaml")
    async def get_openapi():
        return Response(content=yaml.dump(app.openapi()), media_type="application/yaml")
    
    
    @app.get("/.well-known/ai-plugin.json")
    async def openai_api_plugin():
        return {
            "schema_version": "v1",
            "name_for_human": "",
            "name_for_model": "",
            "description_for_human": "",
            "description_for_model": "",
            "auth": {
                "type": "none"
            },
            "api": {
                "type": "openapi",
                "url": "http://localhost:8000/openapi.yaml",
                "is_user_authenticated": False
            },
            "logo_url": "http://localhost:8000/static/logo.png",
            "contact_email": "support@example.com",
            "legal_info_url": "http://www.example.com/legal"
        }
    

    自定义文档内容对于接口的可以用summary,response_description参数, query参数可以用Annotationd, 一个例子:

    @app.get("/api/query_profit_data", summary='query profit data by company code, year and quarter', response_description="""
    return profit data in format {"key":{"0":"value"}}, panda's dataframe""")
    async def query_profit_data(code: Annotated[str, Query(description="the company code", example="sh.600000")],
                                year: Annotated[int, Query(description="year to get profit", example=2023)],
                                quarter: Annotated[
                                    int, Query(description="quarter to get profit. allow values:1,2,3,4", example=1)]):
    

    参考资料

    chatgpt plugin: https://openai.com/blog/chatgpt-plugins

    spring doc: https://springdoc.org/v2/

    fastapi: https://fastapi.tiangolo.com/

  • 相关阅读:
    考研C语言复习初阶(5)
    等差求解一个网络的权重无法适配到别的数据集上
    安卓绘制原理之 MeasureCache优化了什么?
    JavaScript 的真值与假值 | 如何判断一个对象为空
    AI 法律助手与原创奇幻小说生成 | 开源专题 No.33
    Redis Stack功能介绍及redis-om-dotnet使用示例
    C/C++ 有 1 、 2 、 3 、 4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
    Misc入门干货
    WPF绘制圆形调色盘
    Django笔记十四之统计总数、最新纪录和空值判断等功能
  • 原文地址:https://www.cnblogs.com/fairjm/p/chatgpt-plugin-setup-java-python.html