# 5 - Python 调用 Coze 平台工作流 本章偏**平台调用实战**:学会用 API 和 Python 调用你在 Coze 上已搭建好的工作流,把“扣子里的工作流”接进本地代码和业务系统。 --- **本章课程目标:** - 知道调用前需在 Coze 中**发布 API**,并在 API 调试页面拿到 `workflow_id`、`app_id` 和 API Key。 - 理解 Coze 工作流调用里最关键的请求字段:`workflow_id`、`app_id`、`parameters`。 - 能看懂 Coze 流式返回里的常见事件:`PING`、`Message`、`Done`。 - 能用 **cozepy** 官方 SDK 在本地跑通一次最小调用,并知道真实项目里为什么要用环境变量而不是把密钥写死在代码里。 **学习建议:** 这章和第 4 章最适合对照着看。你会发现两个平台虽然界面、SDK 和字段命名不同,但背后的主线是一样的:**平台发布 -> 鉴权 -> 传业务参数 -> 收事件流 -> 去平台日志核对结果**。 --- ## 1、调用前必须先发布 API Coze 的 API 能力需要通过应用发布功能启用。 ![Coze 工作流发布 API 入口的界面示意图](images/5/5-1-1-1.png) 这一步的意义和 Dify 很像:只有发布后的工作流,才适合作为外部系统依赖的稳定入口。 --- ## 2、先在平台里把关键信息拿全 ### 2.1 API 调试入口 发布成功后,在工作流画布页面可以看到 API 调试入口。 ![Coze 工作流画布中的 API 调试入口界面](images/5/5-2-1-1.png) ### 2.2 查看 workflow_id 和 app_id 通过 API playground,选择右侧的 Shell 请求方式。 界面中会显示: - **工作流 ID**:`workflow_id` - **应用 ID**:`app_id` ![Coze API Playground 中查看 workflow_id 和 app_id 的界面](images/5/5-2-2-1.png) 可以这样理解: - `workflow_id`:这次到底执行哪一个工作流 - `app_id`:这个工作流属于哪个应用上下文 ### 2.3 生成并授权 API Key 左侧窗口向下滑动,可以看到 token(即 API Key),点击“授权”按钮。 ![Coze API Playground 中生成并授权 API Key 的界面](images/5/5-2-3-1.png) 点击后会自动生成并填充 API Key。 ![Coze API Playground 中自动填充 API Key 后的界面](images/5/5-2-3-2.png) 右侧的 Shell 命令窗口会同步更新。 ### 2.4 添加参数 请求体中的 `parameters` 对象用于向工作流传递参数,该对象的每个属性都对应工作流中的一个输入变量。 ![Coze API Playground 中配置 parameters 入参的界面](images/5/5-2-4-1.png) 这也是 Coze 调用里最容易出错的地方。因为它不是“差不多就行”,而是**字段名、类型、结构都必须对齐平台里的定义**。 ### 2.5 运行 可以直接点击 Shell 命令窗口右上角的“运行”按钮。 ![Coze API Playground 中运行工作流请求的界面](images/5/5-2-5-1.png) --- ## 3、看懂最小调用请求 平台里看到的 curl 命令大致如下: ```sh curl -X POST 'https://api.coze.cn/v1/workflow/stream_run' \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "workflow_id": "{workflow_id}", "app_id": "{app_id}", "parameters": { "link": "https://example.com/video" } }' ``` 这里最关键的字段只有三个: - `workflow_id`:执行哪个工作流 - `app_id`:归属哪个应用 - `parameters`:传给工作流的实际业务参数 > **注意:** JSON 标准不支持注释,所以请求体里不要写 `# 说明文字` 这种内容。 --- ## 4、怎么看流式结果 ### 4.1 运行结果界面 ![Coze 工作流流式运行结果界面的整体示意图](images/5/5-4-1-1.png) ### 4.2 Message ![Coze 流式返回中 Message 事件内容的界面示意图](images/5/5-4-2-1.png) `Message` 才是携带真正业务内容的事件类型,此处的 `content` 就是工作流某一步的输出。 ### 4.3 Done ![Coze 流式返回中 Done 结束事件的界面示意图](images/5/5-4-3-1.png) `Done` 表示流式响应结束,通常出现在所有 `Message` 之后。 ### 4.4 你真正需要记住的三类信号 - **PING**:心跳包,只负责保活连接,通常可忽略。 - **Message**:真正携带内容的事件。 - **Done**:整次流式输出结束。 > **可这样记:** 写代码时,重点关注 `Message` 和结束信号;`PING` 不是业务结果,只是说明连接还活着。 --- ## 5、用 Python 调用 Coze 工作流 ### 5.1 官方 Python SDK 入口 Coze 提供了官方 Python SDK:`cozepy`。 ![Coze 官方 Python SDK cozepy 的文档或仓库界面示意图](images/5/5-5-1-1.png) ### 5.2 安装依赖 ```sh pip install cozepy ``` ### 5.3 示例源码 ````python """ This example describes how to use the workflow interface to stream chat. """ import os # Our official coze sdk for Python [cozepy](https://github.com/coze-dev/coze-py) from cozepy import COZE_CN_BASE_URL # Get an access_token through personal access token or oauth. coze_api_token = '{API_KEY}' # The default access is api.coze.com, but if you need to access api.coze.cn, # please use base_url to configure the api endpoint to access coze_api_base = COZE_CN_BASE_URL from cozepy import Coze, TokenAuth, Stream, WorkflowEvent, WorkflowEventType # noqa # Init the Coze client through the access_token. coze = Coze(auth=TokenAuth(token=coze_api_token), base_url=coze_api_base) # Create a workflow instance in Coze, copy the last number from the web link as the workflow's ID. workflow_id = '{WORKFLOW_ID}' # The stream interface will return an iterator of WorkflowEvent. Developers should iterate # through this iterator to obtain WorkflowEvent and handle them separately according to # the type of WorkflowEvent. def handle_workflow_iterator(stream: Stream[WorkflowEvent]): for event in stream: if event.event == WorkflowEventType.MESSAGE: print("got message", event.message) elif event.event == WorkflowEventType.ERROR: print("got error", event.error) elif event.event == WorkflowEventType.INTERRUPT: handle_workflow_iterator( coze.workflows.runs.resume( workflow_id=workflow_id, event_id=event.interrupt.interrupt_data.event_id, resume_data="hey", interrupt_type=event.interrupt.interrupt_data.type, ) ) handle_workflow_iterator( coze.workflows.runs.stream( workflow_id=workflow_id ) ) ### 5.4 在本地 PyCharm 中运行 当你直接拷贝平台生成代码时,如果工作流定义了输入变量,但 `stream()` 调用里没有传 `parameters`,就会报错。 ![在 PyCharm 中运行 Coze 工作流代码时报缺少 parameters 的界面示意图](images/5/5-5-4-1.png) 平台里的提示也已经很清楚: ![Coze 平台提示需要传入 parameters 参数的界面示意图](images/5/5-5-4-2.png) **处理方式**:在从 Coze 平台拷贝的代码基础上,为 `stream()` 调用增加 **parameters** 参数: ```python handle_workflow_iterator( coze.workflows.runs.stream( workflow_id=workflow_id, parameters={ "link": "https://www.bilibili.com/video/BV1S2421P788/?share_source=copy_web&vd_source=8d04b2c1b7fd20888b03c20e99f26dc0" # 替换成实际需要的链接 } ) ) ```` ### 5.4 最终代码 ```python """ This example describes how to use the workflow interface to stream chat. """ import os # Our official coze sdk for Python [cozepy](https://github.com/coze-dev/coze-py) from cozepy import COZE_CN_BASE_URL # Get an access_token through personal access token or oauth. coze_api_token = 'cztei_hXYOqnustyYyhrSuGFl4tgcxJ9E2KjYLPnHvcEcoWRwWvujWU0sPqka8xyQ1wsCyi' # The default access is api.coze.com, but if you need to access api.coze.cn, # please use base_url to configure the api endpoint to access coze_api_base = COZE_CN_BASE_URL from cozepy import Coze, TokenAuth, Stream, WorkflowEvent, WorkflowEventType # noqa # Init the Coze client through the access_token. coze = Coze(auth=TokenAuth(token=coze_api_token), base_url=coze_api_base) # Create a workflow instance in Coze, copy the last number from the web link as the workflow's ID. workflow_id = '7537267958432858127' # The stream interface will return an iterator of WorkflowEvent. Developers should iterate # through this iterator to obtain WorkflowEvent and handle them separately according to # the type of WorkflowEvent. def handle_workflow_iterator(stream: Stream[WorkflowEvent]): for event in stream: if event.event == WorkflowEventType.MESSAGE: print("got message", event.message) elif event.event == WorkflowEventType.ERROR: print("got error", event.error) elif event.event == WorkflowEventType.INTERRUPT: handle_workflow_iterator( coze.workflows.runs.resume( workflow_id=workflow_id, event_id=event.interrupt.interrupt_data.event_id, resume_data="hey", interrupt_type=event.interrupt.interrupt_data.type, ) ) handle_workflow_iterator( coze.workflows.runs.stream( workflow_id=workflow_id, parameters={ "link": "https://www.bilibili.com/video/BV1S2421P788/?share_source=copy_web&vd_source=8d04b2c1b7fd20888b03c20e99f26dc0" # 替换成实际需要的链接 } ) ) ``` ### 5.5 运行结果 ![Python 调用 Coze 工作流后的运行结果界面示意图](images/5/5-5-5-1.png) ## 6、除了 SDK,还可以在平台侧运行 如果你只是想先确认工作流本身能正常输出,也可以直接在平台里测试。 ![在 Coze 平台侧直接测试工作流输出的界面示意图](images/5/5-6-1-1.png) 真实项目中,推荐的顺序通常是: 1. 先在平台确认工作流逻辑跑通 2. 再用 API playground 验证请求结构 3. 最后再接入 Python 代码 这样最容易把问题分层定位,而不是平台和代码一起调,最后什么都分不清。 --- **章节思考题:** 1. 调用 Coze 工作流前,你会如何确认“平台侧已经准备好”? **参考思路:** 先确认工作流发布状态、Token 或鉴权方式、`workflow_id`、必要的 `app_id` / `bot_id`、输入参数和平台侧测试结果。平台侧没跑通时,Python 代码再完整也只会放大问题。 2. Coze 和 Dify 的接口字段不同,但调用主线为什么很像? **参考思路:** 两者本质都是把平台工作流暴露成 API:发布、鉴权、传业务参数、接收运行结果、回日志核对。字段名会变,排查顺序和工程关注点差不多。 3. 如果 Python 代码没有拿到预期输出,你会如何分层排查? **参考思路:** 先在平台调试工作流,再用 API playground 或最小请求确认接口,最后看 Python 解析逻辑。这样能分清是平台配置、接口参数、鉴权,还是代码处理的问题。 **本章小结:** - **调用前提**:Coze 工作流要先发布 API,并确认 `workflow_id`、`app_id` 和 API Key 都已拿到。 - **调用核心**:`cozepy` 帮你封装了请求与事件流,但真正最关键的仍然是 `parameters` 是否和工作流输入变量一一对齐。 - **事件流不要只看正文**:Coze 的流式执行除了正常输出,还可能出现 ERROR、INTERRUPT 等事件。学这章时,重点不是“能打印出一段文本”,而是能正确理解一次工作流执行到底是成功完成、等待干预,还是中途失败。 - **调试主线**:和第 4 章一样,平台调试和代码调用要相互印证;一旦结果异常,优先看参数映射、事件流、平台侧调试输出和本地日志是否能互相对上。 **建议下一步:** 如果你想继续走 Coze 本地化和私有化路线,可以看 [第 6 章 Coze 与 Dify 的 Windows 平台部署](6-Coze与Dify的Windows平台部署.md);如果你想从平台调用进一步过渡到代码框架主线,也可以回到 [第 9 章 LangChain 概述与架构](9-LangChain概述与架构.md) 开始进入 LangChain 学习。