Efficient Agent Trajectory Annotation with onPanda

Dynamically connect to agent environments and annotate multi-turn SFT and preference data with tool_calls and reasoning online


Watch the screen recording of agent trajectory annotation in onPanda (starting at 1:42)

Existing agent observability and annotation tools (such as Potato and Argilla) mostly support assigning attributes or adding textual feedback to completed trajectories. However, editing trajectories to construct high-quality multi-turn agent SFT data presents two core challenges:

  1. Coupled environment state: Agent trajectories alternate between tool calls (tool_calls) and environment feedback (tool messages). Once a tool call in a given turn is modified, the original subsequent trajectory is usually no longer valid—the corrected call must be executed in the real environment, and generation must continue from the new feedback.
  2. Complex output structure: In the era of reasoning models and agents, a single model response contains not only content, but also lengthy reasoning chains and structured tool_calls. Annotators must understand and edit both the reasoning process and tool arguments, making manual rewriting costly and annotation UI design challenging.

onPanda (Project Page) is an open-source LLM alignment data annotation tool built around the paradigm of correcting the generation process in real time rather than rewriting outputs after the fact. onPanda dynamically connects to real agent runtime environments, allowing annotators to efficiently edit reasoning, content, and tool_calls at the token level and produce SFT, preference, and token-level supervision data with high on-policy fidelity through real environment interaction.

Live Demo 🎮 | Video Demo ▶️ | Paper 📄 | Source Code 👨‍💻

Annotation interface and interaction

In onPanda, while reading the model output, annotators simply locate the first inappropriate token and either select a replacement from the model's top_logprobs candidates or double-click to type a correction directly. onPanda then truncates everything after that position and lets the model continue generating from the corrected prefix:

onPanda token-level correction interaction: hover to select candidates and continue from prefix

For multi-turn agent trajectories, onPanda seamlessly extends this "locate–correct–continue" loop to reasoning chains and tool calls:

Annotating Agent Trajectories with onPanda

As shown above, onPanda's agent annotation interface features three core mechanisms:

  1. Synchronized dual-view editing: Through bidirectional conversion via the Response Template, annotators can click candidates or edit tokens directly in the structured reasoning and tool_calls panels on the right, or modify the model's native token stream on the left (even inserting special tokens such as </think> to truncate overly long reasoning).
  2. Pre-execution interception (Tool Call Control): Execution pauses before a tool modifies the environment. Annotators can fix tool_calls arguments before clicking Run to approve execution, or click Reject to decline the call (optionally with textual guidance so the model can replan).
  3. Automatic annotation tree branching (1~7 at the bottom): Every prefix edit or rejected tool call is automatically saved as a separate branch, naturally forming preference pairs under the exact same context prefix.

👉 Try it now: Open the agent-annotate example in the live demo to explore and test it yourself.

Connect your own agent tools and environment

Annotating agent trajectories in onPanda relies on real environment feedback and supports two ways to connect the target environment:

  1. Native MCP integration: onPanda natively supports MCP (Model Context Protocol). Any tool environment exposed as a Streamable HTTP MCP Server can be connected directly to the annotation workflow.
  2. Existing agent harness integration: If your target environment is an existing agent framework (harness), the companion harness_to_mcp tool wraps the harness's internal tools and runtime environment into an MCP Server for onPanda.
    • harness_to_mcp natively supports Claude Code, Codex, and OpenCode. To support another custom harness, a coding agent can quickly implement an adapter by referencing the existing ones.

To connect, simply specify the MCP server URL in tool_configs within your annotation data and set "require_approval": "always" to enable human interception and approval before tool execution (see the .panda.json Data Format Specification):

{
  "version": "2.0",
  "dialogs": {
    "1": {
      "messages": [{ "role": "user", "content": "What tools do you have available?" }],
      "tool_configs": [
        {
          "type": "mcp",
          "server_url": "http://127.0.0.1:9330/mcp",
          "server_label": "claude-code",
          "require_approval": "always"
        }
      ]
    }
  }
}

Beyond environment integration, token-level correction requires an inference API that supports continuing generation from an assistant prefix (such as vLLM's continue_final_message), candidate selection relies on top_logprobs, and continuation within reasoning and tool_calls is handled automatically by built-in Response Templates. For supported inference engines (vLLM, SGLang, llama.cpp) and hosted API providers, see API Compatibility.

Benefits of the token-level correction paradigm

Compared with traditional manual post-editing or multi-sample preference ranking, onPanda's token-level correction workflow offers several key advantages:

Annotation results are saved in a single .panda.json file and can be exported into SFT, preference, and token-level correction training datasets using the companion Python library onpanda (see also the Panda-CVL dataset and benchmark). For the full controlled experimental design and analysis, see our paper: onPanda: Efficient Annotation of On-Policy Alignment Data for LLMs and Agents via Token-Level Correction.

Start your own agent annotation project

onPanda has been used in production at StepFun to annotate hundreds of thousands of alignment data samples across vision, audio, and agent trajectory tasks. It can be used in two ways: