> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 快速开始

> 5 步跑通你的第一个 Qoder Cloud Agent。

5 步跑通你的第一个 Qoder Cloud Agent：获取令牌、选择环境、创建 Agent、创建 Session、收发消息。全程只需 curl，无需安装任何 SDK。

## 前置条件

* 一个 Qoder 账号
* 终端环境（macOS / Linux / WSL）
* `curl` 和 `jq`（可选，用于格式化 JSON）

<Accordion title="Windows 用户" defaultOpen>
  本文档中的命令基于 bash 语法。Windows 用户推荐使用以下方式之一：

  * **Git Bash**（推荐）：安装 [Git for Windows](https://git-scm.com/download/win) 自带
  * **WSL**：通过 `wsl --install` 安装 Windows Subsystem for Linux

  如果使用 PowerShell，需注意以下差异：

  * 环境变量设置：`$env:QODER_PAT="your-token"`（而非 `export`）
  * 调用真实 curl：使用 `curl.exe`（PowerShell 的 `curl` 是 `Invoke-WebRequest` 的别名）
  * `jq` 需额外安装：`winget install jqlang.jq`
</Accordion>

## 第 1 步：获取 PAT

1. 登录 [Qoder 控制台](https://qoder.com)
2. 进入「设置 → 个人访问令牌」
3. 点击「创建令牌」，设置名称和有效期
4. 复制令牌并设置环境变量：

```bash theme={null}
export QODER_PAT="your-personal-access-token"
```

<Note>
  令牌只在创建时显示一次，请立即保存。建议写入 `~/.bashrc` 或 `~/.zshrc`。
</Note>

## 第 2 步：选择环境

查询可用环境列表，获取环境 ID：

```bash theme={null}
curl -s https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT"
```

响应示例：

```json theme={null}
{
  "data": [
    {
      "id": "env_019e44eb66bb748cabcd1489f6fa4428",
      "type": "environment",
      "name": "default",
      "description": "",
      "config": {
        "type": "cloud",
        "networking": {
          "type": "unrestricted",
          "allowed_hosts": [],
          "allow_package_managers": false,
          "allow_mcp_servers": false
        },
        "packages": {
          "type": "packages",
          "apt": [],
          "npm": [],
          "pip": []
        }
      },
      "metadata": {},
      "archived_at": null,
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z"
    }
  ],
  "first_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "last_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "has_more": false,
  "next_page": null
}
```

<Tip>
  如果返回 `"data": []`（空数组），说明账号下还没有环境，请先创建一个：

  ```bash theme={null}
  curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \
    -H "Authorization: Bearer $QODER_PAT" \
    -H "Content-Type: application/json" \
    -d '{"name":"default","config":{"type":"cloud","networking":{"type":"unrestricted"}}}'
  ```
</Tip>

```bash theme={null}
# 提取环境 ID（建议用 jq 自动提取，避免手动复制长 ID）
ENV_ID=$(curl -s https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT" | jq -r '.data[0].id')

echo "环境 ID: $ENV_ID"
```

## 第 3 步：创建 Agent

定义一个具备 shell 工具的通用 Agent：

```bash theme={null}
AGENT_RESPONSE=$(curl -s -X POST https://api.qoder.com/api/v1/cloud/agents \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-first-agent",
    "model": "ultimate",
    "system": "你是一个高效的编程助手，擅长代码编写和问题排查。",
    "tools": [
      {
        "type": "agent_toolset_20260401",
        "enabled_tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]
      }
    ]
  }')
echo "$AGENT_RESPONSE" | jq .
AGENT_ID=$(echo "$AGENT_RESPONSE" | jq -r '.id')
echo "Agent ID: $AGENT_ID"
```

响应示例：

```json theme={null}
{
  "id": "agent_019e451902fe7a2ca42c2dfc62d9320e",
  "type": "agent",
  "name": "my-first-agent",
  "description": "",
  "model": "ultimate",
  "system": "你是一个高效的编程助手，擅长代码编写和问题排查。",
  "tools": [
    {
      "type": "agent_toolset_20260401",
      "enabled_tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]
    }
  ],
  "mcp_servers": [],
  "skills": [],
  "metadata": {},
  "multiagent": null,
  "version": 1,
  "archived_at": null,
  "created_at": "2026-05-18T10:00:00Z",
  "updated_at": "2026-05-18T10:00:00Z"
}
```

## 第 4 步：创建 Session

创建 Session 需要两个必填参数：`agent`（Agent ID 或对象）和 `environment_id`（Environment ID）。

将 Agent 绑定到环境，创建运行实例：

```bash theme={null}
SESSION_RESPONSE=$(curl -s -X POST https://api.qoder.com/api/v1/cloud/sessions \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d "{
    \"agent\": \"$AGENT_ID\",
    \"environment_id\": \"$ENV_ID\"
  }")
echo "$SESSION_RESPONSE" | jq .
SESSION_ID=$(echo "$SESSION_RESPONSE" | jq -r '.id')
echo "Session ID: $SESSION_ID"
```

响应示例：

```json theme={null}
{
  "id": "sess_019e451b146470cda02c560bf019fb37",
  "type": "session",
  "agent": {
    "id": "agent_019e451902fe7a2ca42c2dfc62d9320e",
    "type": "agent",
    "name": "my-first-agent",
    "model": {"id": "ultimate", "effective_context_window": 200000},
    "version": 1
  },
  "environment_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "status": "idle",
  "title": null,
  "metadata": {},
  "resources": [],
  "vault_ids": [],
  "deployment_id": null,
  "outcome_evaluations": [],
  "stats": {"active_seconds": 0, "duration_seconds": 0},
  "environment_variables": {},
  "archived_at": null,
  "created_at": "2026-05-18T10:01:00Z",
  "updated_at": "2026-05-18T10:01:00Z"
}
```

<Note>
  Session 创建后处于 `idle` 状态，需要在下一步发送消息后 Agent 才会开始执行。
</Note>

## 第 5 步：发消息 + 收事件

向 Session 发送用户消息，然后通过 SSE 流实时接收 Agent 响应：

```bash theme={null}
# 发送消息（注意：请求体需要用 events 数组包裹）
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.message",
        "content": [{"type": "text", "text": "用 Python 写一个计算斐波那契数列的函数，并运行测试。"}]
      }
    ]
  }' | jq .
```

```bash theme={null}
# 通过 SSE 流实时接收事件
curl -s -N "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events/stream" \
  -H "Authorization: Bearer $QODER_PAT"
```

事件流输出示例：

```text theme={null}
id: evt_019ef515680d7a0ebd3160ca45ec5484
event: user.message
data: {"content":[{"text":"用 Python 写一个计算斐波那契数列的函数，并运行测试。","type":"text"}],"id":"evt_019ef515680d7a0ebd3160ca45ec5484","processed_at":"2026-06-23T15:24:41.357659669Z","type":"user.message"}

id: evt_019ef515681a7c52a0b45aa87625f121
event: session.status_running
data: {"id":"evt_019ef515681a7c52a0b45aa87625f121","processed_at":"2026-06-23T15:24:41.357659669Z","type":"session.status_running"}

event: heartbeat
data: {}

id: evt_49dce735a4ab4fc4
event: agent.thinking
data: {"id":"evt_49dce735a4ab4fc4","processed_at":"2026-06-23T15:24:49.357659Z","type":"agent.thinking"}

id: evt_02f80c5a8c245e04
event: agent.message
data: {"content":[{"text":"我将创建一个包含斐波那契函数和完整测试的 Python 模块。","type":"text"}],"id":"evt_02f80c5a8c245e04","processed_at":"2026-06-23T15:24:49.357659Z","type":"agent.message"}

id: evt_50739b167fb7c6d3
event: agent.tool_use
data: {"evaluated_permission":"allow","id":"evt_50739b167fb7c6d3","input":{"content":"def fibonacci(n): ...","file_path":"/data/fibonacci.py"},"name":"Write","processed_at":"2026-06-23T15:24:49.357659Z","type":"agent.tool_use"}

id: evt_e7c375f3605ff156
event: agent.tool_result
data: {"content":[{"text":"Write file /data/fibonacci.py successfully","type":"text"}],"id":"evt_e7c375f3605ff156","is_error":false,"processed_at":"2026-06-23T15:25:01.853844Z","type":"agent.tool_result"}

id: evt_60eba1483797a419
event: session.status_idle
data: {"id":"evt_60eba1483797a419","processed_at":"2026-06-23T15:25:24.436729Z","stop_reason":{"type":"end_turn"},"type":"session.status_idle"}
```

<Note>
  * 除 `heartbeat` 外，每条事件都有 `id:` 行，JSON 负载包含 `id`、`type` 和 `processed_at` 字段。
  * `heartbeat` 事件约每 15 秒发送一次，用于保持连接活跃。
  * `agent.message` 的 `content` 字段使用 `[{"type":"text","text":"..."}]` 数组格式。
  * `session.status_running` / `session.status_idle` 除 `id`、`type`、`processed_at`（idle 还有 `stop_reason`）外不携带其他字段。
  * `agent.thinking` 表示模型正在推理，不包含 `content` 或 `text` 字段。
</Note>

## 端到端脚本

将以上步骤整合为一个可直接运行的脚本：

```bash theme={null}
#!/bin/bash
# Qoder Cloud Agents 快速开始脚本
# 用法：export QODER_PAT="your-token" && bash quickstart.sh

set -euo pipefail

BASE_URL="https://api.qoder.com/api/v1/cloud"
HEADERS=(
  -H "Authorization: Bearer $QODER_PAT"
)

echo "=== 第 1 步：获取环境 ==="
ENV_ID=$(curl -s "$BASE_URL/environments" "${HEADERS[@]}" | jq -r '.data[0].id')
if [ "$ENV_ID" = "null" ] || [ -z "$ENV_ID" ]; then
  echo "未找到环境，正在创建默认环境..."
  ENV_ID=$(curl -s -X POST "$BASE_URL/environments" \
    "${HEADERS[@]}" \
    -H "Content-Type: application/json" \
    -d '{"name":"default","config":{"type":"cloud","networking":{"type":"unrestricted"}}}' | jq -r '.id')
fi
echo "环境 ID: $ENV_ID"

echo "=== 第 2 步：获取或创建 Agent ==="
AGENT_ID=$(curl -s "$BASE_URL/agents" "${HEADERS[@]}" | jq -r '.data[0].id')
if [ "$AGENT_ID" = "null" ] || [ -z "$AGENT_ID" ]; then
  AGENT_ID=$(curl -s -X POST "$BASE_URL/agents" \
    "${HEADERS[@]}" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "quickstart-agent",
      "model": "ultimate",
      "system": "你是一个高效的编程助手。",
      "tools": [
        {
          "type": "agent_toolset_20260401",
          "enabled_tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]
        }
      ]
    }' | jq -r '.id')
fi
echo "Agent ID: $AGENT_ID"

echo "=== 第 3 步：创建 Session ==="
SESSION_ID=$(curl -s -X POST "$BASE_URL/sessions" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d "{\"agent\": \"$AGENT_ID\", \"environment_id\": \"$ENV_ID\"}" | jq -r '.id')
echo "Session ID: $SESSION_ID"

echo "=== 第 4 步：发送消息 ==="
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {"type": "user.message", "content": [{"type": "text", "text": "打印 Hello World 并告诉我当前系统时间。"}]}
    ]
  }' | jq .

echo "=== 第 5 步：接收事件流 ==="
echo "（按 Ctrl+C 退出）"
curl -s -N "$BASE_URL/sessions/$SESSION_ID/events/stream" "${HEADERS[@]}"
```

## 常见问题

**Q: 提示 401 Unauthorized 怎么办？**

A: 检查 `$QODER_PAT` 是否已正确设置，令牌是否过期。重新创建令牌并更新环境变量。

**Q: 创建 Agent 返回 400 Bad Request？**

A: 检查请求体 JSON 格式是否正确，`model` 字段是否为有效值（如 `"ultimate"`），`tools` 是否为数组。

**Q: Session 一直处于 idle 状态，收不到事件？**

A: Session 创建后默认为 `idle`，必须向其发送 `user.message` 事件才会触发 Agent 执行。请确认第 5 步已正确执行。

**Q: SSE 流连接中断了怎么办？**

A: Stream endpoint 支持 `Last-Event-ID` header 进行断线重连。重连时在请求头中传入上次收到的事件 ID，流将从该事件之后开始重放。如需查询历史事件，请使用 `GET /api/v1/cloud/sessions/{id}/events?order=desc`。

**Q: `GET /api/v1/cloud/environments` 返回空数组？**

A: 新账号可能没有预置环境，请参照第 2 步中的提示手动创建一个。

## 下一步

<CardGroup cols={2}>
  <Card title="定义 Agent" icon="user-gear" href="/zh/cloud-agents/define-agent">
    了解 Agent 配置的全部字段。
  </Card>

  <Card title="云端环境配置" icon="server" href="/zh/cloud-agents/environments">
    自定义运行环境。
  </Card>

  <Card title="启动 Session" icon="play" href="/zh/cloud-agents/sessions">
    深入会话管理。
  </Card>

  <Card title="Agent Skills" icon="sparkles" href="/zh/cloud-agents/skills">
    为 Agent 附加领域专业知识，提升特定任务表现。
  </Card>
</CardGroup>
