Skip to content

Commit 4fdb1b7

Browse files
committed
docs: add managed mode quickstart recipe
Signed-off-by: murphy <starhaotian@gmail.com>
1 parent c958b56 commit 4fdb1b7

1 file changed

Lines changed: 189 additions & 0 deletions

File tree

  • content/zh-CN/recipes/managed-mode-quickstart
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
---
2+
schema_version: 1
3+
slug: managed-mode-quickstart
4+
title: Managed Mode 快速开始:创建 Session、对话并追踪 Credit 消耗
5+
summary: 用最小闭环跑通 Qoder Cloud Agents Managed Mode——创建 Session、发送消息、通过 SSE 事件流接收 Agent 回复,并读取每次模型调用的 Credit 消耗与 Session 累计用量。适合首次接入 Cloud Agents API 的开发者。
6+
type: recipe
7+
category: quick-start
8+
tags:
9+
- session
10+
- rest-api
11+
- sse
12+
- cost
13+
author:
14+
name: murphy
15+
locale: zh-CN
16+
---
17+
18+
## 目标与适用场景
19+
20+
这篇 Recipe 带你用五个 curl 命令跑通 Managed Mode 的最小闭环:创建 Session → 发消息 → 通过事件流接收 Agent 回复 → 查看 Credit 消耗。Managed Mode 下 Agent 运行在 Qoder Cloud 托管环境中,你只需调用 API,无需维护运行环境。适合首次接入 Cloud Agents API 的开发者。
21+
22+
先认识文中反复出现的五个概念:
23+
24+
| 概念 | 说明 |
25+
|---|---|
26+
| Agent | 可复用的 Agent 配置:模型、系统提示词、工具和技能 |
27+
| Environment | Session 的运行环境配置,Managed Mode 下由 Qoder Cloud 托管 |
28+
| Session | Agent 的一次运行实例,绑定 Agent 与 Environment,承载一段对话任务 |
29+
| 事件(Event) | 你与 Agent 之间交换的消息:用户消息、Agent 回复、状态变更等 |
30+
| Credit | 计费单位,每次模型调用按量消耗,累计在 Session 的 `usage` 中 |
31+
32+
整体调用时序如下:
33+
34+
```mermaid
35+
sequenceDiagram
36+
participant C as 客户端
37+
participant A as Cloud Agents API
38+
C->>A: 创建 Session
39+
A-->>C: 返回 Session ID,状态为 idle
40+
C->>A: 连接 SSE 事件流
41+
C->>A: 发送 user.message
42+
A-->>C: agent.message(Agent 回复)
43+
A-->>C: span.model_request_end(含单次 credits)
44+
A-->>C: session.status_idle(本轮结束)
45+
```
46+
47+
开始前,准备好 PAT、Agent ID(及版本号)和托管 Environment ID,并设置为环境变量:
48+
49+
```bash
50+
export QODER_PAT="<你的 PAT>"
51+
export AGENT_ID="<agent_ 前缀的 Agent ID>"
52+
export AGENT_VERSION="<Agent 版本号>"
53+
export ENVIRONMENT_ID="<env_ 前缀的 Environment ID>"
54+
export BASE_URL="https://api.qoder.com/api/v1/cloud"
55+
```
56+
57+
## 操作步骤
58+
59+
### 第一步:创建 Session
60+
61+
Session 创建后处于 `idle`,等待输入:
62+
63+
```bash
64+
curl -s -X POST "$BASE_URL/sessions" \
65+
-H "Authorization: Bearer $QODER_PAT" \
66+
-H "Content-Type: application/json" \
67+
-d @- <<EOF
68+
{
69+
"agent": {"id": "$AGENT_ID", "type": "agent", "version": $AGENT_VERSION},
70+
"environment_id": "$ENVIRONMENT_ID",
71+
"title": "Managed Mode 快速开始"
72+
}
73+
EOF
74+
```
75+
76+
显式传入 `version` 可锁定 Agent 版本,避免 Agent 更新导致行为变化。响应中的关键字段:
77+
78+
```json
79+
{
80+
"id": "<SESSION_ID>",
81+
"type": "session",
82+
"status": "idle",
83+
"usage": {"total_credits": 0}
84+
}
85+
```
86+
87+
保存返回的 Session ID,后续调用都要用到:
88+
89+
```bash
90+
export SESSION_ID="<返回的 sess_ 前缀 ID>"
91+
```
92+
93+
### 第二步:连接 SSE 事件流
94+
95+
Agent 的输出不随发消息的响应返回,而是通过事件流推送。建议先连接事件流再发消息。在第一个终端执行并保持连接:
96+
97+
```bash
98+
curl -s -N "$BASE_URL/sessions/$SESSION_ID/events/stream" \
99+
-H "Authorization: Bearer $QODER_PAT" \
100+
-H "Accept: text/event-stream"
101+
```
102+
103+
断线重连时在请求头带上 `Last-Event-ID`,服务端会从该事件之后续传。
104+
105+
### 第三步:发送消息
106+
107+
在第二个终端发送 `user.message` 事件,`content` 是非空的 content block 数组:
108+
109+
```bash
110+
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
111+
-H "Authorization: Bearer $QODER_PAT" \
112+
-H "Content-Type: application/json" \
113+
-d '{
114+
"events": [
115+
{
116+
"type": "user.message",
117+
"content": [
118+
{"type": "text", "text": "你好,请用一句话介绍你自己。"}
119+
]
120+
}
121+
]
122+
}'
123+
```
124+
125+
返回 HTTP 200 和 `{"data": [...]}` 即受理成功,Session 从 `idle` 进入 `running`。
126+
127+
### 第四步:在事件流中读取回复与 Credit 消耗
128+
129+
回到第一个终端。流中还会出现 `session.status_running` 等状态事件,其中三类关键事件如下(实际输出节选,ID 已脱敏):
130+
131+
```text
132+
id: <EVENT_ID>
133+
event: agent.message
134+
data: {"type":"agent.message","content":[{"type":"text","text":"你好,我是 Hello World Agent,一个能研究、写代码、运行命令并使用工具端到端完成任务的通用助手。"}]}
135+
136+
id: <EVENT_ID>
137+
event: span.model_request_end
138+
data: {"type":"span.model_request_end","is_error":false,"model_usage":{"credits":4.05}}
139+
140+
id: <EVENT_ID>
141+
event: session.status_idle
142+
data: {"type":"session.status_idle","stop_reason":{"type":"end_turn"}}
143+
```
144+
145+
- `agent.message`:Agent 的消息回复,正文在 `content` 数组的 `text` 中。
146+
- `span.model_request_end`:一次模型调用结束,`model_usage.credits` 是本次消耗的 credits(向下取整、最多 2 位小数,数据不可用时省略该字段)。
147+
- `session.status_idle`:本轮结束,`stop_reason.type` 为 `end_turn` 表示正常完成。看到它之后才能发送下一条消息。
148+
149+
### 第五步:查询 Session 累计 Credit
150+
151+
随时可查询 Session 级的累计用量:
152+
153+
```bash
154+
curl -s "$BASE_URL/sessions/$SESSION_ID" \
155+
-H "Authorization: Bearer $QODER_PAT"
156+
```
157+
158+
```json
159+
{
160+
"id": "<SESSION_ID>",
161+
"status": "idle",
162+
"usage": {"total_credits": 4.63}
163+
}
164+
```
165+
166+
`usage.total_credits` 是**快照而非增量**:重复查询时用新值覆盖本地记录,不要累加。实测本轮事件流中只有一个 4.05 credits 的 span,而累计值为 4.63——span 事件不一定覆盖全部计费调用,对账以 `total_credits` 为准。
167+
168+
## 验证结果
169+
170+
逐项确认链路已跑通:
171+
172+
1. 创建 Session 返回 HTTP 200,`id` 以 `sess_` 为前缀,`status` 为 `idle`。
173+
2. 发送消息返回 HTTP 200,`data` 数组包含你发送的 `user.message`。
174+
3. 事件流中出现 `agent.message`,并以 `session.status_idle`(`stop_reason.type` 为 `end_turn`)收尾。
175+
4. `span.model_request_end` 携带 `model_usage.credits`;再次查询 Session,`usage.total_credits` 大于 `0`。
176+
177+
## 可选:常见问题
178+
179+
**Q: 发送消息时收到 HTTP 409?**
180+
181+
Session 还在处理上一轮(`running`)。请等事件流出现 `session.status_idle` 再发下一条,或先调用 `POST /api/v1/cloud/sessions/{id}/cancel` 中断当前轮。
182+
183+
**Q: SSE 断线后如何续传?**
184+
185+
重连时在请求头传入 `Last-Event-ID`(断线前收到的最后一个事件的 `id`),服务端会从该事件之后重放。
186+
187+
**Q: 事件里没有 `model_usage` 字段?**
188+
189+
credits 数据不可用时该字段会被省略。对账请以 `GET /api/v1/cloud/sessions/{id}` 返回的 `usage.total_credits` 为准。

0 commit comments

Comments
 (0)