Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

Formato de trajetória

Formato de trajetória

O Hermes Agent salva as trajetórias de conversa em formato JSONL compatível com ShareGPT, para uso como dado de treinamento, artefato de depuração e conjunto de dados de aprendizado por reforço.

Arquivos-fonte: agent/trajectory.py, run_agent.py (procure por _save_trajectory), batch_runner.py

Convenção de nomes de arquivo​

As trajetórias são escritas em arquivos no diretório de trabalho atual:

ArquivoQuando
trajectory_samples.jsonlConversas que terminaram com sucesso (completed=True)
failed_trajectories.jsonlConversas que falharam ou foram interrompidas (completed=False)

O executor em lote (batch_runner.py) escreve em um arquivo de saída próprio por lote (por exemplo, batch_001_output.jsonl), com campos de metadados a mais.

Você pode trocar o nome do arquivo pelo parâmetro filename de save_trajectory().

Formato de entrada JSONL​

Cada linha do arquivo é um objeto JSON autocontido. Existem duas variantes:

Formato da CLI/interativo (de _save_trajectory)​

{### Formato do executor em lote (de `batch_runner.py`) {#batch-runner-format-from-batchrunnerpy}laude-sonnet-4.6",
"completed": true
}

Formato do executor em lote (de 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
}
}

Os dicionários tool_stats e tool_error_counts são normalizados para incluir TODAS as ferramentas possíveis (a partir de model_tools.TOOL_TO_TOOLSET_MAP), com zero como padrão, garantindo um esquema consistente entre as entradas na hora de carregar o conjunto de dados no HuggingFace.

O array conversations (formato ShareGPT)​

O array conversations usa as convenções de papel do ShareGPT:

Papel na APIfrom do ShareGPT
system"system"
user"human"
assistant"gpt"
tool"tool"

Exemplo completo​

{
"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": "Qual versão do Python está instalada?"
},
{
"from": "gpt",
"value": "<think>\nO usuário quer saber a versão do Python. Eu devo rodar 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>\nPeguei a versão. Agora posso responder ao usuário.\n</think>\nO Python 3.11.6 está instalado neste sistema."
}
],
"timestamp": "2026-03-30T14:22:31.456789",
"model": "anthropic/claude-sonnet-4.6",
"completed": true
}

Regras de normalização​

Marcação do conteúdo de raciocínio​

O conversor de trajetória normaliza TODO raciocínio para tags <think>, não importa como o modelo o produziu originalmente:

  1. Tokens de pensamento nativos (campo msg["reasoning"], de provedores como Anthropic e a série o da OpenAI): envolvidos como <think>\n{reasoning}\n</think>\n e colocados antes do conteúdo.

  2. XML REASONING_SCRATCHPAD (quando o pensamento nativo está desligado e o modelo raciocina por XML instruído no prompt de sistema): as tags <REASONING_SCRATCHPAD> são convertidas em <think> por convert_scratchpad_to_think().

  3. Blocos think vazios: todo turno gpt tem garantidamente um bloco <think>. Se nenhum raciocínio foi produzido, um bloco vazio é inserido: <think>\n</think>\n — isso garante formato consistente para dado de treinamento.

Normalização das chamadas de ferramenta​

As chamadas de ferramenta do formato da API (com tool_call_id, nome da função e argumentos como string JSON) são convertidas em JSON envolvido por XML:

<tool_call>
{"name": "terminal", "arguments": {"command": "ls -la"}}
</tool_call>
  • Os argumentos são convertidos de string JSON de volta para objetos (sem codificação dupla)
  • Se a leitura do JSON falhar (não deveria acontecer — é validado durante a conversa), um {} vazio é usado e um aviso vai para o log
  • Várias chamadas de ferramenta em um mesmo turno de assistant produzem vários blocos <tool_call> em uma única mensagem gpt

Normalização das respostas de ferramenta​

Todos os resultados de ferramenta que vêm depois de uma mensagem de assistant são agrupados em um único turno tool, com respostas em JSON envolvido por XML:

<tool_response>
{"tool_call_id": "call_abc123", "name": "terminal", "content": "saída aqui"}
</tool_response>
  • Se o conteúdo da ferramenta parece JSON (começa com { ou [), ele é interpretado, de modo que o campo de conteúdo carrega um objeto/array JSON em vez de uma string
  • Vários resultados de ferramenta são juntados com quebras de linha em uma única mensagem
  • O nome da ferramenta é casado por posição com o array tool_calls da mensagem de assistant pai

Mensagem de sistema​

A mensagem de sistema é gerada na hora de salvar (não é tirada da conversa). Ela segue o modelo de prompt de chamada de função do Hermes, com:

  • Preâmbulo explicando o protocolo de chamada de função
  • Bloco XML <tools> com as definições JSON das ferramentas
  • Referência de esquema para objetos FunctionCall
  • Exemplo de <tool_call>

As definições de ferramenta incluem name, description, parameters e required (definido como null, para bater com o formato canônico).

Carregar trajetórias​

Trajetórias são JSONL padrão — carregue com qualquer leitor de JSON por linhas:

import json

def load_trajectories(path: str):
"""Carrega as entradas de trajetória de um arquivo JSONL."""
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

# Filtra só as conclusões bem-sucedidas
successful = [e for e in load_trajectories("trajectory_samples.jsonl")
if e.get("completed")]

# Extrai só as conversas, para treinamento
training_data = [e["conversations"] for e in successful]

Carregar para os Datasets do HuggingFace​

from datasets import load_dataset

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

O esquema normalizado de tool_stats garante que todas as entradas tenham as mesmas colunas, evitando erros de descompasso de esquema Arrow ao carregar o conjunto de dados.

Controlar o salvamento de trajetórias​

Salvar trajetória é uma chave do run_agent.py / do nível de biblioteca — a CLI hermes não expõe chave de configuração nem opção para isso:

python run_agent.py --save_trajectories --query='sua pergunta aqui'

Ou de forma programática: AIAgent(..., save_trajectories=True) / initialize_agent(..., save_trajectories=True). Quando está ligado, o método _save_trajectory() é chamado ao fim de cada turno de conversa.

O executor em lote sempre salva trajetórias (esse é o propósito principal dele).

Amostras com zero raciocínio em todos os turnos são descartadas automaticamente pelo executor em lote, para não poluir o dado de treinamento com exemplos sem raciocínio.