完整流程指南
本指南从头到尾介绍了 Imbrace SDK 中的四大工作流。每个部分都是独立的 — 可以按顺序阅读,也可以直接跳转到你需要的内容。
1. 创建 AI 代理并开始聊天
-
初始化客户端
import { ImbraceClient } from "@imbrace/sdk"const client = new ImbraceClient({accessToken: process.env.IMBRACE_ACCESS_TOKEN,env: "stable",})import osfrom imbrace import ImbraceClientclient = ImbraceClient(access_token=os.environ["IMBRACE_ACCESS_TOKEN"],env="stable",)import { ImbraceClient } from "@imbrace/sdk"const client = new ImbraceClient({apiKey: process.env.IMBRACE_API_KEY,organizationId: process.env.IMBRACE_ORGANIZATION_ID,env: "stable",})import osfrom imbrace import ImbraceClientclient = ImbraceClient(api_key=os.environ["IMBRACE_API_KEY"],organization_id=os.environ.get("IMBRACE_ORGANIZATION_ID"),env="stable",) -
创建 AI 代理
workflow_name在你的组织内必须是唯一的。const agent = await client.chatAi.createAiAgent({name: "Support Bot",workflow_name: "support_bot_v1",description: "Handles tier-1 customer support queries",instructions: "You are a helpful support agent. Be concise and friendly.",provider_id: "system", // 使用组织的默认 LLM 提供商model_id: "Default", // 路由到组织配置的默认模型(跨组织通用)})const aiAgentId = agent.id // UUID — 用于所有后续调用console.log("AI agent created:", aiAgentId)agent = client.chat_ai.create_ai_agent({"name": "Support Bot","workflow_name": "support_bot_v1","description": "Handles tier-1 customer support queries","instructions": "You are a helpful support agent. Be concise and friendly.","provider_id": "system", # 使用组织的默认 LLM 提供商"model_id": "Default", # 路由到组织配置的默认模型(跨组织通用)})ai_agent_id = agent["id"]print("AI agent created:", ai_agent_id)provider_id和model_id是可选项 — 省略时 SDK 自动填充{ provider_id: "system", model_id: "Default" }。"Default"路由到组织配置的系统默认模型,是跨组织通用的选择。需要覆盖时显式传入:provider_id: "<uuid>"用于指定自定义 LLM 提供商,或model_id: "gpt-4o"等 — 但具体模型名称只在该组织的system提供商实际公开它时才有效。在硬编码前,使用client.ai.listModels()(TypeScript) /client.ai.list_models()(Python) 列出组织的可用模型。 -
使用 AI 代理流式聊天
const response = await client.aiAgent.streamChat({assistant_id: aiAgentId,messages: [{ role: "user", content: "How do I reset my password?" }],// id 是会话 UUID — 重复使用以保持对话历史// 如果省略,每次调用会自动生成新的 UUID})const reader = response.body!.getReader()const decoder = new TextDecoder()while (true) {const { done, value } = await reader.read()if (done) breakconst text = decoder.decode(value)for (const line of text.split("\n")) {if (line.startsWith("data: ")) {const data = line.slice(6).trim()if (data && data !== "[DONE]") {try {const chunk = JSON.parse(data)process.stdout.write(chunk.delta ?? chunk.content ?? "")} catch {}}}}}response = client.ai_agent.stream_chat({"assistant_id": ai_agent_id,"messages": [{"role": "user", "content": "How do I reset my password?"}],# id 是会话 UUID — 重复使用以保持对话历史。# 如果省略,每次调用会自动生成新的 UUID。})import jsonfor line in response.iter_lines():if isinstance(line, bytes):line = line.decode()if not line.startswith("data: "):continuedata = line[6:].strip()if data and data != "[DONE]":try:chunk = json.loads(data)print(chunk.get("delta") or chunk.get("content") or "", end="")except Exception:pass -
维护对话历史(会话 ID)
在多次调用中传入相同的
id(必须是 UUID)以保持上下文:import { randomUUID } from "crypto"const sessionId = randomUUID()// 第一条消息await client.aiAgent.streamChat({assistant_id: aiAgentId,id: sessionId,messages: [{ role: "user", content: "What's your refund policy?" }],})// 后续 — 相同会话,AI 代理记得上下文await client.aiAgent.streamChat({assistant_id: aiAgentId,id: sessionId,messages: [{ role: "user", content: "How long does it take?" }],})import uuidsession_id = str(uuid.uuid4())# 第一条消息client.ai_agent.stream_chat({"assistant_id": ai_agent_id,"id": session_id,"messages": [{"role": "user", "content": "What's your refund policy?"}],})# 后续 — 相同会话,AI 代理记得上下文client.ai_agent.stream_chat({"assistant_id": ai_agent_id,"id": session_id,"messages": [{"role": "user", "content": "How long does it take?"}],})
2. 创建工作流并将其绑定到 AI 代理
-
列出已有流程以找到你的项目 ID
const { data: flows } = await client.workflows.listFlows({ limit: 5 })const projectId = flows[0]?.projectIdconsole.log("Project ID:", projectId)res = client.workflows.list_flows(limit=5)flows = res.get("data", [])project_id = flows[0]["projectId"] if flows else Noneprint("Project ID:", project_id) -
创建新流程
const flow = await client.workflows.createFlow({displayName: "CRM Update on New Lead",projectId,})console.log("Flow created:", flow.id)flow = client.workflows.create_flow(display_name="CRM Update on New Lead",project_id=project_id,)print("Flow created:", flow["id"]) -
添加 Webhook 触发器并发布流程
新创建的流程处于 DRAFT 状态,没有触发器 — Webhook URL 还不存在,所以
triggerFlow会返回 404。先添加 Webhook 组件作为触发器,然后发布:// 设置 Webhook 组件作为流程的触发器await client.workflows.applyFlowOperation(flow.id, {type: "UPDATE_TRIGGER",request: {name: "trigger",type: "PIECE_TRIGGER",valid: true,displayName: "Webhook",settings: {pieceName: "@activepieces/piece-webhook",pieceVersion: "0.1.24",triggerName: "catch_webhook",input: { authType: "none" },propertySettings: {},},},})// 发布 — 流程状态变为 DISABLED → ENABLED,Webhook URL 变为可用await client.workflows.applyFlowOperation(flow.id, {type: "LOCK_AND_PUBLISH",request: {},})# 设置 Webhook 组件作为流程的触发器client.workflows.apply_flow_operation(flow["id"], {"type": "UPDATE_TRIGGER","request": {"name": "trigger","type": "PIECE_TRIGGER","valid": True,"displayName": "Webhook","settings": {"pieceName": "@activepieces/piece-webhook","pieceVersion": "0.1.24","triggerName": "catch_webhook","input": {"authType": "none"},"propertySettings": {},},},})# 发布 — DISABLED → ENABLED,Webhook URL 变为可用client.workflows.apply_flow_operation(flow["id"], {"type": "LOCK_AND_PUBLISH","request": {},}) -
手动触发流程并传入负载
// 触发并忘记(异步)await client.workflows.triggerFlow(flow.id, {contact_name: "Jane Smith",email: "jane@example.com",})// 同步触发 — 要让它实际返回数据而不超时,// 流程需要通过 ADD_ACTION 使用 applyFlowOperation 添加 "Return Response" 动作// (否则网关会等待 30 秒然后放弃)。const result = await client.workflows.triggerFlowSync(flow.id, {contact_name: "Jane Smith",email: "jane@example.com",})console.log("Flow result:", result)# 触发并忘记(异步)client.workflows.trigger_flow(flow["id"], {"contact_name": "Jane Smith","email": "jane@example.com",})# 同步触发 — 要让它实际返回数据而不超时,# 流程需要通过 ADD_ACTION 使用 apply_flow_operation 添加 "Return Response" 动作# (否则网关会等待 30 秒然后放弃)。result = client.workflows.trigger_flow_sync(flow["id"], {"contact_name": "Jane Smith","email": "jane@example.com",})print("Flow result:", result) -
将流程绑定到你的 AI 代理
在 Imbrace 仪表盘中打开你的 AI 代理,转到 工具 → 工作流,然后附加该流程。AI 代理将能够在对话中适当时触发它。
或者,更新 AI 代理以按名称引用工作流:
await client.chatAi.updateAiAgent(aiAgentId, {name: "Support Bot",workflow_name: "support_bot_v1",workflow_function_call: [{ flow_id: flow.id, description: "Update CRM on new lead" }],})client.chat_ai.update_ai_agent(ai_agent_id, {"name": "Support Bot","workflow_name": "support_bot_v1","workflow_function_call": [{"flow_id": flow["id"], "description": "Update CRM on new lead"}],}) -
查看运行历史
const { data: runs } = await client.workflows.listRuns({flowId: flow.id,limit: 10,})for (const run of runs) {console.log(run.id, run.status, run.startTime)}res = client.workflows.list_runs(flow_id=flow["id"], limit=10)for run in res.get("data", []):print(run["id"], run.get("status"), run.get("startTime"))
3. 管理知识中心并附加到 AI 代理
知识中心文件和文件夹位于 data-board 服务中(client.boards)。文件夹的 _id 就是你作为知识源传递给 AI 代理的值。
-
创建文件夹
const folder = await client.boards.createFolder({name: "Product Documentation",organization_id: process.env.IMBRACE_ORGANIZATION_ID,parent_id: "root",})console.log("Folder ID:", folder._id)folder = client.boards.create_folder({"name": "Product Documentation","organization_id": os.environ.get("IMBRACE_ORGANIZATION_ID"),"parent_id": "root",})print("Folder ID:", folder["_id"]) -
上传文件到文件夹
import { readFileSync } from "fs"const fileBuffer = readFileSync("./docs/faq.pdf")const formData = new FormData()formData.append("file", new Blob([fileBuffer], { type: "application/pdf" }), "faq.pdf")formData.append("folder_id", folder._id)formData.append("organization_id", process.env.IMBRACE_ORGANIZATION_ID ?? "")const uploaded = await client.boards.uploadFile(formData)console.log("File uploaded:", uploaded.file_id)from pathlib import Pathpath = Path("./docs/faq.pdf")files = {"file": (path.name, path.read_bytes(), "application/pdf"),"folder_id": (None, folder["_id"]),"organization_id": (None, os.environ.get("IMBRACE_ORGANIZATION_ID")),}uploaded = client.boards.upload_file(files)print("File uploaded:", uploaded.get("file_id") or uploaded.get("_id")) -
将文件夹附加到 AI 代理
在
folder_ids中传入文件夹_id— AI 代理会从该文件夹中的每个文件检索信息。使用board_ids附加一个 CRM 数据面板(其条目成为知识源 — 参见资源 → 面板与条目)。旧版knowledge_hubs字段已弃用。await client.chatAi.updateAiAgent(aiAgentId, {name: "Support Bot",workflow_name: "support_bot_v1",folder_ids: [folder._id],// board_ids: [boardId], // 可选:附加 CRM 数据面板})client.chat_ai.update_ai_agent(ai_agent_id, {"name": "Support Bot","workflow_name": "support_bot_v1","folder_ids": [folder["_id"]],# "board_ids": [board_id], # 可选:附加 CRM 数据面板}) -
检查和管理文件夹与文件
// 搜索文件夹const folders = await client.boards.searchFolders({ q: "Product" })// 获取文件夹及其内容const contents = await client.boards.getFolderContents(folder._id)console.log("Files:", contents.files?.length)// 重命名文件夹await client.boards.updateFolder(folder._id, { name: "Product Docs v2" })// 搜索文件夹中的文件const files = await client.boards.searchFiles({ folderId: folder._id })// 删除文件夹await client.boards.deleteFolders({ ids: [folder._id] })# 搜索文件夹folders = client.boards.search_folders(q="Product")# 获取文件夹及其内容contents = client.boards.get_folder_contents(folder["_id"])print("Files:", len(contents.get("files") or []))# 重命名文件夹client.boards.update_folder(folder["_id"], {"name": "Product Docs v2"})# 搜索文件夹中的文件files = client.boards.search_files(folder_id=folder["_id"])# 删除文件夹client.boards.delete_folders([folder["_id"]])
4. 管理数据面板与条目(CRM 管道)
-
创建面板
面板是一个 CRM 管道 — 线索、交易、任务或任何结构化数据。
const board = await client.boards.create({name: "Sales Pipeline",description: "Track all active deals",})console.log("Board ID:", board._id)board = client.boards.create(name="Sales Pipeline",description="Track all active deals",)print("Board ID:", board["_id"]) -
添加自定义字段
字段类型包括
ShortText、LongText、Number、Dropdown、Date、Checkbox等。createField返回更新后的面板 — 在board.fields中找到你的新字段。const updated = await client.boards.createField(board._id, {name: "Company",type: "ShortText",})// 找到标识符字段(每个面板自动创建)const identifierField = updated.fields.find(f => f.is_identifier)updated = client.boards.create_field(board["_id"], {"name": "Company","type": "ShortText",})identifier_field = next(f for f in updated["fields"] if f.get("is_identifier")) -
创建面板条目(记录)
条目使用
{ fields: [{ board_field_id, value }] }格式:const item = await client.boards.createItem(board._id, {fields: [{ board_field_id: identifierField._id, value: "Acme Corp" },],})console.log("Item ID:", item._id)item = client.boards.create_item(board["_id"], {"fields": [{"board_field_id": identifier_field["_id"], "value": "Acme Corp"},],})print("Item ID:", item["_id"]) -
列出和搜索条目
// 分页遍历条目const { data: items } = await client.boards.listItems(board._id, { limit: 20, skip: 0 })// 全文搜索const { data: results } = await client.boards.search(board._id, {q: "Acme",limit: 10,})# 分页遍历条目items = client.boards.list_items(board["_id"], limit=20, skip=0)# 全文搜索results = client.boards.search(board["_id"], q="Acme", limit=10) -
更新和删除条目
更新使用
{ data: [{ key, value }] }(注意:是key,不是board_field_id):await client.boards.updateItem(board._id, item._id, {data: [{ key: identifierField._id, value: "Acme Corp — Closed Won" }],})await client.boards.deleteItem(board._id, item._id)client.boards.update_item(board["_id"], item["_id"], {"data": [{"key": identifier_field["_id"], "value": "Acme Corp — Closed Won"}],})client.boards.delete_item(board["_id"], item["_id"]) -
导出为 CSV
const csv = await client.boards.exportCsv(board._id)// csv 是一个字符串 — 写入文件或作为下载发送csv = client.boards.export_csv(board["_id"])# csv 是一个字符串 — 写入文件或作为下载发送