# How to Customize DeepTutor's Behavior: Complete Configuration Guide

> Customize DeepTutor's behavior using its dual-layer registry architecture. Modify tools, capabilities, and agent parameters via YAML files, environment variables, and plugins without touching source code.

- Repository: [✨Data Intelligence Lab@HKU✨/DeepTutor](https://github.com/HKUDS/DeepTutor)
- Tags: how-to-guide
- Published: 2026-04-08

---

**DeepTutor's behavior is controlled through a dual-layer registry architecture—combining YAML configuration files, environment variables, and a plugin system—allowing you to modify tools, capabilities, and agent parameters without altering core source code.**

DeepTutor (HKUDS/DeepTutor) implements a highly modular runtime where all customizable behavior flows through centralized registries and configuration loaders. By understanding how the **Tool Registry** and **Capability Registry** interact with the orchestration layer, you can adapt the system for specific workflows, languages, and computational requirements.

## Understanding the Dual-Layer Registry Architecture

DeepTutor organizes its extensibility through two singleton registries instantiated at startup by the Orchestrator ([`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py)):

- **Tool Registry** ([`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py)): Manages callable tools such as `rag`, `code_execution`, and `web_search`. It handles discovery, registration, and alias resolution via `ToolRegistry._resolve_request()`.
- **Capability Registry** ([`deeptutor/runtime/registry/capability_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/capability_registry.py)): Loads high-level capabilities like `chat`, `deep_solve`, and `deep_question` that orchestrate multiple tools. Plugin discovery occurs through `CapabilityRegistry.load_plugins()`.

Both registries are accessed via `get_tool_registry()` and `get_capability_registry()` respectively. They receive a **UnifiedContext** ([`deeptutor/core/context.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/context.py)) containing resolved configuration, user state, and runtime paths, which determines how each component behaves during execution.

## Configuration Methods: Files vs. Environment Variables

DeepTutor supports two primary customization vectors: static YAML configuration and dynamic environment variables.

### YAML Configuration Files

Runtime settings reside in `data/user/settings/` and are loaded by `deeptutor/services/config/loader.py::load_config_with_main()`. The loader merges user configurations with baseline defaults from [`deeptutor/config/defaults.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/defaults.py) and injects absolute runtime paths (e.g., `user_data_dir`, `knowledge_bases_dir`).

Key files include:

- [`main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/main.yaml): Controls system language, enabled tools, and core paths.
- [`agents.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/agents.yaml): Defines LLM hyperparameters (temperature, max_tokens) for specific capabilities.

### Environment Variables

For deployment-specific settings, DeepTutor uses `pydantic-settings` via [`deeptutor/config/settings.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/settings.py). Critical variables include:

- `LLM_RETRY__MAX_RETRIES`
- `LLM_RETRY__BASE_DELAY`
- `LLM_RETRY__EXPONENTIAL_BACKOFF`

These values override YAML settings and are consumed by the retry logic throughout the application.

## Practical Customization Examples

### Changing the System Language

To switch the interface language, modify the `system` section in your main configuration:

```yaml

# data/user/settings/main.yaml

system:
  language: en

```

The loader normalizes this value through `parse_language()` (lines 76-100 in [`deeptutor/services/config/loader.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/services/config/loader.py)), affecting all UI string rendering.

### Adjusting LLM Retry Behavior

Export these variables before starting DeepTutor to control resilience policies:

```bash
export LLM_RETRY__MAX_RETRIES=5
export LLM_RETRY__BASE_DELAY=2.0
export LLM_RETRY__EXPONENTIAL_BACKOFF=false

```

As implemented in [`deeptutor/config/settings.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/settings.py), these settings configure the `settings.retry` object used by all LLM clients.

### Modifying Agent Parameters

Override default LLM behavior for specific capabilities by editing the agents configuration:

```yaml

# data/user/settings/agents.yaml

capabilities:
  solve:
    temperature: 0.7
    max_tokens: 8192

```

When the orchestrator initializes the "solve" capability, `get_agent_params("solve")` (lines 203-260 in [`loader.py`](https://github.com/HKUDS/DeepTutor/blob/main/loader.py)) returns these overridden values instead of defaults.

### Disabling Built-in Tools

To remove tools from the registry, exclude them from the enabled list:

```yaml

# data/user/settings/main.yaml

tools:
  enabled: ["rag", "code_execution", "reason"]   # web_search omitted

```

Since `ToolRegistry._resolve_request()` only resolves registered tools, omitted entries become unavailable to all capabilities.

## Extending DeepTutor with Custom Plugins

For advanced customization, DeepTutor supports plugin-based capabilities through the `deeptutor/plugins/` directory.

### Plugin Structure

Create a folder with a manifest and implementation:

```text
deeptutor/plugins/my_plugin/
├─ manifest.yaml
└─ capability.py

```

**manifest.yaml:**

```yaml
name: my_plugin
description: "Demo plugin that echoes input"
stages: [echo]
tools_used: []

```

**capability.py:**

```python
from deeptutor.core.capability_protocol import BaseCapability, CapabilityManifest
from deeptutor.core.context import UnifiedContext
from deeptutor.core.stream_bus import StreamBus

class MyPlugin(BaseCapability):
    manifest = CapabilityManifest(
        name="my_plugin",
        description="Echoes the received message",
        stages=["echo"],
    )

    async def run(self, context: UnifiedContext, stream: StreamBus) -> None:
        async with stream.stage("echo", source=self.name):
            await stream.content("Hello from MyPlugin!", source=self.name)

```

During startup, `CapabilityRegistry.load_plugins()` automatically discovers valid plugins by scanning `deeptutor/plugins/` for folders containing [`manifest.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/manifest.yaml) files.

### Selecting Capabilities

Built-in capabilities are mapped in [`deeptutor/runtime/bootstrap/builtin_capabilities.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/bootstrap/builtin_capabilities.py). You can invoke specific capabilities via the CLI ([`deeptutor_cli/chat.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor_cli/chat.py) or [`deeptutor_cli/bot.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor_cli/bot.py)) or API by referencing these mapped names. The CLI argument parsing in [`deeptutor_cli/common.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor_cli/common.py) forwards your selection to the orchestrator.

## Programmatic Configuration Management

For runtime configuration changes without editing files directly, use the `ConfigManager` singleton:

```python
from deeptutor.utils.config_manager import ConfigManager

cfg_mgr = ConfigManager()
current = cfg_mgr.load_config()

# modify a value

current.setdefault("system", {})["language"] = "zh"
cfg_mgr.save_config(current)

```

Located in [`deeptutor/utils/config_manager.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/utils/config_manager.py), this class provides thread-safe read/write access to [`main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/main.yaml), allowing applications built on DeepTutor to offer dynamic settings interfaces.

## Summary

- **Architecture**: DeepTutor uses `ToolRegistry` and `CapabilityRegistry` singletons (available via `get_tool_registry()` and `get_capability_registry()`) to manage all executable components.
- **Configuration**: Modify [`data/user/settings/main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/data/user/settings/main.yaml) and [`agents.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/agents.yaml) for static settings, or use environment variables (`LLM_RETRY__*`) for deployment-specific options.
- **Customization Points**: Change language via `system.language`, adjust agent behavior through [`agents.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/agents.yaml), disable tools by pruning the `enabled` list, and control retry logic via environment variables.
- **Extension**: Deploy plugins to `deeptutor/plugins/` with a [`manifest.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/manifest.yaml) and `BaseCapability` subclass; the registry auto-discovers them on startup.
- **Programmatic Access**: Use `ConfigManager` to modify settings at runtime without raw file I/O.

## Frequently Asked Questions

### How do I disable the web search tool in DeepTutor?

Edit [`data/user/settings/main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/data/user/settings/main.yaml) and remove `web_search` from the `tools.enabled` list. Because `ToolRegistry._resolve_request()` only matches explicitly enabled tools, requests involving web search will fail gracefully with a resolution error, forcing capabilities to rely on remaining tools like `rag` or `code_execution`.

### Can I change DeepTutor's language without restarting the application?

For persistent changes, modify [`main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/main.yaml) and reload. For programmatic changes, use `ConfigManager` to update the configuration object and trigger a context refresh. However, some UI components may require a restart to reload cached string resources parsed by `parse_language()` in [`loader.py`](https://github.com/HKUDS/DeepTutor/blob/main/loader.py).

### Where are the default configuration values defined?

Baseline defaults reside in [`deeptutor/config/defaults.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/defaults.py). When `load_config_with_main()` executes, it merges these defaults with user-specific YAML files from `data/user/settings/`, with user values taking precedence. This ensures the system functions even when configuration files are partially missing.

### How do I add a completely new capability to DeepTutor?

Create a new folder under `deeptutor/plugins/` containing a [`manifest.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/manifest.yaml) describing the capability name and stages, plus a Python file implementing `BaseCapability` from `deeptutor.core.capability_protocol`. The `CapabilityRegistry.load_plugins()` method scans this directory during orchestrator initialization in [`deeptutor/app/facade.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/app/facade.py), automatically registering your capability for use via CLI or API.