Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Harnesses in OpenEnv","local":"harnesses-in-openenv","sections":[{"title":"Which One to Use","local":"which-one-to-use","sections":[{"title":"Harbor or HarnessEnvironment ?","local":"harbor-or-harnessenvironment-","sections":[],"depth":3}],"depth":2}],"depth":1}"/> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/entry/start.CG5FzNt2.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/BBXg17tp.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/BSuxAqoA.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/entry/app.Db-H8-tM.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/Ds_1Ru_R.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/DIlRkxSv.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/DsnmJJEf.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/BAUKCucN.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/nodes/0.CR0SH4Os.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/CR5HsSXT.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/nodes/68.BlMiH78L.js" rel="modulepreload"> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/chunks/C07d6Hje.js" rel="modulepreload"> | |
| <!--1a1f9cf--><meta name="hf:doc:metadata" content="{"title":"Harnesses in OpenEnv","local":"harnesses-in-openenv","sections":[{"title":"Which One to Use","local":"which-one-to-use","sections":[{"title":"Harbor or HarnessEnvironment ?","local":"harbor-or-harnessenvironment-","sections":[],"depth":3}],"depth":2}],"depth":1}"/><!----> | |
| <link href="/docs/openenv/pr_1285/en/_app/immutable/assets/0.tn0RQdqM.css" rel="modulepreload"> <!--[--><!--[0--><!--[--><!--[0--><!--[--><p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg><!----></button></div> <!--[-1--><!--]--></div><!----> <!--[0--><h1 class="relative group"><a id="harnesses-in-openenv" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#harnesses-in-openenv"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Harnesses in OpenEnv</span></h1><!--]--><!----> <p>A harness is the loop around a model: it sends the conversation to the model, runs the tools the model calls, and decides when the episode ends. There are three ways to put a harness and an OpenEnv environment together. They differ in who owns the loop, what the environment provides and who is on the other side, and that decides what each one is for. “Black-box” is the term <a href="https://github.com/huggingface/OpenEnv/blob/main/rfcs/006-agentic-rl-harness-interception.md" rel="nofollow">RFC 006</a> uses, and “white-box” the one <code>openenv.core.harness</code> uses.</p> <table><thead><tr><th></th><th>White-box</th><th>Black-box</th><th>Agent inside the environment</th></tr></thead><tbody><tr><td>Who owns the loop</td><td>The trainer (for example TRL’s <code>environment_factory</code>)</td><td>A real agent (OpenCode, Claude Code, Codex, …)</td><td>A real agent (Claude Code in the tutorial)</td></tr><tr><td>What the environment provides</td><td>Tools and a reward for the model being trained</td><td>Tasks: an instruction, a sandbox, and a verifier</td><td>Its own tools and state, injected into the agent over MCP</td></tr><tr><td>Who is on the other side</td><td>Nobody, the model works through the task</td><td>Nobody, the agent runs to completion</td><td>A user, simulated or real, over several turns</td></tr><tr><td>Trains a model</td><td>Yes</td><td>Yes, from the captured token ids and logprobs in a <code>TrainingTrace</code> (against vLLM or SGLang)</td><td>No, nothing is captured</td></tr><tr><td>Serves real users</td><td>No</td><td>No</td><td>Yes, over <code>WS /harness</code></td></tr><tr><td>Example</td><td>Web tasks in BrowserGym</td><td>“Fix this repository”, “analyze these files”</td><td>Customer service on τ²-bench</td></tr><tr><td>Start here</td><td><a href="browsergym-harness">BrowserGym</a></td><td><a href="harbor-harness">Harbor</a></td><td><a href="claude-code-harness">Claude Code on τ²-bench</a></td></tr></tbody></table> <!--[1--><h2 class="relative group"><a id="which-one-to-use" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#which-one-to-use"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Which One to Use</span></h2><!--]--><!----> <ul><li><strong>You want to train a model on your environment and the loop can be simple.</strong> Use the white-box path. The trainer runs the tool loop, so token ids and logprobs come for free, and the environment only supplies tools and a reward. The BrowserGym tutorial does it with TRL’s <code>GRPOTrainer</code>, and <a href="../guides/training">Training with OpenEnv</a> lists the other frameworks that train on OpenEnv environments.</li> <li><strong>The job is a task that an agent does on its own, and a verifier checks the result.</strong> Use Harbor, to train the model behind the agent or to evaluate it. The agent keeps its own planner, tools and context management in a sandbox, and a proxy records every model call it makes. The resulting <code>TrainingTrace</code> is plain data that doesn’t depend on a trainer, and TRL’s <code>AsyncGRPOTrainer</code> has a worked example.</li> <li><strong>The job is a conversation, and the agent has to use your environment’s tools.</strong> Use <code>HarnessEnvironment</code> from <a href="https://github.com/huggingface/OpenEnv/blob/main/rfcs/005-agentic-harnesses.md" rel="nofollow">RFC 005</a>, to evaluate the agent against a simulated user or to serve it to real ones. The environment injects its tools, answers between turns and scores the conversation with a rubric.</li></ul> <!--[2--><h3 class="relative group"><a id="harbor-or-harnessenvironment-" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#harbor-or-harnessenvironment-"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span>Harbor or HarnessEnvironment ?</span></h3><!--]--><!----> <p>Both run a real agent, and the same agent can go either way: Claude Code is one of Harbor’s agents and the agent in the RFC 005 tutorial. What decides is the shape of the job. If an instruction goes in and a verifier checks what comes out, it is a Harbor task. If someone answers the agent between turns, or the agent works on your environment’s own state (a database, an API), use <code>HarnessEnvironment</code>. τ²-bench is the second kind: a simulated customer replies after every agent turn, which a Harbor task has no place for. To train, only Harbor records the tokens.</p> <p><a href="https://huggingface.co/spaces/FineEnvs/multi-harness-rl" rel="nofollow">The ultimate guide to multi-harness RL</a> goes deeper into the white-box and black-box paths and why training across several agents matters.</p> <blockquote class="note"><p><code>openenv.core.harness</code> also has a session runtime (<code>ResourceSession</code>, <code>MCPHarnessAdapter</code>, <code>build_harness_rollout_func</code>), where OpenEnv runs a small tool loop and a model generates each turn. <a href="sft-warmup"><code>openenv collect</code></a> uses it to collect rollouts for SFT. Its <code>HarnessAdapter</code> is a different class from RFC 005’s <code>AgenticHarnessAdapter</code>.</p></blockquote> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/openenv/blob/main/docs/source/tutorials/harnesses.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg><!----> <span><span class="underline">Update</span> on GitHub</span></a><!----> <p></p><!--]--><!----><!--]--><!--]--><!--]--> <!--[-1--><!--]--><!--]--> | |
| <script> | |
| { | |
| __sveltekit_efhe5s = { | |
| base: "/docs/openenv/pr_1285/en", | |
| assets: "/docs/openenv/pr_1285/en" | |
| }; | |
| const element = document.currentScript.parentElement; | |
| Promise.all([ | |
| import("/docs/openenv/pr_1285/en/_app/immutable/entry/start.CG5FzNt2.js"), | |
| import("/docs/openenv/pr_1285/en/_app/immutable/entry/app.Db-H8-tM.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 68], | |
| data: [null,null], | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 13.5 kB
- Xet hash:
- 51c2778c2a3bca216f0be6da5e187ff0052ea96a70a9e1b1cd5a626fc46f2542
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.