Chuyển tới nội dung chính

Định dạng quỹ đạo

Đại lý Hermes lưu quỹ đạo hội thoại ở định dạng JSONL tương thích với ShareGPT để sử dụng làm dữ liệu huấn luyện, tạo phẩm gỡ lỗi và bộ dữ liệu học tập tăng cường.

Tệp nguồn: agent/trajectory.py, run_agent.py (tìm kiếm _save_trajectory), batch_runner.py

Quy ước đặt tên tệp

Quỹ đạo được ghi vào các tập tin trong thư mục làm việc hiện tại:

Tập tinKhi nào
quỹ đạo_samples.jsonlCuộc trò chuyện đã hoàn tất thành công (completed=True)
failed_trajectories.jsonlCuộc trò chuyện không thành công hoặc bị gián đoạn (completed=False)

Trình chạy bó (batch_runner.py) ghi vào tệp đầu ra tùy chỉnh cho mỗi đợt (ví dụ: batch_001_output.jsonl) với các trường siêu dữ liệu bổ sung.

Bạn có thể ghi đè tên tệp thông qua tham số filename trong save_trajectory().

Định dạng mục nhập JSONL

Mỗi dòng trong tệp là một đối tượng JSON độc lập. Có hai biến thể:

CLI/Định dạng tương tác (từ _save_trajectory)

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

Định dạng chạy hàng loạt (từ 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
}
}

Từ điển tool_statstool_error_counts được chuẩn hóa để bao gồm TẤT CẢ các công cụ có thể có (từ model_tools.TOOL_TO_TOOLSET_MAP) không có giá trị mặc định, đảm bảo lược đồ nhất quán giữa các mục để tải tập dữ liệu HuggingFace.

Mảng hội thoại (Định dạng ShareGPT)

Mảng conversations sử dụng các quy ước vai trò ShareGPT:

Vai trò APIChia sẻGPT từ
hệ thống"hệ thống"
người dùng"con người"
trợ lý"gpt"
công cụ"công cụ"

Ví dụ hoàn chỉnh

{
"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
}

Quy tắc chuẩn hóa

Đánh dấu nội dung lý luận

Bộ chuyển đổi quỹ đạo chuẩn hóa TẤT CẢ lý luận thành các thẻ <think>, bất kể về cách mô hình ban đầu tạo ra nó:

  1. Mã thông báo suy nghĩ bản địa (msg["reasoning"] từ các nhà cung cấp như Anthropic, OpenAI o-series): Được gói gọn dưới dạng <think>\n{reasoning}\n</think>\n và được đặt trước nội dung.

  2. REASONING_SCRATCHPAD XML (khi tư duy bản địa bị vô hiệu hóa và mô hình lý do thông qua XML được hệ thống nhắc nhở): các thẻ <REASONING_SCRATCHPAD> là được chuyển đổi thành <think> thông qua convert_scratchpad_to_think().

  3. Khối suy nghĩ trống: Mỗi lượt gpt được đảm bảo có <think> khối. Nếu không có lý do nào được đưa ra, một khối trống sẽ được chèn vào: <think>\n</think>\n — điều này đảm bảo định dạng nhất quán cho dữ liệu huấn luyện.

Chuẩn hóa cuộc gọi công cụ

Lệnh gọi công cụ từ định dạng API (với tool_call_id, tên hàm, đối số như chuỗi JSON) được chuyển đổi thành JSON được bọc XML:

<tool_call>
{"name": "terminal", "arguments": {"command": "ls -la"}}
</tool_call>
  • Các đối số được phân tích cú pháp từ chuỗi JSON trở lại đối tượng (không được mã hóa kép)
  • Nếu phân tích cú pháp JSON không thành công (không nên xảy ra - được xác thực trong cuộc trò chuyện), một {} trống được sử dụng với một cảnh báo được ghi lại
  • Nhiều lệnh gọi công cụ trong một lượt trợ lý tạo ra nhiều khối <tool_call> trong một tin nhắn gpt

Chuẩn hóa phản hồi của công cụ

Tất cả các kết quả về công cụ theo sau thông báo trợ lý được nhóm thành một công cụ duy nhất chuyển sang các phản hồi JSON được bọc XML:

<tool_response>
{"tool_call_id": "call_abc123", "name": "terminal", "content": "output here"}
</tool_response>
  • Nếu nội dung công cụ trông giống như JSON (bắt đầu bằng { hoặc [), thì nội dung đó sẽ được phân tích cú pháp để trường nội dung chứa một đối tượng/mảng JSON chứ không phải một chuỗi
  • Nhiều kết quả công cụ được nối với dòng mới trong một tin nhắn
  • Tên công cụ được khớp theo vị trí với tool_calls của trợ lý chính mảng

Thông báo hệ thống

Thông báo hệ thống được tạo vào thời điểm lưu (không được lấy từ cuộc hội thoại). Nó tuân theo mẫu lời nhắc gọi hàm Hermes với:

  • Lời mở đầu giải thích giao thức gọi hàm
  • <tools> Khối XML chứa các định nghĩa công cụ JSON
  • Tham chiếu lược đồ cho các đối tượng FunctionCall
  • ví dụ <tool_call>

Các định nghĩa về công cụ bao gồm tên, mô tả, tham sốbắt buộc (được đặt thành null để khớp với định dạng chuẩn).

Đang tải quỹ đạo

Quỹ đạo là JSONL tiêu chuẩn - tải bằng bất kỳ trình đọc dòng JSON nào:

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]

Đang tải bộ dữ liệu HuggingFace

from datasets import load_dataset

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

Lược đồ tool_stats được chuẩn hóa đảm bảo tất cả các mục nhập đều có cùng một cột, ngăn ngừa lỗi không khớp lược đồ Mũi tên trong quá trình tải dữ liệu.

Kiểm soát tiết kiệm quỹ đạo

Trong CLI, việc lưu quỹ đạo được kiểm soát bởi:

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

Hoặc thông qua cờ --save-trajectories. Khi tác nhân khởi tạo với save_trajectories=True, phương thức _save_trajectory() được gọi ở cuối của mỗi lượt trò chuyện.

Trình chạy theo đợt luôn lưu lại quỹ đạo (đó là mục đích chính của nó).

Các mẫu không có lý do trong tất cả các lượt sẽ tự động bị loại bỏ bởi người chạy hàng loạt để tránh làm ô nhiễm dữ liệu huấn luyện với các ví dụ không có lý do.