Strands 引擎
Libre WebUI 内置了一个智能体引擎,它基于开源的 Strands Agents harness(@strands-agents/harness 0.1.1,运行在 @strands-agents/sdk 1.19.0 之上)。引擎在 Libre WebUI 后端进程内运行,因此无需另外安装守护进程。SDK 在首次使用引擎时才会加载;关闭了 Strands 的服务器从不加载它。
引擎驱动的是 Libre WebUI 已经提供的模型:
- 启用 Ollama 时的 Ollama 模型
- 已启用的聊天或补全提供商插件中的模型
每次模型调用都经过对话所用的同一套 Ollama 和插件服务。没有单独的提供商配置,也没有单独的 API 密钥。提供商凭据和 Ollama 开关照常适用,不受影响。
可以在三个地方使用该引擎:
- Strands 页面,用于持久的智能体会话
- 对话,通过模型选择器中的 Strands 条目
- Work,作为输入区 引擎 控件中的 Strands 选项
访问权限
管理员在设置 → 用户管理 → 访问与策略 → Strands 引擎中选择谁可以使用该引擎:
| 模式 | 设置中的标签 | 谁可以使用 Strands |
|---|---|---|
disabled | 关 | 任何人都不能,包括管理员(默认) |
admins | 管理员 | 活跃的管理员 |
all-users | 所有用户 | 所有活跃账户 |
更改会在下一个请求时生效,无需重启。
要在部署层面固定模式,请设置 LIBRE_STRANDS_ACCESS:
LIBRE_STRANDS_ACCESS=admins # or disabled, all-users
固定模式后,用户管理中的该控件会被锁定。除 disabled、admins 或 all-users 以外的任何值都会将引擎锁定为关闭,而不会回退到已保存的设置。
服务器会对每个 REST 请求、WebSocket 对话以及 Work 运行中的每次模型调用强制执行该模式。如果无法读取模式,则拒绝访问。没有访问权限的账户看不到 Strands 页面、Strands 对话条目或 Strands Work 引擎,API 会返回 403。
Strands 页面
从侧边栏打开 Strands(/strands)。
- 会话在重启后仍会保留,每个账户最多 200 个。新会话以第一条消息命名。
- 可以为每个会话选择模型。默认模型使用你的默认聊天模型。
- 回复在生成过程中以流式显示,包括模型的推理过程,每次工具调用也会显示一张卡片。
- 停止会取消正在运行的轮次。一个会话一次只运行一个轮次。
- 删除会话会同时删除其历史记录和工作区。
对话
在模型选择器中选择 Strands。它位于 智能体 组中,与 Agent CLI 模型并列:
- Strands(
strands)使用引擎默认值,也就是你的默认聊天模型。 - Strands · 模型(提供商)(
strands:<route>)为该对话固定一个模型及其提供商。
对话中的 Strands 只取决于 Strands 访问权限。它不需要 CLI代理模型开关,即使该开关处于关闭状态也会显示。在对话中,智能体拥有与 Strands 页面相同的文件工具,每个账户使用一个私有工作区,回复以文本和推理内容的形式返回。关于智能体组,以及如何将 Strands 条目用作生成标题和思考摘要的任务模型,请参阅已安装的编程 Agent。
Work
在 Work 输入区的 引擎 控件中选择 Libre WebUI 或 Strands,并单独选择模型。选择 Strands 时,由 Strands 智能体规划每一步,Work 则在 Work 沙箱中按照 Work 的常规审批策略执行它请求的工具。对话记录、审批、工具执行和运行历史始终以 Work 为准;在 Work 中,Strands 智能体不会自行运行任何工具。
底层的提供商模型必须支持工具调用。Work 会在运行开始前检查这一点,并拒绝未声明支持工具的模型。
早期版本保存的、带有 dsh: 模型前缀的 Work 运行会作为 Strands 运行打开。关于引擎选择与从对话沿用过来的模型之间如何配合,请参阅 Work:Strands 引擎。
安全模型
在 Strands 页面和对话中,智能体只有一组刻意精简的工具:
read、write和edit,用于处理其工作区中的文件- harness 的
todos插件,用于规划多步骤工作
它没有 shell、没有网页抓取、没有记忆,也没有技能,其指令中也不会注入任何 AGENTS.md 文件。
每个会话都有一个私有工作区目录,智能体看到的路径是 /workspace。每个路径都会在跟随符号链接之后再解析,并且必须位于该目录内,因此工作区中的链接无法访问磁盘的其他位置。沙箱拒绝执行命令。
| 项目 | 限制 |
|---|---|
| 每个账户的会话数 | 200 |
| 提示词长度 | 32,000 个字符 |
| 每条消息的智能体轮次 | 24 |
| 文件读取或写入 | 每次调用 2 MB |
| 会话标题 | 120 个字符 |
一轮对话达到轮次上限时会停止,并给出提示。每一轮都可能向你的提供商发起多次模型调用,因此授予访问权限时,请像对待其他会消耗提供商预算的模型访问一样谨慎。
存储
Strands 数据存放在 <DATA_DIR>/strands/ 下,而不是应用数据库中。每个账户都有自己的目录 <DATA_DIR>/strands/users/<account-hash>/,其中包含:
registry.json:该账户的会话列表sessions/:智能体用作上下文的 Strands 会话快照transcripts/:Strands 页面上为每个会话显示的对话记录workspaces/:每个会话的私有工作区chat-workspace/:对话轮次使用的工作区
如果这些会话对你很重要,请将 <DATA_DIR>/strands/ 纳入备份。
用量
提供商使用情况页面(/usage)会在其 智能体 部分中将 Strands 调用计入 Strands 智能体。请参阅智能体用量。
API
除 /api/strands/access 需要管理员权限外,每个路由都要求使用具有 Strands 访问权限的已认证账户。
| 方法 | 路径 | 用途 |
|---|---|---|
GET | /api/strands/access | 读取访问模式,以及 LIBRE_STRANDS_ACCESS 是否固定了该模式(管理员) |
PUT | /api/strands/access | 将 mode 设为 disabled、admins 或 all-users(管理员;已固定时返回 409) |
GET | /api/strands/health | 引擎可用性,以及 harness 和 SDK 的版本 |
GET | /api/strands/models | 引擎可为该账户驱动的模型 |
GET | /api/strands/sessions | 列出会话 |
POST | /api/strands/sessions | 创建会话(可选 title 和 model) |
GET | /api/strands/sessions/:sessionId | 读取会话、其对话记录,以及是否有轮次正在运行 |
PATCH | /api/strands/sessions/:sessionId | 更改会话的标题或模型 |
DELETE | /api/strands/sessions/:sessionId | 删除会话及其对话记录和工作区 |
POST | /api/strands/sessions/:sessionId/messages | 发送 { "text": "..." },并以 NDJSON 流式返回该轮次 |
POST | /api/strands/sessions/:sessionId/cancel | 停止正在运行的轮次 |
消息流每行写入一个 JSON 事件:turn-start、text、reasoning、tool-start、tool-result、done(提供商报告时附带停止原因和令牌用量)以及 error。关闭连接会取消该轮次。在某个轮次运行期间发送消息会返回 409。
配置
| 变量 | 默认值 | 用途 |
|---|---|---|
LIBRE_STRANDS_ACCESS | 未设置(使用管理员设置,admins) | 固定为 disabled、admins 或 all-users;其他任何值都会将引擎锁定为关闭 |
故障排除
请参阅 Strands 引擎问题。