How to Contribute to the Qwen-Agent Project: A Developer’s Guide
To contribute to the Qwen-Agent project, fork the repository, install full optional dependencies with pip install -U "qwen-agent[gui,rag,code_interpreter,mcp]", and submit a pull request that follows the four-layer architecture by subclassing BaseTool with the @register_tool decorator or extending FnCallAgent, while ensuring all changes pass the pytest suite.
Qwen-Agent is a modular framework for building LLM-driven applications with tool use, planning, and memory. To contribute to the Qwen-Agent project effectively, you must understand its layered architecture and follow the established Git workflow for adding tools, agents, or documentation.
Understand the Four-Layer Architecture
Qwen-Agent separates concerns into four distinct layers. Understanding these boundaries ensures your contributions integrate cleanly with the existing codebase.
| Layer | Purpose | Key Source |
|---|---|---|
| LLM Integration | Provides abstract chat model classes (BaseChatModel) and concrete implementations for DashScope, OpenAI-compatible services, and OpenVINO. |
qwen_agent/llm/base.py |
| Tools | Define reusable utilities (web search, code interpreter, vector search) that the LLM can call. Tools are registered with the global TOOL_REGISTRY via the @register_tool decorator. | qwen_agent/tools/base.py |
| Memory / Retrieval | Handles on-the-fly knowledge extraction from uploaded files or external sources, exposing a mem.run() API used by agents. |
qwen_agent/memory/memory.py |
| Agents | High-level orchestration components that combine LLMs, tools, and memory to perform complete tasks. The most common entry point is the Assistant class, built on top of the function-calling base agent. | qwen_agent/agents/assistant.py |
Set Up Your Development Environment
Follow these steps to prepare a local workspace that can exercise all modules, including the GUI, RAG, and code interpreter components.
- Fork and clone the repository to your GitHub account.
git clone https://github.com/<your-username>/Qwen-Agent.git
cd Qwen-Agent
- Install dependencies with all optional extras to ensure you can run the full test matrix locally.
pip install -U "qwen-agent[gui,rag,code_interpreter,mcp]"
- Run the test suite with
pytestto verify that the existing code passes before you begin modifications.
pytest -q
Implement New Features
Create a feature branch using conventional naming (feat/<description> or fix/<description>), then implement your changes according to the layer you are extending.
Adding Custom Tools
Subclass BaseTool (or BaseToolWithFileAccess when file I/O is required) and decorate the class with @register_tool('<your-tool-name>'). Implement the call method and optionally override file_access. The built-in example in qwen_agent/tools/web_search.py demonstrates how to perform external HTTP queries within this contract.
Extending Agents
Inherit from FnCallAgent or Agent and implement _run or other lifecycle hooks. The Assistant class in qwen_agent/agents/assistant.py shows how to inject RAG knowledge and delegate to the generic function-calling loop defined in qwen_agent/agents/fncall_agent.py.
Updating Documentation
Modify README.md, update the online docs under qwen-agent-docs/, and add usage examples to the examples/ folder, such as assistant_rag.py or assistant_qwen3.py.
Validate and Submit Your Changes
Before opening a pull request, ensure your code meets the repository’s quality standards.
- Lint and type-check using
rufforblack(if configured) andmypyto maintain consistent Python formatting. - Commit with concise messages that reference issues (e.g.,
Fix #123 – add vector-search tool).
git add .
git commit -m "feat: add custom vector-search tool"
git push origin feat/custom-tool
- Open a Pull Request targeting the
mainbranch, describing the change and linking related issues. The CI pipeline automatically runspytestand lint checks. - Iterate based on reviewer feedback until the PR is approved and merged.
Code Example: Building a Custom Calculator Tool
The following example demonstrates how to register a new tool and use it with the Assistant agent. This pattern mirrors the "Creating a custom tool" section in the README and shows how the framework automatically discovers tools via the TOOL_REGISTRY.
# 1️⃣ Define a custom tool (e.g., a simple calculator)
from qwen_agent.tools.base import BaseTool, register_tool
import json5
@register_tool('calc')
class CalcTool(BaseTool):
description = 'Simple arithmetic calculator.'
parameters = [{
'name': 'expression',
'type': 'string',
'description': 'A mathematical expression, e.g., "3 * (4 + 5)"',
'required': True
}]
def call(self, params: str, **kwargs):
args = json5.loads(params)
expr = args['expression']
# NOTE: In production, use a safe eval library.
result = eval(expr, {'__builtins__': {}})
return json5.dumps({'result': result})
# 2️⃣ Configure the LLM (DashScope example)
llm_cfg = {
'model': 'qwen-max-latest',
'model_type': 'qwen_dashscope',
# API key is read from the DASHSCOPE_API_KEY env var automatically.
'generate_cfg': {'top_p': 0.8}
}
# 3️⃣ Instantiate the Assistant agent with the custom tool
from qwen_agent.agents import Assistant
assistant = Assistant(
llm=llm_cfg,
function_list=['calc'], # Enable the newly-registered tool
system_message='You are a helpful calculator bot.'
)
# 4️⃣ Run a chat loop
messages = [{'role': 'user', 'content': 'What is 12 divided by 3?'}]
for response in assistant.run(messages=messages):
print(response) # The agent will call `calc` internally and return the answer.
Key Source Files for Contributors
When contributing to the Qwen-Agent project, reference these specific files to understand implementation patterns.
| File | Role |
|---|---|
qwen_agent/agents/assistant.py |
Core agent that injects RAG knowledge and delegates to the generic FnCallAgent. |
qwen_agent/agents/fncall_agent.py |
Implements the function-calling loop, tool selection, and streaming output. |
qwen_agent/tools/base.py |
Global tool registry, BaseTool abstraction, and JSON-schema validation. |
qwen_agent/tools/web_search.py |
Example of a built-in tool that performs external HTTP queries. |
qwen_agent/memory/memory.py |
Provides retrieval of knowledge from uploaded files or external indices. |
qwen_agent/llm/ |
Contains adapters for DashScope, OpenAI-compatible services, and OpenVINO. |
qwen_agent/gui/web_ui.py |
Gradio-based web UI that showcases how to launch an agent interactively. |
examples/ |
Ready-to-run scripts illustrating typical usage patterns. |
tests/ |
Unit and integration tests covering agents, tools, and memory. |
Summary
- Qwen-Agent uses a four-layer architecture: LLM Integration, Tools, Memory, and Agents.
- Register new tools by subclassing BaseTool and using the @register_tool decorator in
qwen_agent/tools/base.py. - Extend agents by inheriting from FnCallAgent or Agent in
qwen_agent/agents/. - Install all optional dependencies (
gui,rag,code_interpreter,mcp) to ensure your development environment matches CI requirements. - Always run
pytest -qand lint checks before submitting a pull request to themainbranch.
Frequently Asked Questions
Do I need to install all optional dependencies to contribute to Qwen-Agent?
While you can contribute with only base dependencies, installing the full suite via pip install -U "qwen-agent[gui,rag,code_interpreter,mcp]" ensures you can run the complete test suite and verify that your changes do not break GUI, RAG, or MCP integrations. The CI pipeline tests against all optional extras, so local verification prevents review delays.
What is the difference between BaseTool and BaseToolWithFileAccess?
BaseTool is the standard abstract class for stateless utilities like calculators or API clients. BaseToolWithFileAccess extends this interface for tools that must read from or write to the filesystem, providing additional lifecycle hooks for file I/O management. Choose the latter when your tool processes uploaded documents or generates artifacts.
How do I test my custom tool before submitting a PR?
Create a unit test in the tests/ directory that instantiates your tool class and calls the call() method with valid and invalid JSON parameters. You can also run the tool through the Assistant agent in an integration test to verify that the TOOL_REGISTRY correctly resolves your tool by name and that the LLM can invoke it during a conversation loop.
Which agent class should I extend for new functionality?
Extend FnCallAgent if your agent requires function-calling capabilities and tool use, as it implements the core loop for selecting and executing tools. Extend the base Agent class only if you are building a completely custom orchestration pattern that does not rely on the standard tool-calling protocol defined in qwen_agent/agents/fncall_agent.py.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →