几种色相,
无数种 Agent。

Hue 是一个开源的 agent harness。在终端里直接用,也能一层层拼进你自己的产品。

$ pnpm add -g @hue/cli

在终端里,
它就是你的 agent。

读代码、跑测试、改文件。每一步都看得见,每一步都能接着来。

hue — ~/acme-api
Hue CLI v0.0.0
~/acme-api
模型claude-sonnet-5-5 · 1M
沙箱local · 当前目录
策略coding · 写入和命令先确认
上下文3 个技能 · 记忆已开启
会话新会话 · hue.db
能做什么
@ 引用文件 ! 直接跑命令
task 派子 agent 并行查
/model 换模型 /resume 接着上次
注意
--yes 会跳过所有确认
上下文快满时会自动压缩
❭ 登录接口偶尔返回 401,帮我查一下 ● grep("expiresAt", src/) ⎿ 4 matches ● read(src/auth/session.ts) ⎿ 84 lines ● bash(npm test -- auth) ⎿ 1 failed · session.test.ts ● expiresAt 存的是秒,比较时被当成了毫秒,token 一签出来就判定过期。 ● edit(src/auth/session.ts) 41 - if (Date.now() > token.expiresAt) {41 + if (Date.now() > token.expiresAt * 1000) {● task(找出 src/ 里其他把 expiresAt 当毫秒比较的地方) ⎿ 子 agent · 独立上下文 · 4 步 · ↑9.8k ↓0.7k ├ grep("expiresAt") ├ read(src/jobs/cleanup.ts) ├ read(src/billing/invoice.ts) └ src/jobs/cleanup.ts:27 也是同样的问题,invoice.ts 没事 ● edit(src/jobs/cleanup.ts) 27 - if (s.expiresAt < Date.now()) expired.push(s)27 + if (s.expiresAt * 1000 < Date.now()) expired.push(s)● bash(npm test) ⎿ all passed ● 修好了。两处比较都把秒换算成毫秒,测试全部通过。
❭
↑38k ↓4.2k R112k W9.6k 4.3%/1Mclaude-sonnet-5-5
hue打开交互界面
hue "看看这个仓库"带着任务打开
hue -p "修好失败的测试"跑完就退出
hue -p --json "…"每个事件一行 JSON
hue -c接着上一次
hue --model <name>换一个模型
hue --sandbox docker在容器里跑

斜杠命令

/model/resume/session/name/copy/export/new/hotkeys/quit!cmd
展开工具输出Ctrl O
显示思考Ctrl T
打断Esc
引用文件@

一个 harness 该有的,
都在。

工具

读、写、搜索、执行命令。任意 MCP server 接上就能用。

会话

每一步都写进事件日志。中断了、进程挂了,接着跑。

沙箱

在本机目录上跑,或者在 Docker 里的仓库副本上跑。

权限

每次工具调用都过一遍规则:放行、拒绝,或者先问你。

上下文

对话变长时自动压缩,长任务不断片。

Skills 与记忆

SKILL.md 按需加载,笔记跨会话留着。

子 agent

把一块活儿交给子 agent,结果再回到主线。

Gateway

HTTP 和 SSE 接入,签名 webhook 连到聊天软件。

观测与评测

事件导出成 OpenTelemetry,同一份事件拿来跑 eval。

每一层,都能换。

十三个小包,只靠带版本号的事件相连。换模型、换存储、换沙箱,其余不动。

01@hue/core

类型、事件和循环

ModelPort · Tool · SandboxPort …
02@hue/ai

模型适配

model('anthropic:claude-sonnet-5-5')
03@hue/tools

工具

tools: codingTools()
04@hue/store

事件日志

store: sqliteStore('hue.db')
05@hue/context

上下文压缩

context: foldToolResults()
06@hue/skills

按需加载 SKILL.md

skills: fromDir('./skills')
07@hue/memory

跨会话笔记

memory: file('./notes')
08@hue/policy

放行、拒绝或先问

policy: presets.coding()
09@hue/sandbox

在哪里执行

sandbox: await local({ root: '.' })
10@hue/runtime

把各层装成 agent

createAgent({ model, tools, store, … })
11@hue/gateway

HTTP、SSE 和 webhook

createGateway({ agent })
12@hue/telemetry

导出 OpenTelemetry

otlpHttp({ url })
13@hue/eval

跑任务、打分

codingTasks()

也能写进
你的代码。

挑几层,拼一份配方。hue 命令本身就是这样拼出来的。

import { createAgent } from '@hue/runtime' import { model } from '@hue/ai' import { codingTools } from '@hue/tools' import { sqliteStore } from '@hue/store' import { local } from '@hue/sandbox' import { presets } from '@hue/policy' const agent = createAgent({ model: model('anthropic:claude-sonnet-5-5'), tools: codingTools(), store: sqliteStore('hue.db'), sandbox: await local({ root: '.' }), policy: presets.coding(), }) for await (const e of agent.run('修好失败的测试')) render(e)

调一个你自己的 agent。

$ git clone https://github.com/hifizz/hue $ cd hue/hue && npm install $ npm install -g ./packages/cli $ export ANTHROPIC_API_KEY=sk-... $ hue