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

# Agents

> 在 BRICKS Buttress 設定中定義 LLM agent，將本地函式作為它的工具，並從函式、HTTP 或 CLI 驅動它

agent 是你在 [BRICKS Buttress](/zh-Hant/buttress) 伺服器設定中宣告的 LLM 迴圈。它在**伺服器行程內**執行，以[本地函式](/zh-Hant/buttress/functions)（以及 MCP 伺服器）作為工具，並把對話歷史保存在磁碟上的 session 檔案中。

主要的使用者是自動化流程：本地函式或 daemon 呼叫 `context.agents.run(...)`，為伺服器端的工作流程加入多步推理。另有互動式 CLI 可驅動並檢視同一批 agent。

<Warning>
  Agents 屬於實驗性功能。`[[agents]]` 與 `[agents_options]` 設定鍵、`/agents` 端點、SSE 事件結構以及 `context.agents` API 都可能在版本之間變動，且不保證有淘汰緩衝期。伺服器啟動時會顯示這項提醒。若你要以此為基礎開發，請鎖定 `bricks-buttress` 版本，並在升級後重新閱讀本頁。
</Warning>

## 定義 agent

在設定至少宣告一個 `[[agents]]` 區段之前，agents 都是關閉的：

```toml theme={null}
[[agents]]
name = "ops-assistant"                            # 必須唯一；同時是 session 的範圍索引鍵
model = "buttress/ggml-org/gpt-oss-20b-GGUF"      # provider/model-id，以「第一個」斜線切分
system_prompt = "You are an ops automation agent. Use the provided tools."
# system_prompt_file = "./prompts/ops.md"         # 或改用檔案；兩者不可並存
tools = ["get-server-status", "restart-service"]  # 本地函式名稱
max_turns = 30
# max_tokens_per_run = 200000
# temperature = 0.2                               # 未被辨識的鍵會直接傳遞給生成

[agents.mcp_servers.github]                       # 選用的 MCP 伺服器
url = "https://api.githubcopilot.com/mcp/"
# optional = true
```

| 鍵                             | 型別        | 預設值  | 說明                                                                   |
| ----------------------------- | --------- | ---- | -------------------------------------------------------------------- |
| `name`                        | string    | —    | 必填。在設定中必須唯一，同時是該 agent session 的範圍索引鍵。可使用英文字母、數字、`-` 與 `_`，最長 64 個字元 |
| `model`                       | string    | —    | 必填。格式為 `provider/model-id`，以**第一個**斜線切分。請參閱 [模型](#模型)                |
| `system_prompt`               | string    | —    | 直接內嵌的系統提示                                                            |
| `system_prompt_file`          | string    | —    | 系統提示檔案路徑；相對路徑以設定檔為基準解析，`~` 會展開為家目錄。與 `system_prompt` 互斥              |
| `tools`                       | string\[] | `[]` | 本地函式名稱，必須逐一列出，不支援萬用字元。請參閱 [工具](#工具)                                  |
| `max_turns`                   | integer   | `30` | 每次執行的「助理↔工具」往返次數上限                                                   |
| `max_tokens_per_run`          | integer   | 無上限  | 每次執行的 token 預算                                                       |
| `[agents.mcp_servers.<name>]` | table     | `{}` | 要加入為工具的 MCP 伺服器。請參閱 [MCP 伺服器](#mcp-伺服器)                              |

上表未列出的鍵都會直接傳遞給生成，因此 `temperature`、`top_p` 等設定可照寫。

agent 定義會在**啟動時**驗證，而不是等到第一次執行：未知的 `buttress/` 模型、找不到的提示檔案、格式錯誤的工具名稱或重複的 agent 名稱，都會讓伺服器直接報錯停止，而不是默默略過該 agent。

### 全域選項

`[agents_options]` 會套用到每個 agent：

```toml theme={null}
[agents_options]
# sessions_dir = "./.buttress-agent/sessions"
# session_max_age = "30d"
# session_max_count = 500
# max_depth = 2
# allow_unauthenticated = false
```

| 鍵                       | 型別              | 預設值                            | 說明                                         |
| ----------------------- | --------------- | ------------------------------ | ------------------------------------------ |
| `sessions_dir`          | string          | `"./.buttress-agent/sessions"` | session 檔案的存放位置。相對路徑以設定檔為基準解析，`~` 會展開為家目錄  |
| `session_max_age`       | number 或 string | `"30d"`                        | 依存留時間清理，可用毫秒數或時間長度字串。設為 `0` 則停用            |
| `session_max_count`     | integer         | `500`                          | 依數量清理，以每個 agent 計。設為 `0` 則停用               |
| `max_depth`             | integer         | `2`                            | 連鎖 agent 呼叫的深度上限 — 函式 → agent → 函式 → agent |
| `allow_unauthenticated` | boolean         | `false`                        | 在**未繫結**的伺服器上提供 `/agents`。請參閱 [安全性](#安全性)  |

## 模型

`model` 的格式是 `provider/model-id`，以第一個斜線切分，因此 model id 本身可以含有斜線。

**`buttress/<repo_id>`** 指向這台伺服器已經載入的模型。該 id 必須對應到某個已設定的 `ggml-llm` 或 `mlx-llm` [`[[generators]]`](/zh-Hant/buttress/configuration#generators) 項目的 `repo_id`，伺服器會在啟動時檢查。流量透過行程內的 loopback 抵達 generator — 不經過 socket，也不需要額外設定。你不需要啟用 `[openai_compat]`；該鍵仍然只管外部的 HTTP 路由。

```toml theme={null}
[[generators]]
type = "ggml-llm"

[generators.model]
repo_id = "ggml-org/gpt-oss-20b-GGUF"

[[agents]]
name = "ops-assistant"
model = "buttress/ggml-org/gpt-oss-20b-GGUF"
```

**其他前綴**則代表雲端供應商 — `anthropic/…`、`openai/…`、`google/…` — 並以該供應商慣用的環境變數（`ANTHROPIC_API_KEY`、`OPENAI_API_KEY` 等）進行驗證。請在 `[env]` 或行程環境中設定。

```toml theme={null}
[env]
ANTHROPIC_API_KEY = "sk-ant-…"

[[agents]]
name = "reviewer"
model = "anthropic/claude-sonnet-5"
```

<Note>
  不支援以 OAuth 登入供應商。使用雲端供應商時，環境中必須有 API key。
</Note>

## 工具

`tools` 必須逐一列出本地函式名稱。每次工具呼叫都會走一般的函式執行器，因此工具會取得與透過 HTTP 或 MCP 呼叫時相同的延遲重新載入、暫存目錄、行程追蹤與 `meta.timeout` 期限 — 而模型看到的參數結構就是該函式的 `meta.parameters` JSON Schema。

中止一次執行時，會一併中止進行中的工具呼叫，以及這些呼叫所產生的行程。

若列出的函式並不存在，該次執行會**直接失敗**，而不是讓無人值守的自動化流程繞過缺少的能力自行發揮。

### MCP 伺服器

`[agents.mcp_servers.<name>]` 可在本地函式之外，額外加入某個 MCP 伺服器的工具。每個伺服器只能指定 `url`（Streamable HTTP）或 `command`（stdio）其中一項：

```toml theme={null}
[agents.mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
headers = { Authorization = "Bearer ghp_…" }

[agents.mcp_servers.local]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/srv/data"]
# env = { LOG_LEVEL = "debug" }
optional = true
```

MCP 工具會以帶伺服器前綴的名稱公開 — `mcp__github__create_issue` — 因此不會與本地函式名稱衝突。伺服器會在第一次需要它的執行時延遲連線；若某個伺服器無法連線，該次執行會**直接失敗**，除非它標記了 `optional = true`，此時 agent 會在沒有該伺服器工具的情況下繼續執行。

## 執行 agent

### 從本地函式

這是主要的使用介面。每個已設定的 agent 都可透過 `context.agents` 取用：

```ts theme={null}
export const meta = {
  description: 'Ask the ops agent to investigate a service.',
  timeout: '10m',
}

export default async ({ service }: { service: string }, context: ButtressFunctionContext) => {
  const result = await context.agents.run('ops-assistant', {
    prompt: `Investigate the '${service}' service and fix it if needed.`,
  })
  return { conclusion: result.content, sessionId: result.sessionId }
}
```

| 成員                                  | 用途                                                                                           |
| ----------------------------------- | -------------------------------------------------------------------------------------------- |
| `agents.run(name, options)`         | 執行一段提示直到完成 → [`AgentRunResult`](#執行結果)。選項有 `prompt`、`sessionId`、`fork`、`onEvent`、`onSession` |
| `agents.list()`                     | 已設定的 agent 名稱                                                                                |
| `agents.sessions(name, { limit? })` | 由新到舊的 [session 摘要](#sessions)                                                                |

一次執行會沿用呼叫端函式的生命週期與期限：`context.signal` — 函式的 `meta.timeout` 到期，或呼叫端斷線 — 會中止該次執行及其工具呼叫。agent 迴圈比一般函式呼叫慢得多，因此請調高 `meta.timeout`，或把工作移到沒有期限的 **daemon**。

agent 的進度會映射到函式自己的 SSE 串流上，成為 `agent` 事件，因此*函式*的 SSE 呼叫端不需額外接線就能看到 agent 的執行過程。

若伺服器沒有設定任何 `[[agents]]`，上述每個方法都會拋出例外。

### 透過 HTTP

| 端點                                        | 用途                                                                 |
| ----------------------------------------- | ------------------------------------------------------------------ |
| `GET /agents`                             | 已設定的 agent 名稱 → `{ "agents": [...] }`                              |
| `POST /agents/<name>/run`                 | 執行一段提示。請求主體為 `{ prompt, sessionId?, fork? }`，回應為 `{ "result": … }` |
| `POST /agents/<name>/run?stream=1`        | 同一個呼叫，改以 SSE 回傳 — 先是 `agent` 進度事件，接著是結果                            |
| `GET /agents/<name>/sessions`             | 由新到舊的 session 摘要。`?limit=` 可限制數量                                   |
| `GET /agents/<name>/sessions/<id>`        | 完整逐字記錄 → `{ "messages": [...] }`                                   |
| `POST /agents/<name>/sessions/<id>/abort` | 中止該 session 進行中的執行 → `{ "aborted": true \| false }`                |

```bash theme={null}
curl -X POST http://localhost:2080/agents/ops-assistant/run \
  -H 'Authorization: Bearer <workspace-access-token>' \
  -H 'Content-Type: application/json' \
  -d '{"prompt": "Which services are unhealthy?"}'
```

執行失敗時會回傳 `AGENT_RUN_FAILED`，並附上 `sessionId`，因此仍然可以取得逐字記錄。被中止的執行回應 `499`，其他失敗回應 `500`。找不到的 agent 與 session 回應 `404 NOT_FOUND`。

串流回應攜帶的是精簡過的 agent 事件：不含部分完成的助理訊息與完整工具結果，因為那會讓串流負載過於龐大。需要完整記錄時，請改從 sessions 端點取得逐字記錄。

### 從 CLI

`bricks-buttress agent` 是一個串流式聊天用戶端，用來連線**執行中**伺服器上的 agent。只要指向伺服器所使用的同一份設定檔，它就會自行找出連接埠與本機 token：

```sh theme={null}
bricks-buttress agent -c config.toml                                # 列出 agent
bricks-buttress agent ops-assistant -c config.toml                  # 聊天
bricks-buttress agent ops-assistant --sessions -c config.toml       # 列出 session
bricks-buttress agent ops-assistant --session <id> -c config.toml   # 接續某個 session
bricks-buttress agent ops-assistant --fork <id> -c config.toml      # 分支後接續該分支
```

| 選項                    | 說明                                            |
| --------------------- | --------------------------------------------- |
| `-c, --config <path>` | 伺服器設定檔 — 用來找出連接埠與本機執行階段 token                 |
| `--url <url>`         | 伺服器基底 URL。預設取自設定檔，否則為 `http://127.0.0.1:2080` |
| `--token <token>`     | 存取 token。預設取自設定檔的執行階段 token 檔案                |
| `--session <id>`      | 接續既有的 session                                 |
| `--fork <id>`         | 分支某個 session，然後接續該分支                          |
| `--sessions`          | 列出該 agent 的 session 後結束                       |

聊天過程會即時串流文字、思考內容與工具呼叫。在聊天中，`/exit` 可離開，`/new` 可開始新的 session，<kbd>Ctrl</kbd>+<kbd>C</kbd> 會中止目前的執行 — 再按一次 <kbd>Ctrl</kbd>+<kbd>C</kbd> 則離開。

### 執行結果

`context.agents.run` 與 `POST /agents/<name>/run` 都會回傳：

| 欄位                 | 說明                                                  |
| ------------------ | --------------------------------------------------- |
| `sessionId`        | 這次執行寫入的 session — 傳回它即可接續                           |
| `content`          | agent 的最終回答                                         |
| `reasoningContent` | 模型有產生思考內容時，此處為該內容                                   |
| `usage`            | `{ input, output, cacheRead, totalTurns }`，為整次執行的彙總 |
| `stopReason`       | 迴圈結束的原因                                             |

`stopReason` 為 `end_turn`（agent 已作答）、`max_turns`、`token_budget`、`aborted` 或 `error` 其中之一。除 `end_turn` 外，都應視為未完成的回答。

## Sessions

每次執行都屬於某個 session。省略 `sessionId` 就會開啟新的 session；把它傳回則接續該對話；若同時加上 `fork: true`，則會分支出一個新的 session 並記下其來源，原本的 session 維持不變。

session 是 `sessions_dir` 底下的 JSONL 檔案，以 agent 名稱區分範圍，並在執行串流的**同時**寫入 — 因此被中止或逾時的執行仍會留下可接續的逐字記錄。

同一個 session 上的執行會依序排隊；不同 session 則平行執行。

清理機制會依存留時間（`session_max_age`）與數量（`session_max_count`，以每個 agent 計）清除舊的 session。

<Note>
  session 是以 agent 的 `name` 區分範圍。重新命名 agent 會讓既有的 session 失去歸屬 — 檔案仍留在磁碟上，但更名後的 agent 不會列出或接續它們。
</Note>

## 安全性

`/agents` 的驗證方式與[本地函式介面](/zh-Hant/buttress/functions#安全性)相同，而非比照開放的推論端點：

* **已繫結**的伺服器需要 workspace 存取 token。請參閱[工作區繫結](/zh-Hant/buttress/workspace-binding)。
* **未繫結**的伺服器會完全拒絕遠端呼叫，除非設定 `[agents_options] allow_unauthenticated = true`。
* 跨站的瀏覽器請求一律遭到拒絕。

伺服器啟動時會在 `sessions_dir` 旁寫入一個臨時的**執行階段 token** 檔案 `runtime-token`，權限為 `0600`。同一台主機上的工具 — 例如上述 CLI — 會讀取它並自動完成驗證，無論伺服器是否已繫結。

<Warning>
  `allow_unauthenticated = true` 會讓任何能連到該連接埠的人執行每個 agent，連帶執行你交給它的每個工具。請只在受信任的網路上這麼做。
</Warning>

agent 定義屬於**受信任的輸入**，與設定檔和函式檔案一樣。agent 的安全性取決於你交給它的函式與 MCP 伺服器：決定何時呼叫它們的是模型，因此請只給 agent 完成工作所需的最小工具清單。

已繫結的伺服器無法為自己簽發 workspace token — 連向 `buttress/` 模型的 loopback 改以內部 token 授權，絕不使用 workspace 憑證。

## 範例

伺服器套件內附 `config/function-samples/run-agent.ts`，這是一個驅動已設定 agent 並回傳其結論、session id、輪數與停止原因的本地函式。`config/sample.toml` 中也帶有一段註解掉的 `[[agents]]` 區塊。其餘範例請參閱[本地函式](/zh-Hant/buttress/functions#範例)。

## 後續步驟

<CardGroup cols={2}>
  <Card title="本地函式" icon="code" href="/zh-Hant/buttress/functions">
    撰寫 agent 要當作工具使用的函式。
  </Card>

  <Card title="設定" icon="gear" href="/zh-Hant/buttress/configuration">
    完整的 TOML 參考，包含 agent 執行所依賴的 generator。
  </Card>
</CardGroup>
