One sentence, and it starts observing, acting, responding.
Ninety percent of productive work happens in the browser; give agents that interface and they can take on real work
What stands between a person and the digital world?
In the command-line era, it was a set of instructions you had to memorize. In the GUI era, it was windows, buttons, and a mouse. Then the web won everything: roughly ninety percent of productivity scenarios end up inside a browser tab. Booking, expensing, reporting, publishing, price-checking — the entire operational surface of the digital world grew onto web pages.
Now it's the agent's turn to answer that question.
Models are already smart enough. They can write, calculate, reason. But the world is beyond the screen: pages change, prices move, things happen. For an agent to genuinely take over human productivity, what it needs isn't smarter conversation. It's the interface humans have used for thirty years: a browser.
The industry has produced plenty of demos of agents observing, acting, and responding to the real world. The hard part is getting from "the demo runs" to "usable every day."
Web Agent is Qoni's action layer, built for that second thing.
One sentence to delegate, and it watches pages and runs flows for you
Give it one sentence, and the agent opens a browser of its own in the cloud:
- Observe. It watches pages for you: a price drops, stock comes back, terms change — anything moves, you hear about it. No crawlers to write, no cron jobs to configure, no 3 a.m. babysitting.
- Act. It searches, compares, fills forms, and reconciles information from dozens of pages into one conclusion. From intent to result, everything in between is its job.
Everything is recorded; every step can be replayed. What it did and why it did it is always available for review.
One API, instead of a browser-engineering stack of your own
There's no shortage of browser-use style automation options — open source and paid alike. But getting a "library that can drive a browser" is only the starting point: as an agent developer, you still end up building and maintaining a complex browser-engineering stack around it. Headless browser clusters to maintain, proxies and login state to babysit, concurrency scheduling, crash recovery, and observation capture to assemble yourself; and scripts that shatter every time a page gets redesigned. The library answers "can it click"; the engineering has to answer "usable every day."
Web Agent hosts the entire execution loop in the cloud — open the page, observe, decide, act, retry on failure. To you, it's one API: your agent states what it wants, and the rest happens in the cloud.
The capabilities are cleanly separated, all exposed as APIs:
- General web operations: log in, fill forms, compare prices, run complete multi-step flows;
- Search and deep research: parallel retrieval across engines, deduplication by normalized URL, cross-checking — producing a conclusion document with a citation list and confidence annotations, not a page of links;
- Track, the standing watch: set a goal and a frequency, and it proactively notifies you when the page changes;
- Login state reuse: sign in once, and later tasks carry on. One login state is one complete browser identity (deliberately not split per site — single sign-on would trap you otherwise), and when it expires, there's a queryable status.
Track and deep research each get a full section below: nothing exposes the gap between "demo" and "production" quite like they do.
Running for hours without falling over takes a four-layer harness, not a wrapper
Wiring a model to a browser takes an afternoon. Running for hours without falling over is the actual engineering. Long-horizon tasks rarely die because the agent "couldn't click the button" — they die of three much duller things: context management, failure recovery, and state persistence.
So the shape of Web Agent isn't "a wrapper around a model." It's a four-layer execution system:
- Orchestration: prompt and context assembly, task memory management, the planning loop, behavioral guardrails. On long tasks, models get lost: context fills with irrelevant material and they forget which step they're on. Orchestration exists so the model always knows where it is, what it has completed, and what remains;
- Browser: sandboxed cloud browsers, one dedicated instance per session. Login state, fingerprints, and caches never bleed between isolated sessions — reusable profiles are carried across sessions explicitly; instances stand by around the clock. A dedicated instance isn't a luxury — it's the baseline of isolation. Two tasks sharing one browser is two people sharing one logged-in computer;
- Scheduling: large-scale concurrent orchestration — queues, quotas, crash recovery — an instance dies, the task doesn't;
- Output: structured artifacts with citations, confidence, and a replayable execution trail. An artifact isn't "the model finished talking" — it's an object downstream programs can consume and humans can audit step by step.
Now for the specific disciplines, one at a time.
One action per step, re-observed after each, squeezes false success to a minimum
Each step performs exactly one action, and every action is followed by a fresh observation. The execution loop is broken into strict micro-steps: observe → decide → act, then back to observe. The agent never chains operations on a stale page snapshot; before executing, it re-verifies that the target element still exists.
This discipline targets the most insidious class of browser-automation accidents: the page changed between two actions. A dialog covered the button, a list re-sorted, an element is still in the DOM but no longer visible. An agent operating on old snapshots "looks successful while clicking somewhere else." The micro-step loop drives that entire class of false success toward zero, mechanically: every action faces a world it has just looked at.
Three observation tiers, escalated on demand: the cleaner the context, the faster the run
Not every step dumps the whole DOM into the model. Observation has three tiers, light to heavy:
- Tier one, the accessibility tree: the lightest observation tier, and the default. For most steps, knowing "which interactive elements are on the page" is enough;
- Tier two, targeted queries: fetch only the fragment this step needs. Verifying one price doesn't require a full-page snapshot;
- Tier three, the full page snapshot: the last resort, used only when the lighter tiers genuinely fall short.
Raw page data always lands in artifact storage; what enters the model context is only the observation this one step needs. This isn't just token frugality: the cleaner the context, the steadier the decisions; the lighter the observation, the faster the loop. Subtraction on what the browser feeds the model is where the speed comes from.
No evidence means failure: success must trace to the end state the user sees
"If there is no evidence it succeeded, it failed." This is the system's highest law.
Green lights from intermediate layers don't count — a status flag flipped, a script ran to completion, the model said "done." Success must be traced to the terminal state the user actually sees: the order confirmation page rendered, the report file landed in the workspace, that line on the page really changed to the expected value.
Regression testing follows the same law: real user tasks are replayed over and over, and the assertions target the final answer, not "the flow completed." A flow can return 200 at every step and still deliver a wrong result; conversely, a test that asserts the terminal state is immune to refactors of everything in between.
Proven paths harden into skills: faster, steadier, self-healing through redesigns
An operation path repeatedly validated on a site hardens into a deterministic action sequence: on a hit, it executes directly, skipping the model call. For high-frequency repetitive tasks this means faster, steadier, cheaper — deterministic code doesn't get creative on the thousandth run.
Skills are not static scripts. When a redesign makes selectors drift, regeneration and revalidation trigger automatically: the model re-scouts the path, validation confirms the new path works, and the new deterministic sequence replaces the old. This is the systemic answer to "scripts shatter everywhere": scripts still shatter, but they grow back on their own.
One boundary: each site's skills are validated independently — a skill is never generalized to another site just because the two look alike. Two e-commerce checkout flows can be identical except for the position of one button, and that button happens to be "confirm payment."
Submit, pay, delete must pass typed gates, never the model's conscience
Submitting forms, paying, deleting — these actions must pass typed gates: actions are explicitly classified, and high-risk categories trigger additional confirmation logic, rather than relying on a "please be careful" line in the prompt.
Recognizing login walls, error pages, and risk-control pages is a required structured output at every step — not the model's optional conscience. Required means the model cannot silently skip it: at every step, it must answer "is there a wall in front of me?"
On CAPTCHAs and identity checks, our position is: we don't do silent bypasses and we shouldn't — the correct move is to escalate to a human. That's an engineering judgment and a matter of boundaries: CAPTCHAs exist precisely to tell humans from programs, and a production system should not sell bypassing them as a feature.
A resource model preserves the environment across disposable tasks: login state and files keep accumulating
One-off demos don't need a resource model. Production tasks do. Web Agent breaks a long task into three explicit objects:
- The Session is the container: one dedicated browser, one login state, one working directory — the task's entire environment;
- The Run is one complete life of one instruction: from entering the queue to delivering an artifact, with explicit state throughout;
- The event stream is the single source of truth: reasoning, actions, input requests, artifacts — all pushed with sequence numbers, resuming from the exact break point after a disconnect. The stream feeds two mouths at once: live progress display, and after-the-fact step-through replay plus offline decision replay.
The environment carries two persistent assets: the workspace passes files across runs (the report one task downloads, the next task processes), and login profiles carry identity across sessions. Tasks are disposable; the environment accumulates.
Making "awaiting input" one of seven lifecycle states lets a run suspend in place and resume
A run's state machine is fully explicit: pending, running, awaiting input, paused, done, failed, canceled. How the seven states flow and who may trigger each transition is written into the protocol, not agreed on verbally.
The state worth dwelling on is awaiting input: it's first-class, not an anomaly. When a human is needed (login, QR scan, CAPTCHA), the task suspends in place and waits rather than failing and starting over. Suspension is not pause: only the moment a human actually takes the wheel is called pause. When the human finishes, the run resumes from the breakpoint with its accumulated context intact.
Done has a bar to clear, too: only success with evidence counts as done — in the SDK this terminal state surfaces as status: "succeeded" (distinct from the done event on the stream). A run that can't produce evidence of success terminates as failed, not as a vague success.
When a step needs a human, it hands you the browser, then resumes with the context intact
Some steps must be done by a person: logging in, scanning a QR code, solving a CAPTCHA.
Many approaches stall here. Web Agent's answer: it hands you the browser. You take over, finish that one step, and after handback it picks up from the breakpoint — nothing gets thrown away and restarted, and the context doesn't vanish.
There's a carefully designed detail here. When a takeover is initiated, the task does not pause; it merely issues a control link valid for a few minutes. Only when someone actually opens the link and takes the wheel does the task pause. If nobody comes, the link expires and the agent keeps working the problem itself. This design avoids an awkward deadlock: the agent calls for help, the human is in a meeting, and the task hangs forever.
The link can be forwarded straight to your end user — SMS or QR code both work — and only one person can hold control at a time. When the human hands back, the agent forcibly re-observes the page before continuing: it doesn't guess what happened during the takeover, it looks.
Others talk about what agents can do. We talk about how a human can take over at any moment, and hand back.
Letting go and staying in control should never have been a trade-off.
Track watches pages for you: deterministic rules decide what changed, not the model's phrasing
Track is simple to use: set a goal and a frequency, and get notified when the page changes. But "did it change" is precisely the judgment a model should never monopolize.
Model phrasing drifts: the same page is "a price cut" today and "a promotion launch" tomorrow. If the model's wording decides whether to alert, your watch system becomes a random number generator. So Track splits the work: the model only describes what it observed; "did it change, should we alert" is decided by deterministic rules. The model is also not allowed to claim "the alert was already sent" on its own: the verdict belongs to code, not to phrasing.
When the rules say changed, a webhook is delivered to the endpoint you configured, and your existing integrations carry it into the team channel; when they say no change, it returns to patrol.
Deep research can wait for your sign-off before large-scale gathering, before a wrong direction becomes an expensive run
Deep research is an explicit pipeline: brief → plan → outline → gather → cross-check → synthesize. Six explicit stages in sequence — not a black box that spins for ten minutes and emits an essay.
The outline stage can stop and wait for human sign-off: confirm the direction, then run. The placement of this pause is deliberate: it sits before large-scale gathering. When the research direction is wrong, diligence multiplies the waste; a minute spent aligning "what are we researching" is far cheaper than rerunning an hour later.
Gathering retrieves across engines in parallel and deduplicates by normalized URL; cross-checking verifies consistency across sources; the final output is a conclusion document with a citation list and confidence annotations, not a page of links.
Replay real tasks toward a clear target: P90 under two minutes, success rate toward 99%
Between "it runs" and "it delivers" lies engineering.
We set a bar for Web Agent. It is not an achievement already reached but a target we are grinding toward: P90 task completion latency within two minutes, and drive the success rate toward 99%.
The method isn't mysterious: take the real tasks users have handed us over the past few years and test against them relentlessly; locate and fix every scenario that underperforms, then replay to verify; round after round, until it's stable. Improvements that work are distilled into general capability, not one-off patches for a single case.
Ops without night watches, finance without manual exports: two workloads already running in production
First: social media automation and data collection. A real daily routine: an ops teammate tells the agent, "watch these three competitors' pricing and new-release pages, tell me when anything changes." Track takes over: patrol on schedule, let deterministic rules decide whether something changed, push a notification into the team channel when an alert is due. The same capability set runs multi-platform publishing, comment-section monitoring, and public data aggregation. One sentence to delegate, then it's the agent's problem — including the page redesign at 3 a.m.
Second: the systems inside enterprises that "can't be integrated." Not every company has a lakehouse and standardized APIs. Real enterprises are littered with nonstandard, hard-to-maintain legacy systems: no API, but there's a web page. A typical loop: a finance teammate exports a report from a legacy system's web UI every week. Web Agent takes over the flow — log in, navigate, export, drop the file into the workspace for the downstream task. Login expired? The task moves into the awaiting-input state, the control link goes to the teammate, and after re-login the task resumes from the breakpoint. Unattended operation doesn't come from "nothing ever goes wrong." It comes from having a viable path after something does.
A few lines to integrate: scope the delegation first, then answer "run finished" and "goal achieved" separately
Everything so far has been the machine's insides. Developers care about a different question: how many lines to plug in.
The SDK ships as @qoniai/qoni (Node 18+, ESM / CommonJS dual build, full TypeScript types), initialized with the AK / SK issued in Qoni Console. Step one of integration isn't sending a task — it's getting a delegation: issue a scoped delegation credential for the current user, and the agent acts only inside its boundary.
import { Qoni } from "@qoniai/qoni";
const qoni = new Qoni({ accessKey, secretKey });
// Authorization first: the products sugar expands each product into its read + manage scope pair
const { data } = await qoni.delegateToken({
user: { id: userId },
products: ["doAnything", "track"],
});
// One instruction, one run
const run = await qoni.doAnything.run({
token: data.token,
prompt: "Open the back office, export last week's reconciliation report, drop it into the workspace",
});
const result = await run.wait();
result.status; // succeeded / failed / canceled: the delivery status of this run
result.isTaskSuccessful; // whether the task's goal was actually achieved: a separate field, answered separately
The last two lines deserve a pause: delivery status and goal achievement are two fields. A run can end normally (succeeded) without achieving its goal; the protocol answers the two questions separately — this is what the "no evidence means failure" discipline looks like inside the SDK.
When a human is needed, the interaction isn't an exception — it's a typed event. All five interaction types (site_login / clarification / confirmation / take_control / wait) arrive on the event stream, wrapped in a handle with methods:
for await (const event of run.events()) {
if (event.type !== "interaction") continue;
const i = run.interactionHandle(event.data);
if (i.type === "clarification" && i.can("answer")) await i.answer("the blue button");
else if (i.can("confirm")) await i.confirm();
}
i.can() carries a deliberate design: whether each action is available is declared explicitly by the backend inside the interaction, and calling an undeclared method throws. In other words, the "recover" button only exists when recovery actually works — the SDK won't paint you a button that does nothing.
Standing watch follows the same shape: qoni.track.create() returns a monitor handle. A new monitor first enters intent alignment (pending_clarification), and once active you can runNow() for an immediate patrol, refine() the schedule and notification channel, and manage its lifecycle with pause() / resume() / delete(). After a disconnect, attach() by id returns you to the same monitor or run, resuming the event stream from the break point.
Don't take a vendor's word for it: verify every capability against real tasks
None of the above needs to be taken on a vendor's word — it lands as checkable items on an acceptance sheet:
- Replay real tasks as regressions; assert the final answer, not "the flow completed";
- Sever the event stream and reconnect; events backfill in sequence;
- Issue a control link and let nobody take it: the task keeps moving and the link expires;
- Have someone take over: only one controller at a time, and a forced re-observation after handback;
- Assign a task that cannot possibly produce evidence of success: the verdict must be failure, not vague success;
- Let a login state expire: the status is queryable, the task moves into the awaiting-input state, and resumes from the breakpoint after re-login;
- Track verdicts are reproducible: feed the same set of observations twice and the verdict is identical; when the verdict is changed, the webhook is delivered to the endpoint you configured;
- Trigger a submit / payment / delete action: it must pass a typed gate; hit a CAPTCHA: it escalates to a human instead of silently bypassing.
One quick-reference table to gather everything this piece covered:
| Capability | In one line |
|---|---|
| General web operations | Multi-step flows from one sentence: log in, fill forms, compare — executed via the micro-step loop |
| Deep research | Six-stage explicit pipeline; outputs a conclusion document with citations and confidence |
| Search | Parallel multi-engine retrieval, normalized-URL dedup, cross-checking |
| Track | Patrol on schedule; deterministic rules decide "changed or not"; webhooks to your endpoint |
| Login profiles | Sign in once, reuse across sessions; one profile is one full browser identity, expiry is queryable |
| Workspaces | Files carried across runs: one task's output, the next task's input |
| Take Control | Links valid for minutes; pause only on takeover; forced re-observation on handback |
| Event stream | Structured record of every step, sequence-numbered, resumable, replayable |
| Skills | Validated paths harden into deterministic sequences; never generalized across sites |
| Risk gates | Submit / pay / delete pass typed gates; CAPTCHAs escalate to humans |
| SDK | @qoniai/qoni; delegation first, five typed interactions, reattach across disconnects |
Next: prove it on public benchmarks, then run in your own browser
Two things — no dates promised, both under way:
- Prove ourselves on public industry benchmarks, and publish the real-task test set we've accumulated over the years;
- Let the agent run beyond the cloud: someday, on your own browser and your own computer.
End-state evidence and real-task replay turn "fast and right" from a slogan into an engineering target
Not another agent that demos well, but "fast and right" delivered as an engineering metric.
Web Agent is currently in private build and will open in stages with Qoni. You can join the waitlist on our website.
一句话,它开始观察、行动、回应。
九成生产力场景都在浏览器里,给 Agent 一个浏览器,它才接得住真实工作
每一代生产力工具,都在重新回答同一个问题:人和数字世界之间,隔着什么?
命令行时代,隔着一套需要背诵的指令;图形界面时代,隔着窗口、按钮和鼠标;到了 Web 时代,浏览器赢下了一切:差不多九成的生产力场景,最终都发生在一个浏览器标签页里。订票、报销、查数、发布、比价,整个数字世界的操作面,长在了网页上。
现在,轮到 Agent 来回答这个问题了。
模型已经足够聪明。它会写、会算、会推理。但世界在屏幕之外:页面在变,价格在变,事情在发生。要让 Agent 真正接管人的生产力,它需要的不是更聪明的对话,而是那个人类用了三十年的界面:一个浏览器。
让 Agent 去观察、行动、回应真实世界,行业里的演示大家看过很多。真正难的,是从"演示能跑"到"天天可用"。
Web Agent 是 Qoni 的行动层,为的就是后面这件事。
一句话下达任务,它替你盯页面、跑流程
一句话下达任务,Agent 在云端打开一个属于它自己的浏览器:
- 观察。 替你盯着页面:价格降了、库存回来了、条款改了,有动静就告诉你。不用写爬虫,不用配定时任务,凌晨三点也不用你惦记。
- 行动。 替你搜索、比价、填表,把几十个页面里的信息核对成一份结论。从意图到结果,中间的事它来。
全程录像,每一步都能回放。它做过什么、为什么这么做,随时可以复盘。
一个 API,你不再需要费尽心思搭建复杂的浏览器工程
市面上并不缺 browser-use 类的浏览器自动化方案,开源的、付费的都有。但拿到一个"能操作浏览器的库"只是起点:作为 Agent 开发者,你仍然要围绕浏览器构建和维护一整套复杂的 Browser Engineering。无头浏览器集群要养,代理和登录态要维护,并发调度、崩溃恢复、观测采集都得自己搭;页面一改版,脚本就碎一地。库解决的是"能不能点",工程要解决的是"天天可用"。
Web Agent 把整个执行循环(打开页面、观察、决策、操作、失败重试)托管在云端。对你来说,它就是一个 API:你的 Agent 说清楚要什么,剩下的事发生在云上。
能力各司其职,全部 API 化:
- 通用网页操作:登录、填表、比价,跑完整的多步流程;
- 搜索与深度研究:多引擎并行检索、按规范化 URL 去重、交叉核对,产出的是带引用清单和置信度标注的结论文档,而不是一页链接;
- Track 持续盯守:设定目标和频率,页面一有变化主动通知你;
- 登录态复用:登录一次,后续任务接着用。一份登录态是一份完整的浏览器身份(刻意不按站点拆分,否则单点登录会把你困死),失效有状态可查。
盯守和深度研究这两条,后文各有一节展开:它们身上最能看出"演示"和"生产"的分野。
跑几小时不翻车,靠的是模型外面的四层 Harness
把模型接上浏览器,一个下午就能跑通。跑几个小时不翻车,才是真正的工程。长程任务挂掉,很少死在"不会点按钮"上,而是死于三件更无聊的事:上下文管理、失败恢复、状态保持。
所以 Web Agent 的形状不是"模型外面包一层",而是四层各司其职的执行系统:
- 编排层:提示词与上下文的组织、任务记忆的管理、规划循环、行为护栏。长任务里模型最容易"迷路":上下文被无关信息挤满,忘了自己在哪一步。编排层的职责就是让模型每一步都知道"我在哪、做到哪、还差什么";
- 浏览器层:沙箱化的云端浏览器,每个会话独占实例。登录态、指纹、缓存在隔离的会话之间互不串扰,可复用的登录态档案则跨会话显式携带;7×24 待命。独占不是奢侈,是隔离的底线:两个任务共享一个浏览器,等于两个人共用一个已登录的电脑;
- 调度层:大规模并发的任务编排,排队、配额、崩溃回收,实例挂了任务不丢;
- 产物层:结构化输出,带引用、带置信度、带可回放的执行轨迹。产物不是"模型说完了",而是能被下游程序直接消费、能被人逐步复核的对象。
下面逐条看这些工程纪律。
每步一个动作、动作后重新观察,把假成功压到最低
每一步只做一个动作,动作之后必须重新观察。 执行循环被拆成严格的微步:观察 → 决策 → 行动,然后回到观察。Agent 永远不基于过期的页面快照连续操作;动作执行前还会再验证一次目标元素是否仍然存在。
这条纪律针对的是浏览器自动化里最阴险的一类事故:页面在两个动作之间变了。弹窗盖住了按钮、列表重新排序、元素还在 DOM 里但已经不可见。基于旧快照连续操作的 Agent,会"看起来成功了、其实点了别处"。微步循环从机制上把这一整类假成功压到最低:每个动作面对的都是刚刚看过一眼的世界。
三档观测按需升级:上下文越干净,跑得越快
不是每一步都把整页 DOM 塞给模型。观察分三档,从轻到重:
- 第一档,无障碍树:最轻量的观测档,也是默认档。大多数步骤,知道"页面上有哪些可交互元素"就够了;
- 第二档,定向查询:只取这一步需要的局部。要核对一个价格,不需要整页快照;
- 第三档,全量页面快照:兜底档,确实不够才升级。
原始页面数据一律落进档案存储,进模型上下文的,只有这一步刚好需要的观测。这不只是省 token 的抠门:上下文越干净,模型的决策越稳;观测越轻,循环越快。给 Agent 的浏览器做减法,才是速度的来源。
无证据即失败:成功必须追到用户看到的终态
"没有证据证明它成功,它就是失败。" 这是整个系统的最高铁律。
中间某一层的绿灯(任务状态翻转了、脚本跑完了、模型说"我做完了")都不算数,判定成功必须追到用户真正看到的终态:订单确认页出现了、报表文件落在了工作目录里、页面上那行字确实变成了预期的值。
回归测试同样如此:拿真实用户的任务反复回放,断言的是最终答案,不是"流程走完了"。一个流程可以每一步都返回 200,最后交出一个错误的结果;反过来,断言终态的测试,对中间路径的重构完全免疫。
跑通的路径沉淀成技能:更快、更稳,页面改版还能自愈
一条在某个站点反复验证过的操作路径,会固化成确定性的动作序列:命中即执行,跳过模型调用。对高频重复的任务,这意味着更快、更稳、更便宜:确定性代码不会在第一千次执行时突发奇想。
技能不是静态的脚本。页面改版导致选择器漂移时,自动触发重新生成、重新验证:模型负责重新探路,验证负责确认新路走得通,然后新的确定性序列替换旧的。这是"脚本碎一地"问题的系统性解法:脚本仍然会碎,但碎了会自己长回来。
还有一条边界:每个站点的技能独立验证,绝不因为两个网站长得像就把技能推广过去。 两个电商站的下单流程可以像到只差一个按钮的位置,而那个按钮恰好是"确认付款"。
提交、付款、删除必须过类型化关卡,不押注模型自觉
提交表单、付款、删除这类动作必须经过类型化的关卡(Gate):动作被显式分类,高风险类别触发额外的确认逻辑,而不是靠提示词里的一句"请谨慎操作"。
登录墙、错误页、风控页的识别是每一步必填的结构化输出,而不是模型"可选的良心"。必填意味着模型无法沉默地跳过:每一步它都必须回答"眼前是不是一堵墙"。
遇到验证码和身份核验,我们的立场是:不做也不该做静默绕过,正确的做法是升级给人。 这既是工程判断,也是边界感:验证码存在的意义就是区分人和程序,一个生产系统不应该以绕过它为能力卖点。
用资源模型养环境:任务是一次性的,登录态和文件可积累
跑一次性的演示不需要资源模型,跑生产任务需要。Web Agent 把长任务拆成三个显式的对象:
- 会话(Session)是容器:一个独占的浏览器、一份登录态、一个工作目录,装着任务的全部环境;
- 执行(Run)是一条指令的一次完整生命:从进入队列到给出产物,全程状态显式;
- 事件流是唯一事实源:推理、动作、请求输入、产物,全部按序编号推送,断线之后从断点续传。事件流同时喂两张嘴:实时的进度展示,和事后的逐步回放与离线决策重放。
环境还有两件持久资产:工作目录跨执行传递文件(上一个任务下载的报表,下一个任务接着处理);登录态档案跨会话复用身份。任务是一次性的,环境是可积累的。
把「等人输入」写进七态生命周期,任务能原地挂起、断点续跑
一次执行的状态机全部显式:排队中、运行中、等人输入、已暂停、完成、失败、已取消。 七个状态之间怎么流转、谁有权触发,写在协议里而不是约定在口头上。
其中最值得说的是"等人输入":它是一等状态,不是异常。需要人的时候(登录、扫码、验证码),任务原地挂起等待,而不是失败重来。挂起不是暂停:人真正接手方向盘那一刻,才叫暂停。人做完,从断点继续,前面积累的上下文一点不丢。
"完成"也有门槛:有证据的成功才叫完成,这个终态在 SDK 里以 status: "succeeded" 呈现(与事件流里的 done 事件是两回事)。给不出成功证据的执行,终态是失败,不是含糊的成功。
需要人时把浏览器交给你,做完交还、断点续跑,上下文不丢
总有些步骤,必须人来做:登录、扫码、验证码。
很多方案走到这类步骤,就停了下来。Web Agent 的做法是:把浏览器的控制权交给你。 你接手把这一步做完,交还后它从断点接着往下干,不用作废重来,上下文不丢失。
这套接管有一个讲究的细节:发起接管时,任务并不暂停,只是签发一个几分钟内有效的接管链接;真的有人打开链接接手,任务才暂停;没人来,链接过期作废,Agent 继续自己想办法。这个设计避免了一种尴尬的死等:Agent 签发了求助,人在开会,任务就此挂死。
链接可以直接转发给你的终端用户(短信、二维码都行),同一时刻只允许一个人控制。人做完交还,Agent 强制重新观察一次页面,再继续:人接管期间发生了什么,它不猜,重新看。
别人在讲 Agent 能做什么。我们在讲,人随时能接管、再交还。
放手,和放心,从来不该是二选一。
Track 替你盯页面:变没变由确定性规则裁决,不靠模型措辞
Track 的用法很朴素:设定目标和频率,页面一有变化主动通知你。但"变没变"这个判断,恰恰是模型最不该独占的环节。
模型的措辞会漂移:同一个页面,今天描述成"价格下调",明天描述成"促销上线"。如果由模型的措辞决定要不要提醒,盯守系统就成了一台随机数发生器。所以 Track 的分工是:模型只负责描述观测,"变没变、该不该提醒"由确定性规则判定。 模型也不被允许自行宣称"已经发过提醒":裁决权在代码,不在措辞。
判定为变化,webhook 投递到你配置的端点,经你现有的集成进到工作群;没变,回到巡查节奏。
深度研究可在大规模收集前等你确认方向,避免越勤奋浪费越彻底
深度研究是一条显式的流水线:简报 → 计划 → 大纲 → 收集 → 交叉核对 → 综合。 六个阶段显式串联,不是一个黑盒转十分钟然后吐一篇文章。
大纲这一步可以停下来等人确认:方向对了再开跑。这个暂停点的位置是有讲究的:它在大规模收集之前。研究方向错了,收集越勤奋,浪费越彻底;先花一分钟对齐"研究什么",比事后重跑一小时便宜得多。
收集阶段多引擎并行检索、按规范化 URL 去重;交叉核对阶段核验多来源的一致性;最终产出带引用清单和置信度标注的结论文档,而不是一页链接。
用真实任务反复回放,目标是把 P90 压进两分钟、成功率推向 99%
"能跑通"和"能交付"之间,隔着的是工程。
我们给 Web Agent 定了一个标准。它不是已经达成的成绩,而是我们正在逼近的目标:任务完成时延的 P90 控制在两分钟以内,成功率朝 99% 去磨。
方法不神秘:拿过去几年真实用户交给我们的任务,反复测试;跑不好的场景,逐个定位、修好、再回放验证;一轮一轮,磨到稳定。有效的改进沉淀成通用能力,而不是某个案例的特殊补丁。
运营不用守夜、财务不用手工导表:它已经在生产里干这两类活
第一类:社交媒体自动化与数据采集。 一个真实的日常:运营同学对 Agent 说"盯住这三家竞品的价格页和新品页,有变化告诉我"。Track 接手:按设定的节奏巡查,变没变由确定性规则裁决,该提醒时通知推到工作群;同一套能力,也在跑多平台内容发布、评论区监控和公开数据聚合。一句话下达,之后是它的事:凌晨三点页面改版了,也是它的事。
第二类:企业内部那些"接不进来的系统"。 不是每家企业都有湖仓一体和标准化 API。真实的企业里,散落着大量不标准、难维护的旧系统:没有 API,但有网页。一个典型的循环:财务同事每周要从一套老系统的网页里导出报表,Web Agent 接管这条流程:登录、导航、导出、把文件落到工作目录交给下游任务。登录过期了?任务挂起进"等人输入",接管链接发给同事,重新登录之后从断点继续。无人值守的场景,靠的不是"永远不出事",而是出事之后有一条走得通的路。
几行代码接入:委托先圈定权限,结果分开回答「跑完了」和「做成了」
前面讲的都是机器内部。开发者关心的是另一件事:接进来要几行代码。
SDK 包名是 @qoniai/qoni(Node 18+,ESM / CommonJS 双构建,TypeScript 类型齐备),凭 Qoni Console 签发的 AK / SK 初始化。接入的第一步不是发任务,而是拿委托:为当前用户签发一张范围明确的委托凭证,Agent 只在这张凭证的边界内行动。
import { Qoni } from "@qoniai/qoni";
const qoni = new Qoni({ accessKey, secretKey });
// 权限先行:products 语法糖会为每个产品展开 read + manage 一对 scope
const { data } = await qoni.delegateToken({
user: { id: userId },
products: ["doAnything", "track"],
});
// 一条指令,一次执行
const run = await qoni.doAnything.run({
token: data.token,
prompt: "打开后台,导出上周的对账单,放到工作目录",
});
const result = await run.wait();
result.status; // succeeded / failed / canceled:这次执行的交付状态
result.isTaskSuccessful; // 任务目标是否真的达成:另一个字段,分开回答
最后两行值得停一秒:交付状态和目标达成是两个字段。 一次执行可以正常结束(succeeded)但没有达成任务目标;协议把这两个问题分开回答,正是"无证据即失败"这条判定纪律在 SDK 里的样子。
需要人的时候,交互不是异常,是一种带类型的事件。五种交互(site_login / clarification / confirmation / take_control / wait)都从事件流里来,包成带方法的句柄:
for await (const event of run.events()) {
if (event.type !== "interaction") continue;
const i = run.interactionHandle(event.data);
if (i.type === "clarification" && i.can("answer")) await i.answer("蓝色那个按钮");
else if (i.can("confirm")) await i.confirm();
}
i.can() 有个讲究:每个动作是否可用由后端在交互里显式声明,调用未声明的方法直接抛错。换句话说,"恢复"按钮只在真的能恢复时才存在,SDK 不给你画一个点了没用的按钮。
盯守走同一套形状:qoni.track.create() 返回监控句柄,新监控先进入意图对齐(pending_clarification),转为 active 后可以 runNow() 立即巡查、refine() 调整节奏与通知通道、pause() / resume() / delete() 管理生命周期。断线之后,凭 id attach() 回同一个监控或执行,从事件流断点续传。
不用听供应商口述,拿真实任务逐项验收每条能力
以上能力都不必听供应商口述,可以直接落成验收单上逐条打钩的条目:
- 拿真实任务回归回放,断言的是最终答案,而不是"流程走完了";
- 中断事件流再重连,事件按序补齐;
- 签发接管链接后无人接手:任务不暂停、继续推进,链接到期作废;
- 有人接手:同一时刻只有一人控制,交还后 Agent 强制重新观察一次页面再继续;
- 布置一个注定给不出成功证据的任务,得到的判定是失败,而不是含糊的成功;
- 让登录态过期:状态可查,任务挂起进"等人输入",重新登录后从断点继续;
- Track 的裁决可复验:同一组观测输入重复裁决,结论一致;判定为变化时,webhook 送达你配置的端点;
- 触发提交 / 付款 / 删除类动作:必须经过类型化关卡;遇到验证码:升级给人,而不是静默绕过。
一张速查表,收拢全文讲过的能力:
| 能力 | 一句话说明 |
|---|---|
| 通用网页操作 | 一句话下达多步流程:登录、填表、比价,微步循环逐步执行 |
| 深度研究 | 六阶段显式流水线,产出带引用清单与置信度标注的结论文档 |
| 搜索 | 多引擎并行检索、规范化 URL 去重、交叉核对 |
| Track 持续盯守 | 按节奏巡查,变没变由确定性规则裁决,webhook 投递到你的端点 |
| 登录态档案 | 登录一次跨会话复用,一份档案是一份完整浏览器身份,失效有状态可查 |
| 工作目录 | 跨执行传递文件,上一个任务的产出,下一个接着用 |
| Take Control | 接管链接分钟级有效,有人接手才暂停,交还后强制重新观察 |
| 事件流 | 每步结构化记录、按序编号推送,断线续传,支持逐步回放 |
| 技能沉淀 | 验证过的路径固化为确定性动作序列,站点之间不迁移 |
| 风险关卡 | 提交 / 付款 / 删除过类型化 Gate,验证码升级给人 |
| SDK 接入 | @qoniai/qoni,委托先行,五种交互类型协议化,断线可 attach 续传 |
下一步:上公开榜单自证,再跑进你自己的浏览器
两件事,不承诺时间,但都在路上:
- 去公开的行业测试榜上证明自己,并把这些年积累的真实任务,整理成一套对外发布的测试集;
- 让 Agent 不只跑在云端:将来,它也能跑在你自己的浏览器和电脑上。
终态证据加真实任务回放,把「又快又准」从口号变成工程目标
不是又一个会演示的 Agent,而是把「又快又准」当成工程指标来交付。
Web Agent 目前处于 private build,将随 Qoni 分阶段开放,可以在官网加入 waitlist。
