How to Customize DeepTutor's Behavior: Complete Configuration Guide

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):

  • Tool Registry (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): 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) 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 and injects absolute runtime paths (e.g., user_data_dir, knowledge_bases_dir).

Key files include:

  • main.yaml: Controls system language, enabled tools, and core paths.
  • 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. 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:


# 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), affecting all UI string rendering.

Adjusting LLM Retry Behavior

Export these variables before starting DeepTutor to control resilience policies:

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, 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:


# 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) returns these overridden values instead of defaults.

Disabling Built-in Tools

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


# 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:

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

manifest.yaml:

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

capability.py:

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 files.

Selecting Capabilities

Built-in capabilities are mapped in deeptutor/runtime/bootstrap/builtin_capabilities.py. You can invoke specific capabilities via the CLI (deeptutor_cli/chat.py or deeptutor_cli/bot.py) or API by referencing these mapped names. The CLI argument parsing in 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:

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, this class provides thread-safe read/write access to 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 and 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, disable tools by pruning the enabled list, and control retry logic via environment variables.
  • Extension: Deploy plugins to deeptutor/plugins/ with a 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 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 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.

Where are the default configuration values defined?

Baseline defaults reside in 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 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, automatically registering your capability for use via CLI or API.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →