Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

轨迹格式

Hermes Agent以兼容ShareGPT的JSONL格式保存对话轨迹,这些轨迹可用于训练数据、调试信息以及强化学习数据集。

相关源文件:agent/trajectory.py、agent/session_persistence.py(查找 _save_trajectory 函数)、batch_runner.py

文件命名规则

轨迹文件会存储在当前工作目录中:

文件名适用场景
trajectory_samples.jsonl成功完成的对话(completed=True)
failed_trajectories.jsonl失败或被中断的对话(completed=False)

批量处理工具batch_runner.py会为每批处理结果生成一个包含额外元数据字段的定制输出文件(例如:batch_001_output.jsonl)。

您可以通过save_trajectory()函数中的filename参数来自定义文件名。

JSONL记录格式

文件中的每一行都是一个独立的JSON对象。该格式有两种变体:

CLI/交互式格式(来自 _save_trajectory)

{
  "conversations": [ ... ],
  "timestamp": "2026-03-30T14:22:31.456789",
  "model": "anthropic/claude-sonnet-4.6",
  "completed": true
}

批量运行器格式(来自 batch_runner.py)

{
  "prompt_index": 42,
  "conversations": [ ... ],
  "metadata": { "prompt_source": "gsm8k", "difficulty": "hard" },
  "completed": true,
  "partial": false,
  "api_calls": 7,
  "toolsets_used": ["code_tools", "file_tools"],
  "tool_stats": {
    "terminal": {"count": 3, "success": 3, "failure": 0},
    "read_file": {"count": 2, "success": 2, "failure": 0},
    "write_file": {"count": 0, "success": 0, "failure": 0}
  },
  "tool_error_counts": {
    "terminal": 0,
    "read_file": 0,
    "write_file": 0
  }
}

tool_stats与tool_error_counts这两个字典均经过标准化处理,会包含model_tools.TOOL_TO_TOOLSET_MAP中列出的所有可能工具,且默认值为零。这样的设计能够确保在加载HuggingFace数据集时,各个条目的结构保持一致。

对话数组(ShareGPT格式)

conversations数组遵循ShareGPT的角色规范:

API角色ShareGPT from值
system"system"
user"human"
assistant"gpt"
tool"tool"

完整示例

{
  "conversations": [
    {
      "from": "system",
      "value": "You are a function calling AI model. You are provided with function signatures within <tools> </tools> XML tags. You may call one or more functions to assist with the user query. If available tools are not relevant in assisting with user query, just respond in natural conversational language. Don't make assumptions about what values to plug into functions. After calling & executing the functions, you will be provided with function results within <tool_response> </tool_response> XML tags. Here are the available tools:\n<tools>\n[{\"name\": \"terminal\", \"description\": \"Execute shell commands\", \"parameters\": {\"type\": \"object\", \"properties\": {\"command\": {\"type\": \"string\"}}}, \"required\": null}]\n</tools>\nFor each function call return a JSON object, with the following pydantic model json schema for each:\n{'title': 'FunctionCall', 'type': 'object', 'properties': {'name': {'title': 'Name', 'type': 'string'}, 'arguments': {'title': 'Arguments', 'type': 'object'}}, 'required': ['name', 'arguments']}\nEach function call should be enclosed within <tool_call> </tool_call> XML tags.\nExample:\n<tool_call>\n{'name': <function-name>,'arguments': <args-dict>}\n</tool_call>"
    },
    {
      "from": "human",
      "value": "What Python version is installed?"
    },
    {
      "from": "gpt",
      "value": "<think>\nThe user wants to know the Python version. I should run python3 --version.\n</think>\n<tool_call>\n{\"name\": \"terminal\", \"arguments\": {\"command\": \"python3 --version\"}}\n</tool_call>"
    },
    {
      "from": "tool",
      "value": "<tool_response>\n{\"tool_call_id\": \"call_abc123\", \"name\": \"terminal\", \"content\": \"Python 3.11.6\"}\n</tool_response>"
    },
    {
      "from": "gpt",
      "value": "<think>\nGot the version. I can now answer the user.\n</think>\nPython 3.11.6 is installed on this system."
    }
  ],
  "timestamp": "2026-03-30T14:22:31.456789",
  "model": "anthropic/claude-sonnet-4.6",
  "completed": true
}

标准化规则

推理内容标记

轨迹转换器会将所有推理内容统一转换为 <think> 标签,而不论模型最初是以何种形式生成这些内容的:

  1. 原生推理标记(来自 Anthropic、OpenAI o 系列等提供方的 msg["reasoning"] 字段):会被封装为 <think>\n{reasoning}\n</think>\n 的格式,并置于内容之前。

  2. REASONING_SCRATCHPAD XML(在禁用原生推理且模型通过系统提示指令以 XML 格式进行推理时):convert_scratchpad_to_think() 函数会将 <REASONING_SCRATCHPAD> 标签转换为 <think> 标签。

  3. 空的思考块:每个 gpt 回应都必定包含一个 <think> 块。如果未生成任何推理内容,则会插入一个空块:\n\n>——这样做是为了确保训练数据格式的一致性。

工具调用标准化

API 格式的工具调用(包含 tool_call_id、函数名称以及作为 JSON 字符串的参数)会被转换为 XML 封装的 JSON 格式:

<tool_call>
{"name": "terminal", "arguments": {"command": "ls -la"}}
</tool_call>
  • 参数会从 JSON 字符串解析为对象形式(不会进行双重编码)。
  • 若 JSON 解析失败(本不应发生,因为已在对话过程中进行了验证),则使用空对象 {} 并记录警告信息。
  • 在一个助手轮次中发起的多次工具调用,会在单个 gpt 消息中生成多个 <tool_call> 块。

工具响应规范化

助手消息之后的所有工具响应都会被汇总到同一个 tool 轮次中,并以 XML 包装的 JSON 格式返回。

<tool_response>
{"tool_call_id": "call_abc123", "name": "terminal", "content": "output here"}
</tool_response>
  • 如果工具内容为 JSON 格式(以 { 或 [ 开头),系统会对其进行解析,从而使 content 字段存储的是 JSON 对象/数组而非字符串。
  • 多个工具的返回结果会在同一条消息中通过换行符分隔。
  • 工具名称会根据其在父助手的 tool_calls 数组中的位置进行匹配。

系统消息

系统消息是在数据保存时生成的(并非来自对话内容)。它遵循 Hermes 函数调用提示模板,包含以下部分:

  • 用于说明函数调用协议的前置说明;
  • 包含 JSON 工具定义的 <tools> XML 块;
  • FunctionCall 对象的架构参考;
  • <tool_call> 的示例。

工具定义需包含 name、description、parameters 和 required 字段(如需符合标准格式,可将该字段设置为 null)。

加载轨迹数据

轨迹数据为标准的 JSONL 格式,可使用任何 JSON-lines 读取工具进行加载:

import json

def load_trajectories(path: str):
    """Load trajectory entries from a JSONL file."""
    entries = []
    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line:
                entries.append(json.loads(line))
    return entries

# Filter to successful completions only
successful = [e for e in load_trajectories("trajectory_samples.jsonl")
              if e.get("completed")]

# Extract just the conversations for training
training_data = [e["conversations"] for e in successful]

正在加载 HuggingFace 数据集

from datasets import load_dataset

ds = load_dataset("json", data_files="trajectory_samples.jsonl")

标准化的 tool_stats 结构确保所有条目都包含相同的字段,从而避免在加载数据集时出现 Arrow 结构不匹配的错误。

控制轨迹保存功能

轨迹保存功能属于 run_agent.py 或库级别的开关——hermes CLI 并未提供相关的配置键或参数。

python run_agent.py --save_trajectories --query='your question here'

或者通过编程方式实现:AIAgent(..., save_trajectories=True) / initialize_agent(..., save_trajectories=True)。启用该选项后,每次对话轮次结束时都会调用_save_trajectory()方法。

批量运行器会始终保存对话轨迹数据(这正是它的核心功能)。

对于所有对话轮次中均无推理行为的样本,批量运行器会自动将其丢弃,以避免用此类非推理样本污染训练数据。