Skip to content

Chapter 1 · Flue Overview and the Harness Philosophy ​

Chapter goals: Understand the architectural evolution from "raw LLM API calls" to "autonomous Agents", clarify what Harness actually is, and build a panoramic view of Flue's core capabilities.

1.1 Three Generations of Evolution: From Raw API to Autonomous Agent ​

Generation 1: Raw LLM API calls. You send a prompt to the model and get back a block of text. It can write poetry, translate, but every step requires human driving — it doesn't query databases itself, doesn't retry on failure, and has no memory.

typescript
// Generation 1: one request, one response; the model can only "speak", not "act"
const response = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Check what issue #42 is about' }],
  }),
});
// The model can only reply "I can't access your GitHub" — it has no action capability

Generation 2: Scripted workflows. You hard-code steps in your code: call the summarization API first, then the classification API, finally write to the database. Reliable but rigid — any unplanned input breaks the flow.

Generation 3: Autonomous Agents. Products like Claude Code and Codex proved one thing: give the model a goal rather than a sequence of steps, let it自主 decide which tools to call, iterate until done — it can complete tasks far beyond what scripts can handle.

1.2 Harness: The "Tack" That Lets a Model Actually Work ​

A fine horse without tack can't pull a cart; a powerful model without Harness can't do work either. Harness is the runtime infrastructure surrounding the LLM:

ComponentPurpose
SessionGives conversations persistent state, remembering context across turns
ToolsLets the model call your application code and affect external systems
SkillsOn-demand loaded domain knowledge, teaching it "how to do a certain class of things"
SandboxSafe file and command execution environment
Loop controlHandles the tool-call → result feedback → continue reasoning cycle

In one sentence

The LLM is the engine; Harness is the whole car — steering wheel, accelerator, brakes, dashboard. Flue's job is to standardize the process of building that car.

1.3 What Is Flue ​

Flue is an open-source Agent Harness framework built by the Astro team. Its core insight is: write Agents using a React mental model — an Agent is just a function, capabilities composed via Hooks:

typescript
// A complete Flue Agent looks like this — doesn't it resemble a React component?
'use agent';
import { useModel, useSandbox, useSkill, useTool } from '@flue/runtime';
import { local } from '@flue/runtime/node';
import triage from '../skills/triage/SKILL.md';
import verify from '../skills/verify/SKILL.md';
import { openIssue, searchCode } from '../tools/github.ts';

// Agent is a function: the function body declares capabilities, the return value is the task directive
export function Triage() {
  useModel('anthropic/claude-sonnet-4-6'); // Pick a model
  useSandbox(local());                     // Give it a local sandbox
  useSkill(triage);                        // Mount triage skill
  useSkill(verify);                        // Mount verification skill
  useTool(openIssue);                      // Mount GitHub tool
  useTool(searchCode);

  // Return value becomes the agent's system instructions
  return `
Triage a bug report: reproduce the issue, locate the root cause,
judge whether the behavior is expected, and attempt a fix.`;
}

1.4 Core Capabilities Overview ​

CapabilityDescriptionCorresponding Hook / Package
AgentsAutonomous agents completing goals, maintaining context across conversations'use agent' function
Models接入任意 Pi-supported Provider (Anthropic/OpenAI/DeepSeek etc.)useModel()
ToolsType-safe application code callsdefineTool() + useTool()
SkillsReusable skill packs in the open Agent Skills formatuseSkill()
SubagentsExpert sub-agent delegationuseSubagent()
SandboxesLocal / remote container execution environmentsuseSandbox()
DurabilityRestore task progress after crashes and restartsBuilt-in persistence
ChannelsEvent接入 for Slack/Teams/Discord/GitHub etc.src/channels/
MCPConnect to the open MCP tool ecosystemuseMcpConnection()
ObservabilityTelemetry export via OpenTelemetry/Sentry etc.@flue/opentelemetry

Deployment is equally flexible: Node.js, Cloudflare Workers, GitHub Actions, GitLab CI/CD, Render are all first-class citizens.

1.5 Tech Stack and Package Structure ​

Flue is built on top of Pi (Earendil Works' agent runtime), reusing all its Provider support. Core packages have clear division of labor:

text
@flue/runtime        # Core: harness, sessions, tools, sandbox
@flue/vite           # Vite plugin: vite dev / vite build
@flue/cli            # flue CLI: local run, project initialization
@flue/sdk            # Client SDK: consume deployed agent conversations
@flue/opentelemetry  # OpenTelemetry tracing adapter
@flue/postgres       # Postgres persistence adapter
typescript
// Typical dev dependency installation
// npm install @flue/runtime @flue/cli
// Add for deployment:
// npm install @flue/vite hono vite

// flue.config.ts —— project-level config; target determines the build output
import { defineConfig } from '@flue/runtime/config';

export default defineConfig({
  target: 'node', // or 'cloudflare'
});
typescript
// Minimal server entry for deployment (covered in detail in Chapter 2)
// src/app.ts —— mount the Triage agent onto an HTTP route
import { createAgentRouter } from '@flue/runtime/routing';
import { Hono } from 'hono';
import { Triage } from './agents/triage.ts';

const app = new Hono();
app.route('/agents/triage', createAgentRouter(Triage));
export default app;

Version requirement

Flue requires Node.js ≥ 22.19.0. Check with node --version before starting.

1.6 Chapter Summary ​

  • Three stages of Agent evolution: raw API → scripted workflow → autonomous Agent;
  • Harness is the runtime infrastructure around the LLM: sessions, tools, skills, sandboxes;
  • Flue writes Agents with a React-style mental model: function = Agent, Hook = capability;
  • Core package is @flue/runtime; build via Vite; deployment supports Node and Cloudflare.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What is the biggest limitation of raw LLM API calls?

2. In Flue, what does the Agent function's return value represent?

3. Which is Flue's core runtime package?

4. Which of the following is NOT within Harness's responsibility?

🛠️ Hands-On Exercises ​

  1. Explain to a colleague in your own words "why Harness cannot be omitted": if you were given only a raw API and asked to have the model统计 your repo's star count, which capability blocks would be missing?
  2. Browse the packages directory at https://github.com/withastro/flue and list each of the six core packages in one sentence. 3.对照 the capabilities table in 1.4, think about which repetitive task at work is best suited for an autonomous Agent; write down its goal and the tool list it would need.

Concepts clear? Next, set up the project and run your first Agent.