共计 3226 个字符,预计需要花费 9 分钟才能阅读完成。
背景痛点:校园场景下的 AI 需求
大学生日常面临课程管理、学术写作、活动协调等高频需求。传统解决方案存在三个明显痛点:

- 信息碎片化:课表、作业 DDL、图书馆资源分散在不同平台
- 操作低效:简单查询(如空教室查找)需要多步人工操作
- 时间成本高:文献综述、代码调试等重复性工作耗时
通过 ChatGPT 插件,可以将这些场景整合为自然语言交互的智能服务。例如:
- 输入 ” 下周三下午有哪些空教室?” 直接获取列表
- 说 ” 帮我找 5 篇关于机器学习的综述论文 ” 自动返回 PDF 链接
技术对比:插件开发 vs 常规 API
插件开发与传统 API 开发的核心差异体现在三个方面:
- 协议规范:必须遵循 OpenAPI 3.0 标准定义接口
- 元数据要求:需要提供 ai-plugin.json 描述文件
- 交互模式:支持多轮对话上下文管理
OpenAPI 规范的作用相当于插件与 ChatGPT 之间的「通信协议」,其核心要素包括:
paths定义所有可访问端点components/schemas声明数据结构securitySchemes设置鉴权方式
核心实现
1. 使用 FastAPI 构建后端
以下是带 JWT 验证的基础框架代码(Python 3.10+):
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
import jwt
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 模拟用户数据库
fake_users_db = {
"student": {
"username": "student",
"password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXe" # 示例哈希
}
}
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, "SECRET_KEY", algorithms=["HS256"])
username = payload.get("sub")
if username not in fake_users_db:
raise HTTPException(status_code=401, detail="Invalid user")
return username
except jwt.PyJWTError:
raise HTTPException(status_code=401, detail="Invalid token")
@app.get("/timetable")
async def get_timetable(user: str = Depends(get_current_user)):
return {"courses": ["AI 基础 9:00-10:30", "数据结构 14:00-15:30"]}
2. ai-plugin.json 配置
在项目根目录创建./.well-known/ai-plugin.json:
{
"schema_version": "v1",
"name_for_human": "校园智能助手",
"name_for_model": "campus_assistant",
"description_for_human": "帮你查询课表、找论文、管理学习任务",
"description_for_model": "Plugin for university students to manage courses and academic tasks",
"auth": {
"type": "oauth",
"client_url": "https://yourdomain.com/auth"
},
"api": {
"type": "openapi",
"url": "https://yourdomain.com/openapi.json"
},
"logo_url": "https://yourdomain.com/logo.png",
"contact_email": "support@yourdomain.com",
"legal_info_url": "https://yourdomain.com/legal"
}
3. Redis 缓存策略
处理异步查询时(如论文检索),建议采用以下缓存方案:
import redis
from fastapi import BackgroundTasks
r = redis.Redis(host='localhost', port=6379, db=0)
@app.get("/papers")
async def search_papers(keyword: str, bg: BackgroundTasks):
cache_key = f"papers:{keyword}"
# 检查缓存
if cached := r.get(cache_key):
return {"status": "cached", "data": cached.decode()}
# 异步更新缓存
async def fetch_and_cache():
data = await external_api_call(keyword) # 模拟外部 API
r.setex(cache_key, 3600, json.dumps(data)) # 1 小时过期
bg.add_task(fetch_and_cache)
return {"status": "fetching", "task_id": uuid.uuid4()}
安全考量
OAuth2.0 授权流程
推荐使用 Auth0 或 Okta 等专业服务,核心流程包括:
- 用户点击 ”Connect with Campus ID”
- 跳转到认证服务器
- 返回授权码到回调 URL
- 服务端用授权码换取 access_token
速率限制
在 FastAPI 中可通过中间件实现:
from fastapi import Request
from fastapi.middleware import Middleware
async def rate_limiter(request: Request):
ip = request.client.host
key = f"rate_limit:{ip}"
current = r.incr(key)
if current == 1:
r.expire(key, 60) # 60 秒窗口
if current > 30: # 每分钟 30 次
raise HTTPException(429, "Too many requests")
app.add_middleware(Middleware(rate_limiter))
避坑指南
CORS 解决方案
在 FastAPI 中正确配置:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://chat.openai.com"],
allow_methods=["*"],
allow_headers=["*"],
)
对话上下文管理
三个关键实践:
- 使用 session_id 关联多轮对话
- 在 Redis 中保存临时状态(TTL 建议 5 分钟)
- 明确清除上下文的触发条件(如超时或用户说 ” 重新开始 ”)
冷启动优化
对于计算密集型插件:
- 部署时启动预热请求
- 使用 keep-alive 连接
- 考虑 AWS Lambda 的 Provisioned Concurrency
延伸思考
插件间数据共享可通过以下方式实现:
- 加密 URL 参数 :如
pluginA生成加密 token 传给pluginB - 中央存储服务:使用 Firebase 或 AWS DynamoDB 作为共享数据库
- 用户授权中转:通过 OAuth scope 获取跨插件访问权限
建议优先考虑方案 3,既保证安全性又符合最小权限原则。例如用户可以先授权「课表插件」读取教学系统数据,再允许「作业提醒插件」访问这些信息生成提醒。
正文完
