From 1b081e489156b84d067ddcebb1b72b45bd9b2b46 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sun, 26 Jul 2026 12:42:53 -0700 Subject: [PATCH] feat: raise default tool-calling iteration limit from 90 to 500 The default max_iterations/agent.max_turns budget was set when long agentic runs were rare; complex tasks now routinely exceed 90 tool calls. Raise the default to 500 across every surface that hardcodes the fallback: AIAgent constructor, DEFAULT_CONFIG, CLI resolution chain, gateway env bridge, cron scheduler, and TUI gateway. Explicit user config values are unaffected (deep-merge preserves them; no _config_version bump needed). Docs (en + zh-Hans), CLI help text, tips, and pinned tests updated to match. --- AGENTS.md | 2 +- agent/agent_init.py | 4 ++-- agent/iteration_budget.py | 4 ++-- cli.py | 12 ++++++------ cron/scheduler.py | 2 +- gateway/run.py | 8 ++++---- hermes_cli/_parser.py | 2 +- hermes_cli/config.py | 2 +- hermes_cli/tips.py | 4 ++-- run_agent.py | 2 +- tests/cli/test_cli_init.py | 8 ++++---- tests/test_tui_gateway_server.py | 8 ++++---- tui_gateway/server.py | 4 ++-- website/docs/developer-guide/agent-loop.md | 2 +- website/docs/guides/python-library.md | 4 ++-- website/docs/reference/cli-commands.md | 2 +- website/docs/reference/environment-variables.md | 2 +- website/docs/user-guide/configuration.md | 6 +++--- .../current/developer-guide/agent-loop.md | 2 +- .../current/guides/python-library.md | 4 ++-- .../current/reference/cli-commands.md | 2 +- .../current/reference/environment-variables.md | 2 +- .../current/user-guide/configuration.md | 8 ++++---- 23 files changed, 48 insertions(+), 48 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cb53e95eb0b9..d623ba59bbf1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -325,7 +325,7 @@ class AIAgent: provider: str = None, api_mode: str = None, # "chat_completions" | "codex_responses" | ... model: str = "", # empty → resolved from config/provider later - max_iterations: int = 90, # tool-calling iterations (shared with subagents) + max_iterations: int = 500, # tool-calling iterations (shared with subagents) enabled_toolsets: list = None, disabled_toolsets: list = None, quiet_mode: bool = False, diff --git a/agent/agent_init.py b/agent/agent_init.py index 955ca11cff8d..69d814f47dcc 100644 --- a/agent/agent_init.py +++ b/agent/agent_init.py @@ -455,7 +455,7 @@ def init_agent( command: str = None, args: list[str] | None = None, model: str = "", - max_iterations: int = 90, # Default tool-calling iterations (shared with subagents) + max_iterations: int = 500, # Default tool-calling iterations (shared with subagents) tool_delay: float = 1.0, enabled_toolsets: List[str] = None, disabled_toolsets: List[str] = None, @@ -529,7 +529,7 @@ def init_agent( requested_provider (str): Original provider identity before runtime canonicalization api_mode (str): API mode override: "chat_completions" or "codex_responses" model (str): Model name to use (default: "anthropic/claude-opus-4.6") - max_iterations (int): Maximum number of tool calling iterations (default: 90) + max_iterations (int): Maximum number of tool calling iterations (default: 500) tool_delay (float): Delay between tool calls in seconds (default: 1.0) enabled_toolsets (List[str]): Only enable tools from these toolsets (optional) disabled_toolsets (List[str]): Disable tools from these toolsets (optional) diff --git a/agent/iteration_budget.py b/agent/iteration_budget.py index 213b97c02265..7d50026c1701 100644 --- a/agent/iteration_budget.py +++ b/agent/iteration_budget.py @@ -2,7 +2,7 @@ Extracted from ``run_agent.py``. Each ``AIAgent`` instance (parent or subagent) holds an :class:`IterationBudget`; the parent's cap comes from -``max_iterations`` (default 90), each subagent's cap comes from +``max_iterations`` (default 500), each subagent's cap comes from ``delegation.max_iterations`` (default 50). ``run_agent`` re-exports ``IterationBudget`` so existing @@ -18,7 +18,7 @@ class IterationBudget: """Thread-safe iteration counter for an agent. Each agent (parent or subagent) gets its own ``IterationBudget``. - The parent's budget is capped at ``max_iterations`` (default 90). + The parent's budget is capped at ``max_iterations`` (default 500). Each subagent gets an independent budget capped at ``delegation.max_iterations`` (default 50) — this means total iterations across parent + subagents can exceed the parent's cap. diff --git a/cli.py b/cli.py index 2f0350b9a36d..4a32e2998998 100644 --- a/cli.py +++ b/cli.py @@ -471,7 +471,7 @@ def load_cli_config() -> Dict[str, Any]: "min_tail_user_messages": 1, # Real user messages guaranteed in the tail (1 = existing single anchor) }, "agent": { - "max_turns": 90, # Default max tool-calling iterations (shared with subagents) + "max_turns": 500, # Default max tool-calling iterations (shared with subagents) "verbose": False, "system_prompt": "", "prefill_messages_file": "", @@ -4099,7 +4099,7 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): provider: Inference provider ("auto", "openrouter", "nous", "openai-codex", "zai", "kimi-coding", "minimax", "minimax-cn") api_key: API key (default: from environment) base_url: API base URL (default: OpenRouter) - max_turns: Maximum tool-calling iterations shared with subagents (default: 90) + max_turns: Maximum tool-calling iterations shared with subagents (default: 500) verbose: Enable verbose logging compact: Use compact display mode resume: Session ID to resume (restores conversation history from SQLite) @@ -4272,9 +4272,9 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): try: self.max_turns = int(os.getenv("HERMES_MAX_ITERATIONS", "")) except (TypeError, ValueError): - self.max_turns = 90 + self.max_turns = 500 else: - self.max_turns = 90 + self.max_turns = 500 # Parse and validate toolsets self.enabled_toolsets = toolsets @@ -13128,8 +13128,8 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): # Notify when iteration budget was hit if result and not result.get("completed") and not result.get("interrupted"): _api_calls = result.get("api_calls", 0) - if _api_calls >= getattr(self.agent, "max_iterations", 90): - _max_iter = getattr(self.agent, "max_iterations", 90) + if _api_calls >= getattr(self.agent, "max_iterations", 500): + _max_iter = getattr(self.agent, "max_iterations", 500) _cprint( f"\n{_DIM}⚠ Iteration budget reached " f"({_api_calls}/{_max_iter}) — " diff --git a/cron/scheduler.py b/cron/scheduler.py index 5bffb00e1461..a20260758997 100644 --- a/cron/scheduler.py +++ b/cron/scheduler.py @@ -3254,7 +3254,7 @@ def run_job( prefill_messages = None # Max iterations - max_iterations = _cfg.get("agent", {}).get("max_turns") or _cfg.get("max_turns") or 90 + max_iterations = _cfg.get("agent", {}).get("max_turns") or _cfg.get("max_turns") or 500 # Provider routing pr = _cfg.get("provider_routing") or {} diff --git a/gateway/run.py b/gateway/run.py index aac6a192555f..07b272331b51 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -1667,9 +1667,9 @@ def _current_max_iterations() -> int: """Return the current per-turn iteration budget after runtime env refresh.""" _reload_runtime_env_preserving_config_authority() try: - return int(os.getenv("HERMES_MAX_ITERATIONS", "90")) + return int(os.getenv("HERMES_MAX_ITERATIONS", "500")) except (TypeError, ValueError): - return 90 + return 500 from contextlib import contextmanager as _contextmanager @@ -7877,10 +7877,10 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew # config.yaml → env bridge did the right thing at a glance (instead # of silently running at a stale .env value for weeks). try: - _effective_max_iter = int(os.getenv("HERMES_MAX_ITERATIONS", "90")) + _effective_max_iter = int(os.getenv("HERMES_MAX_ITERATIONS", "500")) logger.info( "Agent budget: max_iterations=%d (agent.max_turns from config.yaml, " - "or HERMES_MAX_ITERATIONS from .env, or default 90)", + "or HERMES_MAX_ITERATIONS from .env, or default 500)", _effective_max_iter, ) except Exception: diff --git a/hermes_cli/_parser.py b/hermes_cli/_parser.py index a4027221de4a..cb5be6b93589 100644 --- a/hermes_cli/_parser.py +++ b/hermes_cli/_parser.py @@ -382,7 +382,7 @@ def build_top_level_parser(): type=int, default=None, metavar="N", - help="Maximum tool-calling iterations per conversation turn (default: 90, or agent.max_turns in config)", + help="Maximum tool-calling iterations per conversation turn (default: 500, or agent.max_turns in config)", ) _inherited_flag( chat_parser, diff --git a/hermes_cli/config.py b/hermes_cli/config.py index 595d476014bc..25ec774da457 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -945,7 +945,7 @@ DEFAULT_CONFIG = { # pressure. Reopening one re-resumes it from disk. 0/null disables. "max_live_sessions": 16, "agent": { - "max_turns": 90, + "max_turns": 500, # Inactivity timeout for gateway agent execution (seconds). # The agent can run indefinitely as long as it's actively calling # tools or receiving API responses. Only fires when the agent has diff --git a/hermes_cli/tips.py b/hermes_cli/tips.py index a3dab63c44ff..be8cb25b15d0 100644 --- a/hermes_cli/tips.py +++ b/hermes_cli/tips.py @@ -69,7 +69,7 @@ TIPS = [ "hermes chat -t web,terminal enables only specific toolsets for a focused session.", "hermes chat -s github-pr-workflow preloads a skill at launch.", "hermes chat -q \"query\" runs a single non-interactive query and exits.", - "hermes chat --max-turns 200 overrides the default 90-iteration limit per turn.", + "hermes chat --max-turns 1000 overrides the default 500-iteration limit per turn.", "hermes chat --checkpoints enables filesystem snapshots before every destructive file change.", "hermes --yolo bypasses all dangerous command approval prompts for the entire session.", "hermes chat --source telegram tags the session for filtering in hermes sessions list.", @@ -112,7 +112,7 @@ TIPS = [ "Set display.busy_input_mode: queue to queue messages instead of interrupting the agent, or steer to inject them mid-run via /steer.", "Set display.resume_display: minimal to skip the full conversation recap on session resume.", "Set compression.threshold: 0.50 to control when auto-compression fires (default: 50% of context).", - "Set agent.max_turns: 200 to let the agent take more tool-calling steps per turn.", + "Set agent.max_turns: 1000 to let the agent take more tool-calling steps per turn.", "Set file_read_max_chars: 200000 to increase the max content per read_file call.", "Set approvals.mode: smart to let an LLM auto-approve safe commands and auto-deny dangerous ones.", "Set fallback_model in config.yaml to automatically fail over to a backup provider.", diff --git a/run_agent.py b/run_agent.py index 1adf170e5e01..4aa3b8332ef1 100644 --- a/run_agent.py +++ b/run_agent.py @@ -437,7 +437,7 @@ class AIAgent: command: str = None, args: list[str] | None = None, model: str = "", - max_iterations: int = 90, # Default tool-calling iterations (shared with subagents) + max_iterations: int = 500, # Default tool-calling iterations (shared with subagents) tool_delay: float = 1.0, enabled_toolsets: List[str] = None, disabled_toolsets: List[str] = None, diff --git a/tests/cli/test_cli_init.py b/tests/cli/test_cli_init.py index 48de5b7c95f4..c3915777da0c 100644 --- a/tests/cli/test_cli_init.py +++ b/tests/cli/test_cli_init.py @@ -60,7 +60,7 @@ class TestMaxTurnsResolution: def test_default_max_turns_is_integer(self): cli = _make_cli() assert isinstance(cli.max_turns, int) - assert cli.max_turns == 90 + assert cli.max_turns == 500 def test_explicit_max_turns_honored(self): cli = _make_cli(max_turns=25) @@ -69,7 +69,7 @@ class TestMaxTurnsResolution: def test_none_max_turns_gets_default(self): cli = _make_cli(max_turns=None) assert isinstance(cli.max_turns, int) - assert cli.max_turns == 90 + assert cli.max_turns == 500 def test_env_var_max_turns(self): """Env var is used when config file doesn't set max_turns.""" @@ -79,7 +79,7 @@ class TestMaxTurnsResolution: def test_invalid_env_var_max_turns_falls_back_to_default(self): """Invalid env values should not crash CLI init.""" cli_obj = _make_cli(env_overrides={"HERMES_MAX_ITERATIONS": "not-a-number"}) - assert cli_obj.max_turns == 90 + assert cli_obj.max_turns == 500 def test_legacy_root_max_turns_is_used_when_agent_key_exists_without_value(self): cli_obj = _make_cli(config_overrides={"agent": {}, "max_turns": 77}) @@ -88,7 +88,7 @@ class TestMaxTurnsResolution: def test_max_turns_never_none_for_agent(self): """The value passed to AIAgent must never be None (causes TypeError in run_conversation).""" cli = _make_cli() - assert isinstance(cli.max_turns, int) and cli.max_turns == 90 + assert isinstance(cli.max_turns, int) and cli.max_turns == 500 class TestVerboseAndToolProgress: diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index 7b7d6b2a6d65..dbdd2ec5ffc2 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -11656,22 +11656,22 @@ def test_make_agent_waits_for_shared_mcp_discovery(monkeypatch): def test_make_agent_nested_max_turns_takes_priority(monkeypatch): _setup_make_agent_mocks( - monkeypatch, {"agent": {"max_turns": 500}, "max_turns": 100} + monkeypatch, {"agent": {"max_turns": 400}, "max_turns": 100} ) with patch("run_agent.AIAgent") as mock_agent: server._make_agent("sid1", "key1") - assert mock_agent.call_args.kwargs["max_iterations"] == 500 + assert mock_agent.call_args.kwargs["max_iterations"] == 400 -def test_make_agent_defaults_to_90(monkeypatch): +def test_make_agent_defaults_to_500(monkeypatch): _setup_make_agent_mocks(monkeypatch, {}) with patch("run_agent.AIAgent") as mock_agent: server._make_agent("sid1", "key1") - assert mock_agent.call_args.kwargs["max_iterations"] == 90 + assert mock_agent.call_args.kwargs["max_iterations"] == 500 def test_make_agent_uses_session_runtime_overrides(monkeypatch): diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 25bcc2351dc8..daf6ef4597b4 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -5751,7 +5751,7 @@ def _make_agent( _pr = _load_provider_routing() return AIAgent( model=model, - max_iterations=_cfg_max_turns(cfg, 90), + max_iterations=_cfg_max_turns(cfg, 500), provider=runtime.get("provider"), base_url=runtime.get("base_url"), api_key=runtime.get("api_key"), @@ -17560,7 +17560,7 @@ def _(rid, params: dict) -> dict: { "title": "Agent", "rows": [ - ["Max Turns", str(_cfg_max_turns(cfg, 90))], + ["Max Turns", str(_cfg_max_turns(cfg, 500))], ["Toolsets", ", ".join(cfg.get("enabled_toolsets", [])) or "all"], ["Verbose", str(cfg.get("verbose", False))], ], diff --git a/website/docs/developer-guide/agent-loop.md b/website/docs/developer-guide/agent-loop.md index da904d2ef0ae..24cee51082df 100644 --- a/website/docs/developer-guide/agent-loop.md +++ b/website/docs/developer-guide/agent-loop.md @@ -181,7 +181,7 @@ These tools modify agent state directly and return synthetic tool results withou The agent tracks iterations via `IterationBudget`: -- Default: 90 iterations (configurable via `agent.max_turns`) +- Default: 500 iterations (configurable via `agent.max_turns`) - Each agent gets its own budget. Subagents get independent budgets capped at `delegation.max_iterations` (default 50) — total iterations across parent + subagents can exceed the parent's cap - At 100%, the agent stops and returns a summary of work done diff --git a/website/docs/guides/python-library.md b/website/docs/guides/python-library.md index 24d1aecc95e4..1fb0387400e1 100644 --- a/website/docs/guides/python-library.md +++ b/website/docs/guides/python-library.md @@ -309,7 +309,7 @@ print(review) | `disabled_toolsets` | `List[str]` | `None` | Blacklist specific toolsets | | `save_trajectories` | `bool` | `False` | Save conversations to JSONL | | `ephemeral_system_prompt` | `str` | `None` | Custom system prompt (not saved to trajectories) | -| `max_iterations` | `int` | `90` | Max tool-calling iterations per conversation | +| `max_iterations` | `int` | `500` | Max tool-calling iterations per conversation | | `skip_context_files` | `bool` | `False` | Skip loading AGENTS.md files | | `skip_memory` | `bool` | `False` | Disable persistent memory read/write | | `api_key` | `str` | `None` | API key (falls back to env vars) | @@ -329,5 +329,5 @@ print(review) :::warning - **Thread safety**: Create one `AIAgent` per thread or task. Never share an instance across concurrent calls. - **Resource cleanup**: The agent automatically cleans up resources (terminal sessions, browser instances) when a conversation ends. If you're running in a long-lived process, ensure each conversation completes normally. -- **Iteration limits**: The default `max_iterations=90` is generous. For simple Q&A use cases, consider lowering it (e.g., `max_iterations=10`) to prevent runaway tool-calling loops and control costs. +- **Iteration limits**: The default `max_iterations=500` is generous. For simple Q&A use cases, consider lowering it (e.g., `max_iterations=10`) to prevent runaway tool-calling loops and control costs. ::: diff --git a/website/docs/reference/cli-commands.md b/website/docs/reference/cli-commands.md index cdf16ad1c246..727dd8b57592 100644 --- a/website/docs/reference/cli-commands.md +++ b/website/docs/reference/cli-commands.md @@ -120,7 +120,7 @@ Common options: | `--ignore-rules` | Skip auto-injection of `AGENTS.md`, `SOUL.md`, `.cursorrules`, persistent memory, and preloaded skills. Combine with `--ignore-user-config` for a fully isolated run. | | `--safe-mode` | Troubleshooting mode: disable ALL customizations — user config, rules/memory injection, plugins, shell hooks, and MCP servers (implies `--ignore-user-config` and `--ignore-rules`). Use to isolate whether a problem comes from your setup or from Hermes itself. | | `--source ` | Session source tag for filtering (default: `cli`). Use `tool` for third-party integrations that should not appear in user session lists. | -| `--max-turns ` | Maximum tool-calling iterations per conversation turn (default: 90, or `agent.max_turns` in config). | +| `--max-turns ` | Maximum tool-calling iterations per conversation turn (default: 500, or `agent.max_turns` in config). | Examples: diff --git a/website/docs/reference/environment-variables.md b/website/docs/reference/environment-variables.md index 9473ac605c41..362652974035 100644 --- a/website/docs/reference/environment-variables.md +++ b/website/docs/reference/environment-variables.md @@ -733,7 +733,7 @@ Advanced per-platform knobs for throttling the outbound message batcher. Most us | Variable | Description | |----------|-------------| -| `HERMES_MAX_ITERATIONS` | Max tool-calling iterations per conversation (default: 90) | +| `HERMES_MAX_ITERATIONS` | Max tool-calling iterations per conversation (default: 500) | | `HERMES_INFERENCE_MODEL` | Override model name at process level (takes priority over `config.yaml` for the session). Also settable via `-m`/`--model` flag. | | `HERMES_YOLO_MODE` | Set to `1` to bypass dangerous-command approval prompts. Equivalent to `--yolo`. | | `HERMES_ACCEPT_HOOKS` | Auto-approve any unseen shell hooks declared in `config.yaml` without a TTY prompt. Equivalent to `--accept-hooks` or `hooks_auto_accept: true`. | diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index 96ce47b7f6b2..0d37503c4954 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -854,13 +854,13 @@ See [Memory Providers](/user-guide/features/memory-providers) for the analogous ## Iteration Budget -When the agent is working on a complex task with many tool calls, it can burn through its iteration budget (default: 90 turns). Hermes does **not** inject mid-task pressure warnings — earlier builds warned the model at 70%/90% budget, which caused models to abandon complex tasks prematurely and was removed in April 2026. +When the agent is working on a complex task with many tool calls, it can burn through its iteration budget (default: 500 turns). Hermes does **not** inject mid-task pressure warnings — earlier builds warned the model at 70%/90% budget, which caused models to abandon complex tasks prematurely and was removed in April 2026. -Instead, when the budget is actually exhausted (90/90), Hermes injects one message asking the model to wrap up and allows a single **grace call** so it can deliver a final response. If that grace call still doesn't produce text, the agent is asked to summarise what it accomplished. +Instead, when the budget is actually exhausted (500/500), Hermes injects one message asking the model to wrap up and allows a single **grace call** so it can deliver a final response. If that grace call still doesn't produce text, the agent is asked to summarise what it accomplished. ```yaml agent: - max_turns: 90 # Max iterations per conversation turn (default: 90) + max_turns: 500 # Max iterations per conversation turn (default: 500) api_max_retries: 3 # Retries per provider before fallback engages (default: 3) ``` diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/agent-loop.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/agent-loop.md index a3f168389131..23e8065e9edf 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/agent-loop.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/agent-loop.md @@ -181,7 +181,7 @@ for each tool_call in response.tool_calls: agent 通过 `IterationBudget` 追踪迭代次数: -- 默认:90 次迭代(可通过 `agent.max_turns` 配置) +- 默认:500 次迭代(可通过 `agent.max_turns` 配置) - 每个 agent 拥有独立预算。子 agent 获得独立预算,上限为 `delegation.max_iterations`(默认 50)——父 agent 与子 agent 的总迭代次数可超过父 agent 的上限 - 达到 100% 时,agent 停止并返回已完成工作的摘要 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/python-library.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/python-library.md index 59493c66fce6..e25e7c5007b0 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/python-library.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guides/python-library.md @@ -309,7 +309,7 @@ print(review) | `disabled_toolsets` | `List[str]` | `None` | 黑名单指定工具集 | | `save_trajectories` | `bool` | `False` | 将对话保存为 JSONL | | `ephemeral_system_prompt` | `str` | `None` | 自定义系统 prompt(不保存到轨迹文件) | -| `max_iterations` | `int` | `90` | 每次对话的最大工具调用迭代次数 | +| `max_iterations` | `int` | `500` | 每次对话的最大工具调用迭代次数 | | `skip_context_files` | `bool` | `False` | 跳过加载 AGENTS.md 文件 | | `skip_memory` | `bool` | `False` | 禁用持久化内存的读写 | | `api_key` | `str` | `None` | API 密钥(回退到环境变量) | @@ -329,5 +329,5 @@ print(review) :::warning - **线程安全**:每个线程或任务创建一个 `AIAgent` 实例。切勿在并发调用中共享同一实例。 - **资源清理**:agent 在对话结束时会自动清理资源(终端会话、浏览器实例)。若在长期运行的进程中使用,请确保每次对话正常结束。 -- **迭代限制**:默认的 `max_iterations=90` 较为宽松。对于简单的问答场景,建议适当降低该值(如 `max_iterations=10`),以防止工具调用循环失控并控制成本。 +- **迭代限制**:默认的 `max_iterations=500` 较为宽松。对于简单的问答场景,建议适当降低该值(如 `max_iterations=10`),以防止工具调用循环失控并控制成本。 ::: \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli-commands.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli-commands.md index d4ef1885a6eb..cd0353bb41a3 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli-commands.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli-commands.md @@ -108,7 +108,7 @@ hermes chat [options] | `--ignore-user-config` | 忽略 `~/.hermes/config.yaml`,使用内置默认值。`.env` 中的凭据仍会加载。适用于隔离的 CI 运行、可复现的 bug 报告和第三方集成。 | | `--ignore-rules` | 跳过 `AGENTS.md`、`SOUL.md`、`.cursorrules`、持久 memory 和预加载 skill 的自动注入。与 `--ignore-user-config` 组合可实现完全隔离的运行。 | | `--source ` | 用于过滤的会话来源标签(默认:`cli`)。对于不应出现在用户会话列表中的第三方集成,使用 `tool`。 | -| `--max-turns ` | 每个对话轮次的最大工具调用迭代次数(默认:90,或 config 中的 `agent.max_turns`)。 | +| `--max-turns ` | 每个对话轮次的最大工具调用迭代次数(默认:500,或 config 中的 `agent.max_turns`)。 | 示例: diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/environment-variables.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/environment-variables.md index 4b15a846f147..99914065ea30 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/environment-variables.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/environment-variables.md @@ -526,7 +526,7 @@ Graph 事件(Teams 会议、日历、聊天等)的入站变更通知监听 | 变量 | 描述 | |----------|-------------| -| `HERMES_MAX_ITERATIONS` | 每次对话的最大工具调用迭代次数(默认:90) | +| `HERMES_MAX_ITERATIONS` | 每次对话的最大工具调用迭代次数(默认:500) | | `HERMES_INFERENCE_MODEL` | 在进程级别覆盖模型名称(优先于本次会话的 `config.yaml`)。也可通过 `-m`/`--model` 标志设置。 | | `HERMES_YOLO_MODE` | 设为 `1` 可绕过危险命令审批提示。等同于 `--yolo`。 | | `HERMES_ACCEPT_HOOKS` | 无需 TTY 提示自动批准 `config.yaml` 中声明的任何未见过的 shell hook。等同于 `--accept-hooks` 或 `hooks_auto_accept: true`。 | diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md index 6d4c7c14f6d1..a092445e65c0 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/configuration.md @@ -637,17 +637,17 @@ context: ## 迭代预算 -当 agent 在处理具有许多工具调用的复杂任务时,它可能会耗尽其迭代预算(默认:90 轮)。Hermes **不会**在任务中途注入压力警告 —— 早期版本会在预算达到 70%/90% 时警告模型,这会导致模型过早放弃复杂任务,该机制已于 2026 年 4 月移除。 +当 agent 在处理具有许多工具调用的复杂任务时,它可能会耗尽其迭代预算(默认:500 轮)。Hermes **不会**在任务中途注入压力警告 —— 早期版本会在预算达到 70%/90% 时警告模型,这会导致模型过早放弃复杂任务,该机制已于 2026 年 4 月移除。 -取而代之的是,当预算真正耗尽(90/90)时,Hermes 注入一条消息要求模型收尾,并允许一次**宽限调用**以便其给出最终响应。如果该宽限调用仍未产生文本,则会要求 agent 总结已完成的工作。 +取而代之的是,当预算真正耗尽(500/500)时,Hermes 注入一条消息要求模型收尾,并允许一次**宽限调用**以便其给出最终响应。如果该宽限调用仍未产生文本,则会要求 agent 总结已完成的工作。 ```yaml agent: - max_turns: 90 # 每次对话轮次的最大迭代次数(默认:90) + max_turns: 500 # 每次对话轮次的最大迭代次数(默认:500) api_max_retries: 3 # 回退启动前每个 provider 的重试次数(默认:3) ``` -当迭代预算完全耗尽时,CLI 向用户显示通知:`⚠ Iteration budget reached (90/90) — response may be incomplete`。 +当迭代预算完全耗尽时,CLI 向用户显示通知:`⚠ Iteration budget reached (500/500) — response may be incomplete`。 `agent.api_max_retries` 控制 Hermes 在回退 provider 切换启动**之前**对瞬时错误(速率限制、连接断开、5xx)重试 provider API 调用的次数。默认为 `3` —— 总共四次尝试。如果您配置了[回退 providers](/user-guide/features/fallback-providers) 并希望更快地故障转移,请将其降至 `0`,这样主 provider 上的第一个瞬时错误会立即切换到回退,而不是对不稳定的端点进行重试。