跳到主要内容

轨迹格式

Hermes Agent 会以兼容 ShareGPT 的 JSONL 格式保存对话轨迹,用于训练数据、调试产物和强化学习数据集。

Hermes Agent 以兼容 ShareGPT 的 JSONL 格式保存对话轨迹 用作训练数据、调试工件和强化学习数据集。

源文件:agent/trajectory.pyrun_agent.py(搜索_save_trajectory)、batch_runner.py

文件命名约定

轨迹被写入当前工作目录中的文件中:

文件
trajectory_samples.jsonltrajectory_samples.jsonl成功完成的对话 (completed=True)
failed_trajectories.jsonlfailed_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_statstool_error_counts 字典被规范化为包括 所有可能的工具(来自 model_tools.TOOL_TO_TOOLSET_MAP),默认值为零, 确保 HuggingFace 数据集加载的条目之间的架构一致。

对话数组(ShareGPT 格式)

conversations 数组使用 ShareGPT 角色约定:

API 角色ShareGPT from
系统"system"
用户"human"
助理"gpt"
工具"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. 本机思维标记(来自提供商的 msg["reasoning"] 字段,例如 Anthropic、OpenAI o 系列):包装为 <think>\n{reasoning}\n</think>\n 并放在内容之前。

  2. REASONING_SCRATCHPAD XML(当本机思维被禁用并且模型 通过系统提示指示的 XML 的原因): <REASONING_SCRATCHPAD> 标签是 通过 convert_scratchpad_to_think() 转换为 <think>

  3. 空思考块:每个 gpt 回合保证有一个 <think> 堵塞。如果没有产生推理,则插入一个空块: <think>\n</think>\n — 这确保了训练数据的格式一致。

工具调用规范化

来自 API 格式的工具调用(使用 tool_call_id、函数名称、参数为 JSON 字符串)转换为 XML 包装的 JSON:

<tool_call>
{"name": "terminal", "arguments": {"command": "ls -la"}}
</tool_call>
  • 参数从 JSON 字符串解析回对象(不是双重编码)
  • 如果 JSON 解析失败(不应该发生 - 在对话期间验证), 使用空的 {} 并记录警告
  • 一个辅助回合中的多个工具调用会产生多个 <tool_call> 块 在单个 gpt 消息中

工具响应标准化

助理消息后的所有工具结果都分组到单个 tool 中 转而使用 XML 包装的 JSON 响应:

<tool_response>
{"tool_call_id": "call_abc123", "name": "terminal", "content": "output here"}
</tool_response>
  • 如果工具内容看起来像 JSON(以 {[ 开头),则会对其进行解析,以便 内容字段包含 JSON 对象/数组而不是字符串
  • 多个工具结果在一条消息中以换行符连接
  • 工具名称按位置与父助手的 tool_calls 进行匹配 大批

系统消息

系统消息是在保存时生成的(不是从对话中获取的)。 它遵循 Hermes 函数调用提示模板:

  • 解释函数调用协议的序言
  • <tools> 包含 JSON 工具定义的 XML 块
  • FunctionCall 对象的架构参考
  • <tool_call> 示例

工具定义包括 namedescriptionparametersrequired (设置为 null 以匹配规范格式)。

加载轨迹

轨迹是标准 JSONL — 使用任何 JSON 行读取器加载:

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 模式确保所有条目具有相同的列, 防止数据集加载期间出现箭头架构不匹配错误。

控制轨迹保存

在 CLI 中,轨迹保存由以下各项控制:

# config.yaml
agent:
save_trajectories: true # default: false

或者通过 --save-trajectories 标志。当代理初始化时 save_trajectories=True,最后调用_save_trajectory()方法 每个对话回合。

批处理运行器始终保存轨迹(这是其主要目的)。

所有回合中推理为零的样本将被自动丢弃 批处理运行器以避免非推理示例污染训练数据。