docs: complete all English and Chinese documentation pages

Agent-Logs-Url: https://github.com/bytedance/deer-flow/sessions/a5f192e7-8034-4e46-af22-60b90ee27d40

Co-authored-by: foreleven <4785594+foreleven@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-11 05:37:06 +00:00
committed by JeffJiang
parent 716cae20c6
commit 814a488bcb
54 changed files with 4890 additions and 37 deletions
@@ -1,3 +1,170 @@
import { Callout, Cards } from "nextra/components";
# Customization
TBD
<Callout type="info" emoji="🔧">
DeerFlow is designed to be adapted. You can extend agent behavior by writing
custom middlewares, adding new tools, building skill packs, and replacing any
built-in component through the config.yaml <code>use:</code> field.
</Callout>
DeerFlow's pluggable architecture means most parts of the system can be replaced or extended without forking the core. This page maps the extension points and explains how to use each one.
## Custom middlewares
Middlewares are the primary extension point for adding behavior to the Lead Agent. They wrap every LLM turn and can read and modify the agent's state before or after the model call.
To add a custom middleware:
1. Implement the `AgentMiddleware` interface from `langchain.agents.middleware`.
2. Pass your middleware to the `custom_middlewares` parameter when building the agent.
```python
from langchain.agents.middleware import AgentMiddleware
from deerflow.agents.thread_state import ThreadState
class AuditMiddleware(AgentMiddleware):
async def on_start(self, state: ThreadState, config):
# Runs before each model call
print(f"[audit] turn starts: {len(state.messages)} messages in context")
return state, config
async def on_end(self, state: ThreadState, config):
# Runs after each model call
print(f"[audit] turn ends: last message type = {state.messages[-1].type}")
return state, config
```
Custom middlewares are injected into the chain immediately before `ClarificationMiddleware`, which always runs last.
## Custom tools
Add new tools to the agent by registering them in `config.yaml` under `tools:`:
```yaml
tools:
- use: mypackage.tools:my_custom_tool
api_key: $MY_TOOL_API_KEY
```
Your tool must be a LangChain `BaseTool` or a function decorated with `@tool`. It will be instantiated using the `use:` class path and any additional fields from the config entry.
For community-style tools, the pattern is a module-level function or class that returns a `BaseTool`:
```python
# mypackage/tools.py
from langchain_core.tools import tool
@tool
def my_custom_tool(query: str) -> str:
"""Search my custom data source."""
return do_search(query)
```
## Custom sandbox provider
The sandbox can be replaced by implementing the `SandboxProvider` interface:
```python
from deerflow.sandbox.sandbox_provider import SandboxProvider
from deerflow.sandbox.sandbox import Sandbox
class MyCustomSandboxProvider(SandboxProvider):
def acquire(self, thread_id: str | None = None) -> str:
# Return a sandbox_id
...
def get(self, sandbox_id: str) -> Sandbox | None:
# Return the sandbox instance for this id
...
def release(self, sandbox_id: str) -> None:
# Cleanup
...
```
Then reference it in `config.yaml`:
```yaml
sandbox:
use: mypackage.sandbox:MyCustomSandboxProvider
```
## Custom memory storage
Replace the file-based memory with any persistent store by implementing `MemoryStorage`:
```python
from deerflow.agents.memory.storage import MemoryStorage
from typing import Any
class RedisMemoryStorage(MemoryStorage):
def load(self, agent_name: str | None = None) -> dict[str, Any]:
...
def reload(self, agent_name: str | None = None) -> dict[str, Any]:
...
def save(self, memory_data: dict[str, Any], agent_name: str | None = None) -> bool:
...
```
Configure it in `config.yaml`:
```yaml
memory:
storage_class: mypackage.storage:RedisMemoryStorage
```
## Custom skills
Skills are the easiest extension point. Create a directory under `skills/custom/your-skill-name/` with a `SKILL.md` file. The skill is discovered automatically on the next `load_skills()` call.
See [Skills](/docs/harness/skills) for the full directory structure and `SKILL.md` format.
## Custom models
Any LangChain-compatible chat model can be used by specifying it in the `use:` field:
```yaml
models:
- name: my-custom-model
use: mypackage.models:MyCustomChatModel
# Any extra fields are passed as kwargs to the constructor
base_url: http://my-model-server:8080
api_key: $MY_MODEL_API_KEY
```
The model class must implement the LangChain `BaseChatModel` interface.
## Custom checkpointer
Thread state persistence can use any LangGraph-compatible checkpointer:
```yaml
checkpointer:
type: sqlite
connection_string: ./my-checkpoints.db
```
For custom backends, implement the LangGraph `BaseCheckpointSaver` interface and configure it programmatically when initializing the `DeerFlowClient`.
## Guardrails
Add pre-execution authorization for tool calls through the `guardrails:` config:
```yaml
guardrails:
enabled: true
provider:
use: deerflow.guardrails.builtin:AllowlistProvider
config:
denied_tools: ["bash", "write_file"]
```
For custom guardrail logic, implement a class with `evaluate()` and `aevaluate()` methods and reference it via `use:`.
<Cards num={2}>
<Cards.Card title="Integration Guide" href="/docs/harness/integration-guide" />
<Cards.Card title="Configuration" href="/docs/harness/configuration" />
</Cards>
@@ -1,3 +1,175 @@
import { Callout, Cards } from "nextra/components";
# Integration Guide
TBD
<Callout type="info" emoji="🔌">
DeerFlow Harness can be embedded into any Python application. This guide
covers the integration patterns for using DeerFlow as a library inside your
own system.
</Callout>
DeerFlow Harness is not only a standalone application. It is a Python library you can import and use inside your own backend, API server, automation system, or multi-agent orchestrator.
## Embedding DeerFlowClient
The primary integration point is `DeerFlowClient`. It wraps the LangGraph runtime and exposes a clean API for sending messages and streaming responses from any Python application.
```python
from deerflow.client import DeerFlowClient
from deerflow.config import load_config
# Load configuration (reads config.yaml or DEER_FLOW_CONFIG_PATH)
load_config()
client = DeerFlowClient()
```
The client is thread-safe and designed to be instantiated once and reused across requests.
## Async streaming
The recommended integration pattern is async streaming. This gives you real-time access to each token and event as the agent produces it:
```python
import asyncio
async def run_agent(thread_id: str, user_message: str):
async for event in client.astream(
thread_id=thread_id,
message=user_message,
config={
"configurable": {
"model_name": "gpt-4o",
"subagent_enabled": True,
}
},
):
# Process each streaming event
yield event
# In a FastAPI handler:
# from fastapi.responses import StreamingResponse
# return StreamingResponse(run_agent(thread_id, message), media_type="text/event-stream")
```
## Non-streaming invocation
For batch processing or when you only need the final result:
```python
async def run_agent_sync(thread_id: str, user_message: str) -> dict:
result = await client.ainvoke(
thread_id=thread_id,
message=user_message,
)
return result
```
## Thread management
Threads represent persistent conversations. Use unique thread IDs to isolate different user sessions:
```python
import uuid
# New conversation
thread_id = str(uuid.uuid4())
# Continuing an existing conversation (same thread_id)
# The agent will see the full history if a checkpointer is configured
await client.ainvoke(thread_id=existing_thread_id, message="Follow up question")
```
## Custom per-agent configuration
Build domain-specific agents by creating named agent configs and passing the `agent_name` at runtime:
```python
# agents/research-assistant/config.yaml must exist with skills and tool config
result = await client.ainvoke(
thread_id=thread_id,
message=user_message,
config={
"configurable": {
"agent_name": "research-assistant",
"model_name": "gpt-4o",
}
},
)
```
## Integrating with FastAPI
DeerFlow Gateway is itself a FastAPI application. You can mount it as a sub-application or router:
```python
from fastapi import FastAPI
from deerflow.config import load_config
load_config()
app = FastAPI()
# Mount the DeerFlow gateway router
from deerflow.app.gateway.main import app as gateway_app
app.mount("/deerflow", gateway_app)
```
Or use `DeerFlowClient` directly in your own FastAPI routes with streaming:
```python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from deerflow.client import DeerFlowClient
app = FastAPI()
client = DeerFlowClient()
@app.post("/chat/{thread_id}")
async def chat(thread_id: str, body: dict):
async def generate():
async for event in client.astream(thread_id=thread_id, message=body["message"]):
yield f"data: {event}\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
```
## Integrating with LangGraph
DeerFlow Harness is built on LangGraph. The Lead Agent is a standard LangGraph graph. You can compose it with your own LangGraph nodes and graphs:
```python
from deerflow.agents.lead_agent.agent import make_lead_agent
from langgraph.graph import StateGraph
# Access the underlying LangGraph agent factory
agent = make_lead_agent(config)
```
## Configuration in embedded mode
When embedded in another application, set the config path explicitly to avoid ambiguity:
```python
import os
os.environ["DEER_FLOW_CONFIG_PATH"] = "/path/to/my-deerflow-config.yaml"
from deerflow.config import load_config
load_config()
```
Or pass the path directly:
```python
from deerflow.config import load_config
load_config(config_path="/path/to/my-deerflow-config.yaml")
```
## MCP server integration
DeerFlow can expose its agent as an MCP server, allowing other MCP-compatible systems to call it as a tool. Refer to the DeerFlow repository for MCP server integration examples.
<Cards num={2}>
<Cards.Card title="Customization" href="/docs/harness/customization" />
<Cards.Card title="Configuration" href="/docs/harness/configuration" />
</Cards>
+153 -1
View File
@@ -1,3 +1,155 @@
import { Callout, Cards, Steps } from "nextra/components";
# Quick Start
TBD
<Callout type="info" emoji="🚀">
This guide shows you how to use the DeerFlow Harness programmatically — not
through the App UI, but by importing and calling the harness directly in
Python.
</Callout>
The DeerFlow Harness is the Python SDK and runtime foundation. This quick start walks you through the key APIs for running an agent, streaming its output, and working with threads.
## Prerequisites
DeerFlow Harness requires Python 3.12 or later. The package is part of the `deerflow` repository under `backend/packages/harness`.
If you are working from the repository clone:
```bash
cd backend
uv sync
```
## Configuration
All harness behaviors are driven by `config.yaml`. At minimum, you need at least one model configured:
```yaml
# config.yaml
config_version: 6
models:
- name: gpt-4o
use: langchain_openai:ChatOpenAI
model: gpt-4o
api_key: $OPENAI_API_KEY
request_timeout: 600.0
max_retries: 2
sandbox:
use: deerflow.sandbox.local:LocalSandboxProvider
tools:
- use: deerflow.community.ddg_search.tools:web_search_tool
- use: deerflow.community.jina_ai.tools:web_fetch_tool
- use: deerflow.sandbox.tools:ls_tool
- use: deerflow.sandbox.tools:read_file_tool
- use: deerflow.sandbox.tools:write_file_tool
- use: deerflow.sandbox.tools:bash_tool
```
Copy `config.example.yaml` to `config.yaml` and fill in your API key.
## Running the harness
The primary entry point for the DeerFlow Harness is `DeerFlowClient`. It manages thread state, invokes the Lead Agent, and streams the response.
<Steps>
### Import and configure
```python
import asyncio
from deerflow.client import DeerFlowClient
from deerflow.config import load_config
# Load config.yaml from the current directory or DEER_FLOW_CONFIG_PATH
load_config()
client = DeerFlowClient()
```
### Create a thread
```python
thread_id = "my-thread-001"
```
Thread IDs are arbitrary strings. Reusing the same ID continues the existing conversation (if a checkpointer is configured).
### Send a message and stream the response
```python
async def run():
async for event in client.astream(
thread_id=thread_id,
message="Research the top 3 open-source LLM frameworks and summarize them.",
config={
"configurable": {
"model_name": "gpt-4o",
"thinking_enabled": False,
"is_plan_mode": True,
"subagent_enabled": True,
}
},
):
print(event)
asyncio.run(run())
```
</Steps>
## Configurable options
The `config.configurable` dict controls per-request behavior:
| Key | Type | Default | Description |
|---|---|---|---|
| `model_name` | `str \| None` | first model in config | Model to use for this request |
| `thinking_enabled` | `bool` | `True` | Enable extended thinking mode (if supported) |
| `reasoning_effort` | `str \| None` | `None` | Reasoning effort level (model-specific) |
| `is_plan_mode` | `bool` | `False` | Enable TodoList middleware for task tracking |
| `subagent_enabled` | `bool` | `False` | Allow the agent to delegate subtasks |
| `max_concurrent_subagents` | `int` | `3` | Maximum parallel subagent calls per turn |
| `agent_name` | `str \| None` | `None` | Name of a custom agent to load |
## Streaming event types
`client.astream()` yields events from the LangGraph runtime. The key event types are:
| Event type | Description |
|---|---|
| `messages` | Individual message chunks (text, thinking, tool calls) |
| `thread_state` | Thread state updates (title, artifacts, todo list) |
Message chunks contain the token stream as the agent generates its response.
## Working with a custom agent
If you have defined a custom agent, pass its `name` in the configurable:
```python
async for event in client.astream(
thread_id="thread-002",
message="Analyze the attached CSV and generate a summary chart.",
config={
"configurable": {
"agent_name": "data-analyst",
"subagent_enabled": True,
}
},
):
...
```
The custom agent's configuration (model, skills, tool groups) is loaded automatically from `agents/data-analyst/config.yaml`.
## Next steps
<Cards num={3}>
<Cards.Card title="Design Principles" href="/docs/harness/design-principles" />
<Cards.Card title="Lead Agent" href="/docs/harness/lead-agent" />
<Cards.Card title="Configuration" href="/docs/harness/configuration" />
</Cards>
@@ -1,3 +1,5 @@
import { Callout } from "nextra/components";
# API / Gateway Reference
<Callout type="info">
@@ -39,21 +41,13 @@ http://localhost:2026/api
### Threads and memory
| Method | Path | Description |
| -------- | ----------------------------- | -------------------------------------------------- |
| `GET` | `/api/threads` | List threads |
| `DELETE` | `/api/threads/{thread_id}` | Delete a thread |
| `GET` | `/api/memory` | Get global memory data (context + facts) |
| `DELETE` | `/api/memory` | Clear all memory data |
| `POST` | `/api/memory/reload` | Reload memory from storage file |
| `GET` | `/api/memory/facts` | (included in `/api/memory` response `facts` array) |
| `POST` | `/api/memory/facts` | Create a memory fact |
| `PATCH` | `/api/memory/facts/{fact_id}` | Update a memory fact |
| `DELETE` | `/api/memory/facts/{fact_id}` | Delete a memory fact |
| `GET` | `/api/memory/export` | Export memory data as JSON |
| `POST` | `/api/memory/import` | Import and overwrite memory data |
| `GET` | `/api/memory/config` | Get memory configuration |
| `GET` | `/api/memory/status` | Get memory config + data in one request |
| Method | Path | Description |
| -------- | -------------------------- | ------------------------- |
| `GET` | `/api/threads` | List threads |
| `DELETE` | `/api/threads/{thread_id}` | Delete a thread |
| `GET` | `/api/memory` | Get global memory |
| `GET` | `/api/memory/{agent_name}` | Get agent-specific memory |
| `DELETE` | `/api/memory` | Clear global memory |
### Extensions
@@ -1,3 +1,67 @@
import { Callout } from "nextra/components";
# Concepts Glossary
TBD
This glossary defines the core terms used throughout the DeerFlow documentation.
---
## Agent
In DeerFlow, an agent is the primary processing unit that receives user messages, decides what actions to take (tool calls or direct responses), and generates output. DeerFlow uses a two-tier architecture with a **Lead Agent** and **Subagents**.
## Artifact
A file produced by the agent — a report, chart, code file, or other deliverable. Artifacts are exposed via the `present_files` tool and persisted in the thread's user-data directory.
## Checkpoint
A persisted snapshot of thread state, saved after each agent turn. Checkpoints allow conversations to resume after server restarts and support state management for long-horizon tasks.
## Context Engineering
The practice of controlling what the agent sees, remembers, and ignores at each step — through summarization, scoped subagent contexts, and external file memory — to keep the agent effective over long-horizon tasks.
## Harness
An opinionated agent runtime that packages tool access, skill loading, sandbox execution, memory, subagent coordination, and context management — rather than just exposing abstractions.
## Lead Agent
The primary executor in each DeerFlow thread, responsible for planning, tool calls, and response generation. Built on LangGraph + LangChain Agent, augmented by the middleware chain.
## Long-horizon Agent
An agent that remains useful across a chain of actions — making plans, calling tools many times, managing intermediate files, and producing a final artifact — rather than producing only a single answer.
## Memory
Structured facts and user context that persists across independent conversation sessions, injected into the agent's system prompt in subsequent sessions.
## Middleware
A plugin that wraps every LLM call, able to read and modify agent state before and after the model invocation. DeerFlow uses middleware for memory, summarization, title generation, and other cross-cutting behaviors.
## MCP (Model Context Protocol)
An open standard for connecting language models to external tools and data sources. DeerFlow's MCP integration allows connection to any compatible tool server.
## Sandbox
The isolated execution environment where the agent performs file and command-based work. DeerFlow supports local (`LocalSandboxProvider`) and container-based (`AioSandboxProvider`) sandbox modes.
## Skill
A task-oriented capability pack containing structured instructions, workflows, and best practices, loaded into the agent's context on demand. Skills provide specialization without polluting the general agent context.
## Subagent
A focused worker that handles a delegated subtask, running with an isolated context that contains only the information needed to complete its assigned work.
## Thread
The complete encapsulation of a conversation and all its associated state — message history, artifacts, todo list, and checkpoint data.
## ThreadState
The LangGraph-managed state object in DeerFlow, containing `messages`, `artifacts`, `todo_list`, and runtime metadata.
@@ -1,3 +1,5 @@
import { Callout } from "nextra/components";
# Configuration Reference
This page is the complete reference for all top-level fields in `config.yaml`.
@@ -43,11 +45,8 @@ models:
base_url: null # Optional: custom endpoint URL
request_timeout: 600.0 # Request timeout in seconds
max_retries: 2 # Number of retries on failure
supports_vision: true # Whether the model accepts image inputs
supports_thinking: false # Whether the model supports extended thinking
# thinking: {} # Optional thinking config (passed when thinking is active)
# when_thinking_enabled: {} # Optional overrides applied when thinking is enabled
# when_thinking_disabled: {} # Optional overrides applied when thinking is disabled
supports_vision: true # Whether to enable vision capabilities
thinking_enabled: false # Whether to enable extended thinking
# Any additional fields are passed through to the model constructor
```
@@ -30,7 +30,7 @@ These options are passed via `config.configurable` (for programmatic use) or sel
Set in the model configuration in `config.yaml`:
| Flag | Type | Description |
| ------------------- | ------ | ------------------------------------- |
| `supports_vision` | `bool` | Model accepts image inputs |
| `supports_thinking` | `bool` | Model supports extended thinking mode |
| Flag | Type | Description |
| ------------------ | ------ | ------------------------------------- |
| `supports_vision` | `bool` | Model accepts image inputs |
| `thinking_enabled` | `bool` | Model supports extended thinking mode |
@@ -14,7 +14,7 @@ backend/
│ │ ├── memory.py # Memory read/clear
│ │ ├── threads.py # Thread management
│ │ └── uploads.py # File uploads
│ └── app.py # FastAPI app entry point (create_app())
│ └── main.py # FastAPI app entry point
└── packages/harness/deerflow/
├── agents/
@@ -85,4 +85,4 @@ frontend/src/
| Skill loading (hot reload) | `skills/loader.py` |
| MCP tool cache | `mcp/cache.py` |
| File upload handling | `uploads/manager.py` |
| Gateway app factory | `app/gateway/app.py` |
| Gateway main router | `app/gateway/main.py` |
@@ -1,3 +1,99 @@
import { Callout, Steps } from "nextra/components";
# Create Your First Harness
TBD
This tutorial shows you how to use the DeerFlow Harness programmatically — importing and using DeerFlow directly in your Python code rather than through the web interface.
## Prerequisites
- Python 3.12+
- `uv` installed
- DeerFlow repository cloned
## Install
```bash
cd deer-flow/backend
uv sync
```
## Create configuration
Create a minimal `config.yaml`:
```yaml
config_version: 6
models:
- name: gpt-4o
use: langchain_openai:ChatOpenAI
model: gpt-4o
api_key: $OPENAI_API_KEY
sandbox:
use: deerflow.sandbox.local:LocalSandboxProvider
tools:
- use: deerflow.community.ddg_search.tools:web_search_tool
- use: deerflow.sandbox.tools:read_file_tool
- use: deerflow.sandbox.tools:write_file_tool
```
## Write the code
<Steps>
### Create a Python file
Create `my_agent.py` in the `backend/` directory:
```python
import asyncio
import os
from deerflow.client import DeerFlowClient
from deerflow.config import load_config
os.environ["OPENAI_API_KEY"] = "sk-..."
# Load config.yaml
load_config()
client = DeerFlowClient()
async def main():
async for event in client.astream(
thread_id="my-first-thread",
message="Write a Python fibonacci function with a docstring",
config={
"configurable": {
"model_name": "gpt-4o",
}
},
):
print(event)
asyncio.run(main())
```
### Run it
```bash
cd backend
uv run python my_agent.py
```
</Steps>
## What the events look like
The stream yields events like:
```python
{"type": "messages", "data": {"content": "def fibonacci..."}}
{"type": "thread_state", "data": {"title": "Python Fibonacci Function"}}
```
## Next steps
- [Use Tools and Skills](/docs/tutorials/use-tools-and-skills)
- [Harness Quick Start](/docs/harness/quick-start)
@@ -1,3 +1,74 @@
import { Callout, Steps } from "nextra/components";
# Deploy Your Own DeerFlow
TBD
This tutorial guides you through deploying DeerFlow to a production environment using Docker Compose for multi-user access.
## Prerequisites
- Docker and Docker Compose installed
- A server or VM (Linux recommended)
- LLM API key
## Steps
<Steps>
### Clone the repository
```bash
git clone https://github.com/bytedance/deer-flow.git
cd deer-flow
```
### Create the configuration file
```bash
cp config.example.yaml config.yaml
```
Edit `config.yaml` to add your model configuration.
### Create the environment variables file
```bash
cat > .env << EOF
OPENAI_API_KEY=sk-your-key-here
DEER_FLOW_ROOT=$(pwd)
BETTER_AUTH_SECRET=$(openssl rand -base64 32)
BETTER_AUTH_URL=https://your-domain.com
EOF
```
### Start the services
```bash
docker compose -f docker/docker-compose-dev.yaml up -d
```
### Verify the deployment
```bash
# Check all services are healthy
curl http://localhost:2026/api/models
# Follow logs
docker compose -f docker/docker-compose-dev.yaml logs -f
```
Open `http://your-server:2026` in your browser.
</Steps>
## Production checklist
- Configure HTTPS/TLS for nginx
- Set `BETTER_AUTH_SECRET` to a strong random string (minimum 32 characters)
- Configure firewall rules to allow only necessary ports
- Back up `backend/.deer-flow/` directory regularly
- Consider using a container-based sandbox (`AioSandboxProvider`) for multi-user isolation
## Next steps
- [Full Deployment Guide](/docs/application/deployment-guide)
- [Operations and Troubleshooting](/docs/application/operations-and-troubleshooting)
@@ -1,3 +1,59 @@
import { Callout, Steps } from "nextra/components";
# First Conversation
TBD
This tutorial walks you through your first complete agent conversation in DeerFlow — from launching the app to getting meaningful work done with the agent.
## Prerequisites
- DeerFlow app is running (see [Quick Start](/docs/application/quick-start))
- At least one model is configured in `config.yaml`
## Steps
<Steps>
### Open the workspace
Open [http://localhost:2026](http://localhost:2026) in your browser. You will see the conversation workspace.
### Send your first message
Type a question in the input box, for example:
```
Research the top 3 most popular open-source LLM frameworks in 2024 and compare their strengths and weaknesses.
```
Press Enter to send.
### Watch the agent work
You will see the agent start working:
- Expand the **thinking steps** to see which tools it is calling
- Watch search results stream in
- Wait for the final report to be generated
### Interact with the result
Once the report is generated, you can:
- Ask for more detail on a specific section
- Ask to export the report as a file (the agent will use the `present_files` tool)
- Ask to create a chart based on the research findings
</Steps>
## What just happened
The agent used the DeerFlow Harness to:
1. Receive your message and add it to the thread state
2. Run the middleware chain (memory injection, title generation)
3. Call the LLM, which decided to search the web
4. Execute web search tool calls
5. Synthesize results into a structured response
6. Update the thread state with any artifacts produced
## Next steps
- [Use Tools and Skills](/docs/tutorials/use-tools-and-skills)
- [Workspace Usage](/docs/application/workspace-usage)
@@ -1,3 +1,59 @@
import { Callout } from "nextra/components";
# Use Tools and Skills
TBD
This tutorial shows you how to configure and use tools and skills in DeerFlow to give the agent access to web search, file operations, and domain-specific capabilities.
## Configuring tools
Add tools to `config.yaml`:
```yaml
tools:
# Web search
- use: deerflow.community.ddg_search.tools:web_search_tool
# Web content fetching
- use: deerflow.community.jina_ai.tools:web_fetch_tool
# Sandbox file operations
- use: deerflow.sandbox.tools:ls_tool
- use: deerflow.sandbox.tools:read_file_tool
- use: deerflow.sandbox.tools:write_file_tool
- use: deerflow.sandbox.tools:bash_tool
```
## Enabling skills
Enable skills through the DeerFlow app's extensions panel, or edit `extensions_config.json` directly.
**Via the app UI:**
1. Open the DeerFlow app
2. Click the Extensions/Skills icon in the sidebar
3. Find `deep-research` and toggle it on
## Using a skill for research
With the `deep-research` skill enabled, select it in the conversation input, then send a research request:
```
Do a deep research on the latest advances in quantum computing, focusing on practical applications.
```
The agent will run a multi-step research workflow including web search, information synthesis, and report generation.
## Using the data analysis skill
Enable `data-analysis`, then upload a CSV or data file and ask the agent to analyze it:
```
Analyze this CSV file and identify the top trends.
```
The agent will use the sandbox tools to read the file, run analysis, and produce charts.
## Next steps
- [Work with Memory](/docs/tutorials/work-with-memory)
- [Tools Reference](/docs/harness/tools)
- [Skills Reference](/docs/harness/skills)
@@ -1,3 +1,64 @@
import { Callout } from "nextra/components";
# Work with Memory
TBD
This tutorial shows you how to enable and use DeerFlow's memory system so the agent remembers important information about you across multiple sessions.
## Enable memory
In `config.yaml`:
```yaml
memory:
enabled: true
injection_enabled: true
max_injection_tokens: 2000
debounce_seconds: 30
```
## How memory works
Memory works automatically through `MemoryMiddleware`:
1. **First conversation**: tell the agent about your preferences, project, or background.
2. **Automatic learning**: the agent extracts and saves important facts in the background.
3. **Future conversations**: memory facts are automatically injected into the system prompt — the agent does not need you to repeat context.
## Example
**First conversation:**
```
I am a Python backend developer primarily using FastAPI and PostgreSQL.
My team follows PEP 8 and prefers type annotations everywhere.
Please remember this for future code suggestions.
```
**Later conversation** (no need to repeat background):
```
Help me write a user authentication module
```
The agent will automatically produce FastAPI-style code with type annotations.
## Inspect memory
Memory is stored in `backend/.deer-flow/memory.json`:
```bash
cat backend/.deer-flow/memory.json
```
## Per-agent memory
When a custom agent is active, it maintains its own memory file at:
```
backend/.deer-flow/agents/{agent_name}/memory.json
```
This keeps each agent's learned knowledge separate.
## Next steps
- [Deploy Your Own DeerFlow](/docs/tutorials/deploy-your-own-deerflow)
- [Memory System Reference](/docs/harness/memory)