Project Reading · withastro/flue

Flue 技术解读:把大模型装进 Agent Harness

Flue 不是一个聊天 App,也不是 Astro 的页面框架插件。它是一个用 TypeScript 构建 AI Agent 的底层框架,核心目标是把模型、工具、技能、文件系统、沙箱、持久化会话和部署入口装配成一个可运行的 agent。

写作日期:2026-06-21 主题:AI Agent Framework 关键词:Harness、Tools、Sandbox、Durable Execution
抽象的 Agent Harness 架构头图:中心运行时连接模型、工具、沙箱、数据库和部署目标
图 1:Flue 的核心隐喻是一个 agent harness。模型负责推理,harness 负责把推理变成可执行的工作。

一、Flue 到底是做什么的?

如果只用一句话概括:Flue 是一个 TypeScript Agent Harness 框架,用来构建可部署、可恢复、能调用工具和进入工作区执行任务的 AI Agent。 它把开发者平时零散拼起来的 LLM 调用、工具函数、上下文、沙箱、会话存储、HTTP 路由和部署目标,收进一个统一的工程模型里。

这和普通的“调一次模型拿一次回答”不一样。Flue 更关注的是让模型在一个持续上下文里工作:它可以先读文件,再调用工具,再根据结果继续行动,必要时把一部分任务交给子 agent,最后把结果返回给你的应用。

定位 Headless agent framework

它本身没有聊天界面。你用它写 agent,再把 agent 接进自己的网站、Webhook、后台任务或 CI。

语言 TypeScript first

Agent、工具、workflow、路由和部署配置都以 TypeScript 为主,适合直接嵌入 Web 应用和服务端工程。

架构 LLM + Harness

模型只负责生成和推理;harness 提供记忆、工具、文件系统、命令执行、沙箱和恢复机制。

Flue Harness session · loop · routing · runtime LLM reasoning and generation Tools typed application actions Skills reusable procedures Sandbox files and commands Persistence history, queue, events Targets Node.js, Cloudflare, CI
图 2:Flue 的价值不在于“又包了一层 LLM API”,而在于把 agent 运行所需的几类上下文和能力组合成一个可编程 harness。

二、用户如何使用 Flue?

Flue 的“用户”需要分成两类:开发者和最终用户。开发者直接使用 Flue 写 agent;最终用户通常并不知道 Flue 的存在,而是通过产品里的聊天框、按钮、Webhook、队列任务或 CI 流程间接触发 agent。

开发者的最小使用路径

官方快速开始给出的路径非常直接:安装 runtime 和 CLI,初始化目标环境,写一个 agent 文件,然后在本地连接它。

npm install @flue/runtime
npm install --save-dev @flue/cli
npx flue init --target node

# 然后创建一个 agent,例如 agents/hello-world.ts
npx flue connect hello-world local
1. install runtime + CLI 2. init node or cloudflare 3. createAgent model + instructions 4. add powers tools, skills, sandbox 5. connect HTTP, workflow, CI
图 3:Flue 的开发入口是代码,不是配置面板。你定义 agent,然后从自己的应用里驱动它。

一个最小 agent 长什么样?

最小版本只需要模型和指令。文件名会成为 agent 名称,运行时会发现并加载它。

import { createAgent } from '@flue/runtime';

export default createAgent(() => ({
  model: 'anthropic/claude-sonnet-4-6',
  instructions: 'Tell a funny "hello world" engineering joke.',
}));

稍微像生产系统一点的 agent

真实项目通常会加上工具、技能、工作目录和沙箱。下面这个伪例子表达的是 Flue 的工程思路:让 agent 在一个受控环境里完成“代码仓库审查”。

import { createAgent } from '@flue/runtime';
import { local } from '@flue/runtime/node';
import reviewChecklist from '../skills/review-checklist/SKILL.md' with { type: 'skill' };
import { repositoryTools } from '../shared/repository-tools.ts';

export default createAgent(() => ({
  model: 'anthropic/claude-sonnet-4-6',
  instructions: 'Review the change and report findings supported by evidence.',
  cwd: '/srv/repositories/catalog-service',
  tools: repositoryTools,
  skills: [reviewChecklist],
  sandbox: local(),
}));
最终用户如何触达? 最终用户通常不会执行 npx flue connect。更常见的方式是:客服系统把 ticket id 映射成 agent id,GitHub webhook 把 issue 评论 dispatch 给 agent,后台 job 启动 workflow,或者你的 Web UI 把用户消息 POST 到 /agents/<name>/<id>

三、它的原理:Agent = LLM + Harness

Flue 官方文档给出的核心心智模型是:agent 不是“一个聪明 prompt”,而是运行在 harness 里的大语言模型。模型单独存在时,只能接收上下文并生成文本;harness 则给它工作环境、可调用能力和恢复机制。

Model 负责判断下一步

模型读取当前上下文,决定回答、调用工具、读写文件、运行命令或委派子 agent。

Tools 执行应用动作

工具是带 schema 的函数,例如查订单、建工单、读取业务数据。参数会校验,真正权限由应用控制。

Skills 加载专业流程

技能提供可复用说明和步骤,例如审查清单、调试流程、领域知识,不等同于执行代码。

Sandbox 限制工作空间

沙箱决定 agent 能看到哪些文件、能不能执行命令、是否直接访问宿主机或远程隔离环境。

Persistence 保存会话状态

继续型 agent 需要会话历史、输入队列和事件流。中断后能否恢复,取决于目标环境和数据库适配器。

Targets 部署到运行环境

Flue 支持 Node.js、Cloudflare 等目标。应用负责认证、授权、触发入口和外部副作用治理。

输入 HTTP / webhook 会话上下文 instructions history skills 模型决策 answer or act 调用工具 业务函数 进入沙箱 文件和命令 输出 answer / events 每一次工具结果、文件观察和模型输出都会回到上下文,形成下一轮决策的材料。
图 4:一次 agent 运行不是单次请求,而是“观察、决策、行动、再观察”的循环。Flue 的 runtime 负责维护这个循环和边界。

工具为什么不是“随便给模型一个 API key”?

Flue 的工具通过 defineTool(...) 定义,包含名称、描述、参数 schema 和 execute 函数。模型只能选择参数;真正使用哪个用户、哪个仓库、哪个 ticket、哪组凭据,应该由你的应用在工具闭包或 agent id 里绑定。

import { defineTool } from '@flue/runtime';
import * as v from 'valibot';

export const lookupOrderStatus = defineTool({
  name: 'lookup_order_status',
  description: 'Look up the current fulfillment status for one order ID.',
  parameters: v.object({
    orderId: v.string(),
  }),
  execute: async ({ orderId }) => {
    return await orders.getStatus(orderId);
  },
});
权限边界不要交给模型。 模型可以决定“查哪个订单号”,但不应该决定“以哪个客户身份查询”。客户、仓库、ticket、token 和租户边界应由应用代码固定,再把一个受限工具交给 agent。

沙箱承担什么职责?

沙箱类型 适合场景 关键边界
Virtual sandbox 默认轻量工作区,适合应用主动提供输入文件、让 agent 处理后取回输出。 内存型工作区,不等同于完整 Linux 环境,也不是持久文件系统。
Local sandbox 可信开发工具、一次性 CI runner、需要直接操作宿主 checkout 的任务。 不是隔离边界。模型驱动的文件和命令访问会触达宿主机。
Remote sandbox 不可信请求、多租户任务、需要独立生命周期和 Linux 工具链的编码任务。 工作区、凭据、网络、生命周期仍需应用或平台策略管理。

持久化执行解决什么问题?

Agent 一旦能调用外部工具,就会遇到“执行到一半服务重启”的问题。简单重放可能导致重复发消息、重复建工单或重复付款。Flue 的 durable agent 思路是把 session history、输入队列和事件记录下来,在恢复时尽量保守地判断:能确认没执行过才重试,已经完成的结果要保留,结果不确定的外部动作不能盲目再跑一遍。

Cloudflare 目标会利用 Durable Object 和 SQLite 提供更强的默认恢复能力;Node.js 目标默认以内存为主,如果要跨重启保存状态,需要配置数据库适配器。这个设计很重要,因为它把“会话可恢复”和“文件工作区可恢复”拆成了两个不同问题。

四、什么时候适合用 Flue?

Flue 适合那些“模型不能只回答,还要持续行动”的场景。换句话说,如果你的需求需要上下文、工具、文件、命令、恢复和部署入口一起工作,Flue 的抽象就开始有价值。

场景 是否适合 原因
客服 ticket 助手 适合 每个 ticket 可以映射为一个 agent id,工具按 ticket 范围授权,会话能持续跟进。
GitHub issue triage 适合 需要读仓库、运行命令、调用 GitHub API、记录过程,并处理异步 webhook。
一次性文本摘要 不一定需要 如果只是单次模型调用,普通 SDK 或轻量 workflow 足够。
多租户自动编码平台 谨慎适合 需要 remote sandbox、严格授权、配额、审计、幂等和资源生命周期管理。
公司内部 agent 平台 适合 Flue 的 headless API 可以接入内部系统,把不同 agent 变成统一运行模型。

工程实践建议

从权限开始 先设计 agent id 和授权边界

不要先写万能工具。先决定一个 agent 实例代表哪个用户、ticket、仓库或租户。

工具要窄 给模型动作,不给模型钥匙

让工具执行明确动作,例如“查询当前 ticket 的订单”,而不是暴露任意数据库查询。

沙箱分级 可信任务和不可信任务分开

本地沙箱适合可信工作流;多租户和外部输入应优先考虑远程隔离环境。

外部副作用 为工具调用设计幂等

凡是会发消息、创建记录、扣款或修改状态的工具,都应该有应用侧幂等键和审计记录。

  • createAgent
  • defineTool
  • skills
  • subagents
  • virtual sandbox
  • local()
  • dispatch()
  • durable session
  • Node.js target
  • Cloudflare target

五、和“普通 LLM 应用”的差异

普通 LLM 应用往往是“用户输入 → 模型输出”。Flue 的重点则是“应用输入 → agent 进入上下文 → 根据环境行动 → 把过程和结果沉淀回来”。这个差异会影响你如何设计系统。

维度 普通 LLM 调用 Flue 式 Agent
控制方式 开发者硬编码步骤,模型主要负责生成。 开发者定义边界和能力,模型在循环里决定路径。
上下文 通常由一次请求携带,结束后丢失或手动保存。 agent instance 有持续会话,可以被后续输入重新打开。
行动能力 少量函数调用,通常围绕单个请求。 工具、文件、命令、技能和子 agent 一起构成工作环境。
失败恢复 由应用自己处理,容易出现重复副作用。 框架提供 durable agent 机制,但应用仍需处理外部幂等。

六、参考资料

本文基于官方仓库和文档梳理,并结合 agent harness 工程实践做了解读。

  1. withastro/flue GitHub 仓库
  2. Flue Getting Started
  3. What is an agent?
  4. Agents guide
  5. Tools guide
  6. Sandboxes guide
  7. Durable Agents

一句话结论

Flue 的真正价值不是“帮你更方便地调模型”,而是把模型放进一个有工具、有边界、有状态、有恢复能力的运行环境里。对开发者来说,你写的不是一步步脚本,而是一个 agent 能安全工作的舞台。