OpenAI Agent Kit 全网首发深度解读与上手指南
Agent Kit 简介
Agent Kit 是 OpenAI 推出的一个基于 Agent 的工作流编排工具,可以一条龙搞定「编排 → 发布 → 集成 →评估」的 AI 工作流平台。
如果你正在寻找把 AI 工作流从原型拉到生产的稳妥方式,Agent Kit 值得优先试用。它把可视化编排、前端嵌入、数据连接与效果评估串成一个闭环,降低实施成本、提升上线速度。
核心组件一览
- Agent Builder:拖拽式可视化编排,所见即所得地搭流程。
- ChatKit:将已发布的工作流一键嵌入前端页面,开箱即用的聊天组件。
- Evals:自动化评估与优化,支持自定义指标和评估模型。
- Connector Registry:统一管理数据源与工具接入,规范化配置与权限。
为什么选 Agent Kit
- 输出到自定义组件:工作流的结果可直达你的前端组件,可在 Widgets Studio 设计并复用渲染逻辑。
- 前端快速接入:通过 ChatKit 将工作流发布为组件,几行代码接入对话能力。
- 内置评估闭环:使用 Evaluation 评估与优化工作流,支持自定义指标,持续提升效果。
使用限制与注意事项
- MCP 工具生态仍在扩充,当前数量有限。
- 深度绑定 OpenAI 生态。
- 付费与企业认证:使用 Agent Builder 等功能需要付费账号;GPT‑5 系列与高级优化需完成企业认证。
实战上手路径
我们将基于官方 Starter 项目 演示入门,并扩展用 Python FastAPI + React 集成一个小型 Demo。
准备工作
- 获取
OPENAI_API_KEY
:在 OpenAI 平台 创建密钥。后端创建会话时将使用该密钥,以校验调用归属并防止workflow_ID
泄露被滥用。 - 配置域名白名单:在 域名白名单设置 添加你的前端站点域名,确保 ChatKit 组件安全可用。
在 Agent Builder 创建与发布工作流
创建工作流
在 Agent Builder 选择模板或从零开始搭建。若未通过 企业认证,请将模型切换为可用的 GPT‑4 系列。
可在 Agent Builder 使用 Evals 评估工作流效果,支持自定义指标和评估模型。
发布工作流
发布后获取 workflow_ID
,用于在 ChatKit 前端组件中进行绑定与调用。
官方示例项目
下载项目并安装依赖及环境
# 下载项目
git clone https://github.com/openai/openai-chatkit-starter-app.git
# 安装依赖项
npm install
# 复制环境变量文件
cp .env.example .env.local
将 .env.local 中的 OPENAI_API_KEY 及 NEXT_PUBLIC_CHATKIT_WORKFLOW_ID 替换为你自己的 OPENAI_API_KEY 及 workflow_ID
启动项目
# 打包项目
npm run build
# 启动项目
npm run dev
自定义调整
可在 lib/config.ts 调整 初始提示、问候文本、ChatKit 主题
可在 components/.tsx 调整事件触发逻辑,以集成您的分析及存储
想第一时间掌握 OpenAI AgentKit 的实战用法,以及更多 MCP、Agent、RAG、多模态 应用落地案例
来 赋范空间大模型社区 ,这里不仅有 AgentKit 全流程实操拆解,还有持续更新的 Agent / RAG / 多模态 应用落地实战案例,带你深入学习。
工作流集成项目Demo
此项目基于 Python FastAPI + React 实现使用 Agent Kit 的工作流集成项目Demo。
可加 小助理 领取项目源码
服务端
由于 CDN 限制,我们可以在服务端返回本地的 chatkit.js 脚本。
@app.get("/cdn/chatkit.js")
async def proxy_chatkit_js():"""返回本地 chatkit.js """base_dir = os.path.dirname(__file__)local_candidates = [os.path.abspath(os.path.join(base_dir, "../frontend/public/chatkit.js")), ]for local_path in local_candidates:with open(local_path, "rb") as f:content = f.read()logger.info(f"使用本地 ChatKit 脚本: {local_path}")return Response(content=content,media_type="application/javascript",headers={"Cache-Control": "public, max-age=3600","Access-Control-Allow-Origin": "*"})
解析工作流配置文件 workflows.json,加载工作流列表及默认工作流。
def load_workflow_config():base_dir = os.path.dirname(__file__)data_dir = os.path.abspath(os.path.join(base_dir, "..", "data"))candidates = [os.path.abspath(os.path.join(data_dir, "workflows.json")),]for path in candidates:if os.path.exists(path):with open(path, "r", encoding="utf-8") as f:try:return json.load(f)except Exception as e:logger.error(f"读取工作流配置失败: {e}")breaklogger.warning("请配置工作流")return {"workflows": [],"default": None,}WORKFLOW_CONFIG = load_workflow_config()@app.get("/api/workflows")
async def get_workflows():"""返回工作流列表"""return WORKFLOW_CONFIG
创建 ChatKit 会话
def _create_chatkit_session(workflow_type: str, workflow_id: str, stable_user_id: str):"""调用 OpenAI ChatKit 创建会话并返回 session_id 与 client_secret。"""headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}","OpenAI-Beta": "chatkit_beta=v1",}payload = {"workflow": {"id": workflow_id}, "user": stable_user_id}response = requests.post("https://api.openai.com/v1/chatkit/sessions",headers=headers,json=payload,timeout=30,)if response.status_code != 200:logger.error(f"ChatKit API 错误: {response.status_code} {response.text}")raise Exception(f"OpenAI API Error ({response.status_code}): {response.text}")session = response.json()return session.get("id"), session.get("client_secret")@app.post("/api/chatkit/session")
async def create_chatkit_session(workflow_type: str | None = None):"""创建 ChatKit 会话1. 前端请求这个接口2. 服务端使用 OpenAI API Key 创建 session3. 返回 client_secret、session_id、workflow_id 给前端4. 前端使用 client_secret 连接 ChatKit"""try:# 解析工作流:优先前端传入,其次使用 workflows.json 的 defaultselected_type = workflow_type or WORKFLOW_CONFIG.get("default")workflow_id = WORKFLOWS_MAP.get(selected_type or "")if not selected_type or not workflow_id:raise HTTPException(status_code=400, detail="工作流识别错误请确认配置")workflow_type = selected_typelogger.info(f"创建 ChatKit Session for workflow: {workflow_type} ({workflow_id})")# 为该工作流维持稳定 user_idstable_user_id = _get_or_create_user_id(workflow_type)sid, csec = _create_chatkit_session(workflow_type, workflow_id, stable_user_id)logger.info(f"ChatKit Session 创建成功: {sid} (workflow: {workflow_type})")# 持久化最新密钥到本地 JSONif sid and csec:_set_latest_secret(sid, csec, workflow_type, workflow_id)return {"client_secret": csec,"session_id": sid,"workflow_type": workflow_type,"workflow_id": workflow_id}except Exception as e:logger.error(f"创建 ChatKit Session 失败: {str(e)}")raise HTTPException(status_code=500,detail=f"Failed to create ChatKit session: {str(e)}")
前端有 session_id 时,可通过该接口获取最新的 client_secret 以恢复历史会话。
@app.get("/api/chatkit/session")
async def get_latest_client_secret(session_id: str | None = None):"""前端仅存储 session_id,通过该接口获取密钥以恢复历史。"""try:if not session_id:raise HTTPException(status_code=400, detail="缺少 session_id")info = _get_latest_secret(session_id)if not info:raise HTTPException(status_code=404, detail="未找到该会话")return {"client_secret": info["client_secret"],"session_id": session_id,"workflow_type": info.get("workflow_type"),"workflow_id": info.get("workflow_id"),"updated_at": info.get("updated_at")}except HTTPException:raiseexcept Exception as e:logger.error(f"查询最新密钥失败: {e}")raise HTTPException(status_code=500, detail=f"查询失败: {e}")
挂载前端页面
app.mount("/", StaticFiles(directory=frontend_dist_path, html=True), name="static")
想第一时间掌握 OpenAI AgentKit 的实战用法,以及更多 MCP、Agent、RAG、多模态 应用落地案例
来 赋范空间大模型社区 ,这里不仅有 AgentKit 全流程实操拆解,还有持续更新的 Agent / RAG / 多模态 应用落地实战案例,带你深入学习。
前端
主页面
import { useChatKit } from '@openai/chatkit-react';
import { useEffect, useState } from 'react';
import './App.css';
import WorkflowSelector from './components/WorkflowSelector';
import ChatPane from './components/ChatPane';function App() {const [errorMsg, setErrorMsg] = useState(null);// 工作流配置从后端加载const [flows, setFlows] = useState([]);const [activeFlow, setActiveFlow] = useState(null);const [flowsLoading, setFlowsLoading] = useState(true);// 仅在前端保存每个工作流的 session_id,由后端映射并返回最新 client_secretconst storageKey = 'chatkit.flowSessions';const readSessions = () => {try {return JSON.parse(localStorage.getItem(storageKey) || '{}');} catch {return {};}};const writeSessions = (map) => {try {localStorage.setItem(storageKey, JSON.stringify(map));} catch {// 忽略存储错误}};const getSavedSessionId = (flow) => {const m = readSessions();return m[flow || 'default'] || null;};const setSavedSessionId = (flow, sid) => {const m = readSessions();m[flow || 'default'] = sid;writeSessions(m);};const { control: kitCtrl } = useChatKit({api: {// 会话续期或网络重试时调用async getClientSecret(currentClientSecret) {const flowKey = activeFlow || 'default';const savedSid = getSavedSessionId(flowKey);// 1) 初次挂载或切回工作流:若有 session_id,向后端查询最新密钥if (!currentClientSecret && savedSid) {try {const resp = await fetch(`/api/chatkit/session?session_id=${encodeURIComponent(savedSid)}`);if (resp.ok) {const info = await resp.json();return info.client_secret;}} catch (e) {}}// 2) 无有效 session_id 或刷新失败:创建新会话,并保存 session_idtry {const response = await fetch(`/api/chatkit/session${activeFlow ? `?workflow_type=${encodeURIComponent(activeFlow)}` : ''}`, {method: 'POST',headers: { 'Content-Type': 'application/json' },});if (!response.ok) {throw new Error(`HTTP ${response.status}: ${response.statusText}`);}const data = await response.json();setSavedSessionId(flowKey, data.session_id);return data.client_secret;} catch (error) {setErrorMsg(error.message);throw error;}},},// 输入框配置composer: {placeholder: '输入消息',},onError: (error) => {const emsg = error.message || JSON.stringify(error);setErrorMsg(emsg);},});useEffect(() => {// 从后端加载工作流配置(async () => {try {const resp = await fetch('/api/workflows');if (!resp.ok) throw new Error(`HTTP ${resp.status}`);const cfg = await resp.json();const options = (cfg.workflows || []).map(w => ({ id: w.id, name: w.name, workflow_id: w.workflow_id }));setFlows(options);const defaultType = cfg.default || (options[0]?.id ?? null);setActiveFlow(defaultType);setFlowsLoading(false);} catch (e) {setFlowsLoading(false);}})();}, []); return (<div className="app"><div className="header"><p>AgentKit:Agent Builder + Chat Kit Demo</p></div>{/* 主内容区域 */}<div className="main-content"><div className="left-column"><WorkflowSelectorflows={flows}activeFlow={activeFlow}flowsLoading={flowsLoading}onChange={(newFlow) => {setActiveFlow(newFlow);}}/><ChatPaneerrorMsg={errorMsg}activeFlow={activeFlow}kitCtrl={kitCtrl}/></div></div></div>);
}export default App;
chatkit组件
import { ChatKit } from '@openai/chatkit-react';export default function ChatPane({ width, errorMsg, activeFlow, kitCtrl }) {return (<div className="chat-container" style={{ width: `${width}px` }}>{errorMsg ? (<div className="error-state"><h3>加载失败</h3><p>{errorMsg}</p><button onClick={() => window.location.reload()} className="reload-btn">重新加载</button></div>) : (<ChatKit key={activeFlow || 'default'} control={kitCtrl} className="chatkit-widget" />)}</div>);
}
工作流选择器组件
export default function WorkflowSelector({ flows, activeFlow, flowsLoading, onChange }) {return (<div className="workflow-selector"><label htmlFor="workflow-select">选择工作流:</label><selectid="workflow-select"value={activeFlow ?? ''}onChange={(e) => onChange?.(e.target.value)}className="workflow-select"disabled={flowsLoading}>{flowsLoading ? (<option value="">加载中...</option>) : ((flows?.length ?? 0) > 0 ? (flows.map(opt => (<option key={opt.id} value={opt.id}>{opt.name || opt.id}</option>))) : (<option value="">未配置工作流</option>))}</select></div>);
}
详情参考
OpenAI AgentKit 介绍
OpenAI AgentKit 文档
ChatKit 示例项目
ChatKit 高级示例项目
ChatKit Studio