The project's README from github.com/Xu123-Bob/Baize. As one markdown file: README.md.
Know all things, and code with you by intuition.
Baize — an auspicious beast in ancient Chinese mythology that knows all things, now reincarnated as a Vibe Coding assistant.
An open-source AI Coding Agent CLI and a drop-in alternative to Claude Code CLI. Supports multiple backends (DeepSeek / OpenAI-compatible / GLM / Qwen / Kimi / local Ollama), privacy sanitization, and multilingual interaction, with a complete toolkit: tool invocation, skill loading, subagent delegation, context compression, and secure sandbox.
Multi-backend support: DeepSeek, any OpenAI-compatible API (GLM / Qwen / Kimi / OpenAI), and local Ollama. Switch with one setting.
Zero-config startup: Automatically generates configuration files on first run. Users only need to enter the key once.
Complete toolchain: bash execution, file read/write/edit, glob/grep search, web search and fetch, background tasks, task and todo management.
Skills system: Load domain knowledge (SKILL.md) on demand, making the AI more professional in specific scenarios.
Subagents: Delegate complex tasks to subagents with independent contexts to avoid polluting the main session.
Hooks: Python or Shell hooks that support pre/post tool-call interception, audit logging, auto-formatting, and test gating.
MCP protocol: Connect external tool servers (GitHub, Filesystem, etc.) via Model Context Protocol.
Context compression: Two-level compression (tool result truncation + LLM summarization), supporting very long conversations.
Secure sandbox: Command whitelist, path escape detection, dangerous command blocking, sensitive file protection, and script injection interception.
Privacy sanitization: Automatically detects and masks phone numbers, emails, ID cards, bank cards, API keys and other PII before sending to the LLM, then restores them in the response. Two levels (standard / strict), switchable via natural language or /privacy.
Multilingual interaction: Freely switch between Chinese / English / Japanese / Korean / Spanish / French — just say English or use /lang ja, and the AI thinks and replies in that language.
Black-gold themed CLI: Adaptive Chinese width, code highlighting, Diff coloring, and thought collapsing.
Python 3.10+ (requires tomllib; built in on 3.11+; on 3.10 install tomli)
pip
bash -- Press Win+R and enter cmd
baize
(1) After unzipping, enter this file directory:
bash -- Press Win+R and enter cmd
cd path/to/extracted/directory # If you are already in this file directory and press Win+R then cmd, skip this step
pip install -r requirements.txt
python -m Baize
After installation, press Win+R, enter cmd, open the CLI, type baize, and run it.
(2) After downloading the ZIP, install locally: unzip, enter the directory, and run:
bash -- Press Win+R and enter cmd
pip install .
After installation, press Win+R, enter cmd, open the CLI, type baize, and run it.
baize
On first run, Baize automatically generates two configuration files:
~/.baize/config.toml # Backend configuration (choose DeepSeek / OpenAI / Ollama)
~/.baize/.env # Key file
Windows path: C:\Users\your-username\.baize\.
Open ~/.baize/config.toml and modify active_provider:
active_provider = "deepseek" # or "openai" / "ollama"
[model_providers.deepseek]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
env_key = "DEEPSEEK_API_KEY"
model = "deepseek-v4-pro"
[model_providers.openai]
name = "OpenAI"
base_url = "https://api.openai.com/v1"
env_key = "OPENAI_API_KEY"
model = "gpt-4o-mini"
[model_providers.ollama]
name = "Ollama (local)"
base_url = "http://localhost:11434/v1"
env_key = ""
model = "qwen2.5:7b"
Edit ~/.baize/.env:
# Required for DeepSeek backend
DEEPSEEK_API_KEY=sk-your-key
# Required for OpenAI-compatible APIs (GLM / Qwen / Kimi / OpenAI)
#OPENAI_API_KEY=your-key
#Ollama local requires no key
baize
If you see the black-gold logo and welcome message, startup succeeded.
After startup, describe your needs in natural language at the >>> Decree: prompt:
>>> 降旨: Write a Python script to scrape Douban Top250 and save it as CSV
>>> 降旨: Help me check type errors in all Python files under src/
>>> 降旨: Find all places in this repository that use requests and change them to httpx
Baize supports six languages: 中文, English, 日本語, 한국어, Español, Français.
Two ways to switch:
Baize automatically detects your input language:
>>> 降旨:Hello, help me write a Python script
[system] Detected input language: English. Baize switched to English.
(replies in English)
>>> 降旨:日本語で答えてください
[system] Detected input language: 日本語. Baize switched to 日本語.
(replies in Japanese)
>>> 降旨:/lang # Show current language and available list
[system] Current language: English (en)
[system] Available:
zh 中文
en English ←
ja 日本語
ko 한국어
es Español
fr Français
>>> 降旨:/lang English # Switch by language name
>>> 降旨:/lang ja # Switch by language code
>>> 降旨:/lang 西班牙语 # Chinese names work too
Supports language name / language code / localized name. To switch to English, any of English, en, 英语, 英文 works.
/exit, /quit --> Exit Baize/clear --> Clear conversation history, todos, thought records, and tool records/compact --> Manually compress context (use when the conversation is too long)/commit --> Save the current session and commit to Git (if inside a Git repository)/lang → Show current language; /lang en switches to English (accepts code or name)/skills --> List all available skills/skills reload --> Reload the user skills directory/unload --> Unload the currently active skill/show thought --> View the full thought record/show tool --> View tool call records/show all --> View all session history/skill-name --> Load the specified skill (supports fuzzy matching)/privacy --> Privacy sanitization control (see "Privacy Sanitization" below)Don't want to use a cloud API? Use local Ollama:
#1. Install Ollama: https://ollama.com/download
#2. Pull a model
ollama pull qwen2.5:7b
#3. Start the Ollama service
ollama serve
#4. Modify ~/.baize/config.toml
active_provider = "ollama"
#5. Start Baize
baize
Recommended models: qwen2.5:7b (strong Chinese), llama3.1:8b, deepseek-r1:7b.
Baize supports four extension methods. Place them in the current working directory to take effect.
Write domain knowledge in ./skills/skill-name/SKILL.md. The AI will proactively load it when encountering complex tasks.
---
name: pandas-eda
description: Best practices for exploratory data analysis with pandas
tags: data,python
---
# Pandas EDA Guide
## Core Steps
1. Use df.info() to inspect field types and missing values
2. Use df.describe() for statistical description
...
You can also manually load it in conversation with /pandas-eda.
Define specialized subagents in ./subagent/role-name/AGENT.md. The main agent can delegate tasks through the agent tool.
---
name: code-reviewer
description: A strict code reviewer
---
You are a senior code reviewer. During review, prioritize:
1. Boundary conditions and exception handling
2. Resource leaks
3. Concurrency safety
...
Place the following under ./hooks/:
PreToolUse-*.shPostToolUse-*.shStop-*.shThey receive JSON input and return a decision:
#!/bin/bash
#PreToolUse-guard.sh
read -r input
if echo "$input" | grep -q "rm -rf"; then
echo '{"hookSpecificOutput":{"permissionDecision":"block","permissionDecisionReason":"Deletion prohibited"}}'
fi
Python hooks can directly call built-in APIs (see the hook_* functions in Baize.py).
Configure external tool servers in ./MCP/mcp_config.json:
{
"mcpServers": [
{
"name": "filesystem",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"env": {},
"enabled": true
}
]
}
Baize enables the following security mechanisms by default:
ls, cat, grep, git, python3, etc. are allowed./tmp.rm -rf /, fork bombs, curl | sh, git push --force, etc..env, .ssh/, id_rsa, *.pem, etc.python -c "os.system(...)".If you need to relax restrictions in a trusted project, modify ALLOWED_COMMANDS and FORBIDDEN_PATH_PATTERNS in Baize.py.
Baize ships with a bidirectional, reversible privacy sanitization mechanism. Sensitive information is replaced with placeholders before being sent to the LLM, and restored automatically in the response — completely transparent to you. What you see (history, tool arguments, final answer) is always the original text; what the LLM sees is always [[PHONE_1]], [[EMAIL_1]], etc.
Off by default. Enable when needed.
>>> 降旨:enable privacy sanitization
[system] Privacy sanitization enabled (standard mode).
>>> 降旨:enable strict sanitization
[system] Privacy sanitization enabled (strict mode).
>>> 降旨:disable privacy protection
[system] Privacy sanitization disabled.
Standard :Mainland China phone numbers, ID cards, bank cards (Luhn check), emails, IPv4/IPv6, OpenAI/Anthropic/GitHub/AWS API keys, Bearer tokens, private key blocks, password fields, URL credentials
Strict:All of standard + Chinese names, QQ numbers, WeChat IDs, Mainland China license plates
User input (with real PII) → messages store original text
↓ sanitize_messages()
What the LLM sees: [[PHONE_1]], [[EMAIL_1]]
↓ LLM response
Placeholders → restore_message()
Restored to original → stored / displayed / executed
Same original text reuses the same placeholder, so one phone number stays as [[PHONE_1]] throughout a session.
Tool arguments are graded by sensitivity: text-only tools like todo, ask_user_question, task_* have their arguments sanitized; path/command/URL tools like run_read, run_bash, run_webfetch are left alone (otherwise they would fail because the path was replaced).
Subagents are protected too: tasks delegated from the main agent go through the same sanitize/restore pipeline.
>>> 降旨:/privacy test My phone is 13812345678, email [email protected]
Original: My phone is 13812345678, email [email protected]
Masked : My phone is [[PHONE_1]], email [[EMAIL_1]]
Restored: My phone is 13812345678, email [email protected]
>>> 降旨: /privacy status
[Privacy Sanitization]
Current mode : standard
Active rules : 15 / 19
Placeholders : 2
Sanitize calls: 3
Restore calls : 3
baize-agent/
├── pyproject.toml # Packaging configuration
├── README.md
├── tests/ # Tests (not shipped with the package)
| ├── __init__.py
| ├── test_history.py
| └── test_skill_loader.py
├── .env.example # Environment variable example
├── .gitignore
└── agent/ # Main package
├── __init__.py
├── Baize.py # Main program and Agent Loop
├── config.py # Multi-backend configuration loading
├── ui_theme.py # CLI rendering theme
├── utils.py # General utilities
├── logo.txt
├── skills/ # Built-in skills
├── subagent/ # Built-in subagents
├── core/ # Core logic (side-effect free, unit-testable)
| ├── __init__.py
| ├── history.py # Session history cleaning / token estimation / compression
| └── privacy.py # Privacy sanitization
├── hooks/ # Built-in hooks
└── MCP/ # MCP client and configuration
├── __init__.py
├── mcp_client.py
└── mcp_config.json
DEEPSEEK_API_KEY Description: DeepSeek API Default: key —DEEPSEEK_BASE_URL Description: DeepSeek endpoint Default: https://api.deepseek.comOPENAI_API_KEY Description: OpenAI Default: compatible API key —OPENAI_BASE_URL Description: OpenAI-compatible endpoint Default: https://api.openai.com/v1OLLAMA_BASE_URL Description: Ollama service address Default: http://localhost:11434Write variables to ~/.baize/.env; there is no need to modify shell config files.
This project uses pytest. Before development, install the package in editable mode with dev dependencies:
pip install -e ".[dev]"
Run all tests:
python -m pytest tests/ -v
Run a single file:
python -m pytest tests/test_history.py -v
agent/: The main package shipped with the package. All runtime logic and resources (skills, subagent, hooks, MCP) are here.agent/core/: Pure logic modules with no external side effects. They must be independently testable. Put new logic of this kind here and add tests.tests/: Corresponds one-to-one with source files under agent/, named test_<module>.py.A: ~/.baize/.env, not the .env in the project root.
A: No. Just change active_provider in ~/.baize/config.toml.
A: No. Select active_provider = "ollama" and leave env_key empty.
A: Just say "switch to /path/to/project" in the conversation, and Baize will call the set_workspace tool.
A: Baize automatically performs two-level compression: first truncating old tool results, then requesting the LLM to generate a summary. You can also manually run /compact.
A: The default command whitelist blocks dangerous operations such as rm -rf /; before writing files, it shows a Diff and asks for confirmation.
Issues and PRs are welcome. It is recommended to first read the agent_loop function in Baize.py to understand the Agent main loop before extending it.
MIT License
This project is hosted on AtomGit in China: https://atomgit.com/Com_Xu/Baize
Thanks to AtomGit for including this project in the G-star incubation program
Thanks to PR contributors, Douyin followers, and students who follow me
Inspired by excellent AI Coding tools such as Claude Code and Codex
Built on DeepSeek, OpenAI SDK, and MCP
Thanks to all developers walking the Vibe Coding path together
Developers focus on ideas and decisions; Baize handles the trivial and execution. Let programming return to intuition, and let creation flow like myth.
If Baize is useful to you, you’re welcome to sponsor or tip. Independent development also takes a lot of time. Sponsorship will not change the product update schedule. Thank you for your support!
Scan the QR code with WeChat. Please indicate "Baize Open Source Cooperation" or "Corporate Recruitment".
Scan with Douyin to follow