tencent cloud

Tool Lazy Loading Override

Download
Focus Mode
Font Size
Last updated: 2026-09-30 18:15:50
AI-Translated & Reviewed

Overview

CodeBuddy Code supports temporarily changing the lazy loading state of tools by using the Defer(...) / NoDefer(...) modifiers while specifying the list of available tools, without modifying the global configuration. This document is a complete reference for this capability.
Note:
By default, whether a tool uses lazy loading is determined by the defer_loading field in the product defaults or MCP configuration (see MCP documentation - Lazy Loading for details). These are globally effective default settings. This feature allows you to temporarily adjust the behavior for a single session or a single custom agent without changing the default configuration.

1. Syntax Overview

In any "tool list" field that accepts tool names, add a modifier before the name of a regular tool:
Syntax
Description
Read
Standard tool. Whether to defer is determined by the global default.
Defer(Glob)
The session/agent forces Glob to use deferred loading (not directly included in the model's tool list, and discoverable through ToolSearch).
NoDefer(Bash)
The session/agent forces Bash to skip deferred loading (directly included in the model's tool list).
Defer(mcp__github__*)
Wildcard match that sets the entire group of MCP tools to deferred loading.
Defer(*)
Set all tools in the current list to deferred loading (extreme trimming).
Note:
* is the only supported wildcard character and matches any character sequence. Other characters (such as ? and []) are treated literally.

2. Available Channels

Modifiers can be used in the following three types of "tool list" fields:

2.1 CLI --tools Parameter

codebuddy --tools "Read,Defer(Glob),NoDefer(Bash)"
The tools field in ACP and SDK clients is equivalent to the CLI.

2.2 Custom Agent frontmatter

In the YAML frontmatter of .codebuddy/agents/*.md:
---
name: code-reader
description: A read-only code exploration agent
tools:
- Read
- Grep
- Defer(Glob) # Makes Glob use lazy loading and be discovered through ToolSearch when needed.
- NoDefer(Bash) # Forces Bash to not use lazy loading for this agent, even if lazy loading is enabled by default.
---

3. Where Modifiers Cannot Be Used

Modifiers apply only to "tool list" fields. The following "permission rule" fields do not accept modifiers:
--allowed-tools / settings.permissions.allow
--disallowed-tools / settings.permissions.deny
The matcher in the hooks configuration
# ✖ Error: An error is reported immediately.
codebuddy --allowed-tools "Defer(Glob)"
# Error: Defer(...) / NoDefer(...) modifiers belong in --tools, not in permission rule fields.

# ✔ Correct: Write them separately.
codebuddy --tools "...,Defer(Glob)" --allowed-tools "Glob(src/**)"
Reason: "Exposure policy" (whether to use lazy loading) and "behavior constraints" (parameter filtering) are two orthogonal concerns, and expressing them separately is clearer.

4. Priority and Merging

The final decision follows this priority order (from highest to lowest):
Priority
Source
Description
0a
NoDefer(X) matched at any layer
Force non-defer (regardless of what other sources say).
0b
Defer(X) matched at any layer
Force defer.
1
MCP tool-level tools[name].defer_loading
MCP static configuration
2
MCP server-level defer_loading
MCP static configuration
3
Environment variable CODEBUDDY_DEFER_TOOL_LOADING
Global switch
4
User setting settings.deferToolLoading
Global switch
5
Built-in default (CodeBuddy Code factory configuration)
Fallback

Key rules

NoDefer always takes precedence over Defer: Even if a custom agent writes Defer(X), after CLI --tools writes NoDefer(X), X still does not use lazy loading in this session, because the user's runtime declaration takes priority.
CLI and agent configuration participate equally: Modifiers from both sources take effect as a union, without any order of precedence. The final result is determined by the "NoDefer takes precedence" rule.
Duplicate names: When the same tool appears multiple times in the same field, the modifiers from the last occurrence take precedence (consistent with the semantics when --allowedTools has duplicates).

5. Automatic Attachment: ToolSearch and DeferExecuteTool

As long as at least one Defer(...) appears in the tool list, CodeBuddy Code automatically adds the following two tools (if they are not already in the list):
Tool
Function
ToolSearch
Enables the model to search for and discover lazily loaded tools.
DeferExecuteTool
Enables the model to actually call lazily loaded tools.
In other words, you can write it like this:
# Equivalent to codebuddy --tools "Bash,Read,Defer(Edit),ToolSearch,DeferExecuteTool"
codebuddy --tools "Bash,Read,Defer(Edit)"

Why Automatic Attachment?

Tools with lazy loading do not directly enter the model's tool list. The model must discover them through ToolSearch and invoke them through DeferExecuteTool. If either one is missing, Defer(...) means "the model can no longer use this tool". Automatic addition makes the most common usage intuitive.

Wildcard Guardrails: Defer(*) Does Not Sweep Itself

When you write Defer(*), theoretically "all tools" are lazy-loaded, including ToolSearch and DeferExecuteTool themselves, which makes the defer workflow ineffective. To avoid this "self-lockout", automatic addition also adds a NoDefer guardrail to these two tools:
codebuddy --tools "Defer(*)"
# Behavior is equivalent to:
# codebuddy --tools "*,ToolSearch,DeferExecuteTool" + NoDefer(ToolSearch),NoDefer(DeferExecuteTool)
The model can still see and use ToolSearch / DeferExecuteTool, so it can search for and invoke other tools that are lazy-loaded.

Scenarios Where Automatic Attachment Is Not Triggered

If the tool list contains only NoDefer(...) and no Defer(...): the user's intent is to bring the tool back to direct invocation, unrelated to the defer workflow.
If there are no modifiers in the tool list: keep the original behavior.
If the user has explicitly listed ToolSearch or DeferExecuteTool: idempotent, do not add them again.

6. Typical Use Cases

6.1 Temporarily Deferring Tools to Save Tokens

# Knowing that only Read/Edit will be used this time, temporarily put away other large tools.
codebuddy --tools "Read,Edit,Defer(Bash),Defer(Glob),Defer(Grep)"
Only Read, Edit, and ToolSearch are visible in the model context. When needed, other tools can be invoked through ToolSearch.

6.2 Temporarily Forcing Deferred Tools to Be Directly Available

# Assume Bash is configured for lazy loading by default, but it needs to be directly callable this time.
codebuddy --tools "default,NoDefer(Bash)"
Note:
default means "all built-in tools" and can be used together with modifiers.

6.3 Fine-Grained Exposure Policies for Custom Agents

---
name: explorer
description: A specialized agent for exploring large repositories that puts away search tools to reduce distractions.
tools:
- Read
- Edit
- ToolSearch
- Defer(Glob)
- Defer(Grep)
- Defer(LSP)
---

6.4 Exposing MCP Tool Groups on Demand

codebuddy --tools "default,Defer(mcp__github__*)"
Put all tools from the GitHub MCP server into lazy loading. When needed, the model can find them by searching for keywords such as github pr and github issue through ToolSearch.

7. Troubleshooting

7.1 Syntax Errors

Error: Invalid --tools value: Invalid tool spec "Defer(Read(*.md))": Defer(...) only accepts a tool name or glob; permission filters like Read(*.md) belong in --allowed-tools, not --tools.
Move parameter filtering to --allowed-tools:
codebuddy --tools "Defer(Read)" --allowed-tools "Read(*.md)"

7.2 Modifiers Placed in the Wrong Field

Error: Invalid permission rule "Defer(Glob)" in --allowed-tools / settings.permissions.allow: Defer(...) / NoDefer(...) modifiers belong in --tools, not in permission rule fields.

7.3 Nesting / Empty Content

Defer(NoDefer(X)): Nested modifiers are rejected and have no meaningful semantics.
Defer(): Empty content is rejected.
defer(Read): Lowercase is not recognized and is rejected as a literal "tool name containing parentheses".

7.4 Spelling Errors in Custom Agents

The tools field in custom agent frontmatter uses lenient validation: a single invalid entry only produces a warning log and is then ignored, without causing CodeBuddy Code to fail to start. Look for prompts similar to the following in the logs to locate the issue:
[AgentToolSpec] my-agent: invalid-pattern — Invalid tool spec "Defer(Read(*.md))": ...
The --tools input directly from CLI and ACP clients is strictly validated, and invalid syntax causes an immediate error.

8. Collaboration with Permission Rules

Modifiers are completely orthogonal to --allowed-tools and can be used together:
codebuddy \\
--tools "Read,Write,Defer(Glob)" \\
--allowed-tools "Glob(src/**)"
Meaning:
Glob uses lazy loading and does not directly enter the model's tool list.
When the model invokes Glob through ToolSearch > DeferExecuteTool, it is still subject to the Glob(src/**) permission constraint.
Calling Glob(/etc/*) is rejected according to permission rules.

9. Interaction with ToolSearch / DeferExecuteTool

Modifiers directly affect the behavior of these two tools:
Modifier
Impact on ToolSearch
Impact on DeferExecuteTool
Defer(X) (X is not originally deferred)
Automatically joins the searchable deferred tool set upon first access.
Automatically register and allow upon first call.
NoDefer(X) (X is originally deferred)
Does not appear in search results (X has been directly added to the model's tool list and does not need to be searched for).
Returns an error when X is called, guiding direct invocation.
Error example (NoDefer path):
Error: Tool "Bash" is not deferred in this session (NoDefer modifier). Call it directly instead of via DeferExecuteTool.

10. Known Limitations

MCP server overall name: It is not currently supported to directly use a server name as a modification target in --tools. You can only specify tool names or wildcards (such as Defer(mcp__github__*)).
Wildcard reverse enumeration: Wildcard entries such as Defer(mcp__*) cannot be reverse-enumerated into specific tool names. The lazy indexing of MCP tools still relies on the asynchronous driving process of mcp-server-manager itself.

Help and Support

Was this page helpful?

Help us improve! Rate your documentation experience in 5 mins.

Feedback