ChatGPT Plugin開發setup

2023-05-15 18:01:16

記錄一下快速模板,整體很簡單,如果不接auth,只需要以下:

  • 提供一個/.well-known/ai-plugin.json介面,返回openAI所需要的格式
  • 提供openAPI規範的檔案
  • CORS設定

其他的和普通的web開發類似.

本地開發就直接使用localhost即可,前幾天官方localhost無法聯通,最近應該修復了.

要讓GPT更好理解介面內容,介面需要寫詳細的檔案,在檔案內寫清楚各個引數作用和可選值以及範例.

Spring Boot

增加對檔案的依賴

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.1.0</version>
</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": "[email protected]",
                    "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": "[email protected]",
        "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/