BYOA Core (Bring Your Own Agent)
可擴充的 AI Agent 核心框架。透過 API 直接與 Claude 互動,自由組裝 Tools、Skills、MCP 來打造你自己的 Agent。
為什麼選擇 BYOA Core?
| 特點 | 說明 |
|---|---|
| API-first | 直接呼叫 Anthropic API,不依賴 CLI 工具,無被封禁風險 |
| Pay-per-use | 按量計費,輕度使用比月費訂閱更划算 |
| 可組裝 | Tools、Skills、MCP 三種擴充機制,像樂高一樣自由拼裝 |
| 可嵌入 | 作為 library 嵌入你的應用,不是獨立的 CLI 工具 |
快速開始
安裝
# 基本安裝(核心功能)
uv add byoa-core
# 可選功能
uv add byoa-core[web] # web_fetch + web_search 工具
uv add byoa-core[mcp] # MCP 整合
uv add byoa-core[all] # 全部安裝
或使用 pip:
pip install byoa-core
pip install byoa-core[all]
設定 API Key
export ANTHROPIC_API_KEY=your_api_key
或在程式碼中明確指定:
from agent_core import AgentCoreConfig, ProviderConfig
config = AgentCoreConfig(
provider=ProviderConfig(api_key='sk-ant-...'),
)
最小範例
import asyncio
from agent_core import Agent, AgentCoreConfig, AnthropicProvider
async def main():
config = AgentCoreConfig()
provider = AnthropicProvider(config.provider)
agent = Agent(config=config, provider=provider)
async for chunk in agent.stream_message('什麼是 Python?'):
if isinstance(chunk, str):
print(chunk, end='', flush=True)
asyncio.run(main())
使用手冊
變更模型與參數
from agent_core import AgentCoreConfig, ProviderConfig
config = AgentCoreConfig(
provider=ProviderConfig(
model='claude-sonnet-4-20250514', # 變更模型
max_tokens=4096, # 最大回應 token 數
timeout=60.0, # API 超時秒數
enable_prompt_caching=True, # 啟用 prompt caching
),
system_prompt='你是一位 Python 專家,請用繁體中文回答。',
)
自訂工具(Tools)
Tools 讓 Agent 能執行實際操作(讀檔、搜尋、API 呼叫等)。
from agent_core import Agent, AgentCoreConfig, AnthropicProvider
from agent_core.tools.registry import ToolRegistry
# 定義自訂工具(支援同步與 async)
def get_weather(city: str) -> str:
return f'{city} 目前 25°C,多雲'
# 註冊工具
registry = ToolRegistry()
registry.register(
name='get_weather',
description='查詢指定城市的天氣資訊',
parameters={
'type': 'object',
'properties': {
'city': {'type': 'string', 'description': '城市名稱'},
},
'required': ['city'],
},
handler=get_weather,
)
# 建立 Agent 並注入工具
config = AgentCoreConfig(
system_prompt='你是助手。需要查天氣時使用 get_weather 工具。',
)
provider = AnthropicProvider(config.provider)
agent = Agent(config=config, provider=provider, tool_registry=registry)
使用內建工具:
框架提供 5 個內建開發工具,可透過 create_default_registry() 一次註冊:
from pathlib import Path
from agent_core.tools.setup import create_default_registry
registry = create_default_registry(Path('./workspace'))
# 已註冊:read_file, edit_file, list_files, grep_search, bash
| 內建工具 | 說明 |
|---|---|
read_file |
讀取檔案內容,支援行數範圍與語言偵測 |
edit_file |
精確搜尋替換編輯,支援新建檔案與備份 |
list_files |
遞迴目錄列表,支援 pattern 過濾 |
grep_search |
正則搜尋程式碼,支援上下文行數 |
bash |
執行 Shell 指令(含安全限制) |
混合使用內建 + 自訂工具:
registry = create_default_registry(Path('./workspace'))
# 追加自訂工具到同一個 registry
registry.register(
name='calculator',
description='計算數學表達式',
parameters={
'type': 'object',
'properties': {
'expression': {'type': 'string'},
},
'required': ['expression'],
},
handler=lambda expression: str(eval(expression)),
)
自訂技能(Skills)
Skills 透過 system prompt 注入來改變 Agent 的行為模式,採用兩階段載入:
- Phase 1:所有已註冊 Skill 的
name+description注入 system prompt(讓 LLM 知道有哪些能力可用) - Phase 2:只有啟用的 Skill 才載入完整
instructions
from agent_core import Skill, SkillRegistry
skill_registry = SkillRegistry()
# 註冊 Skill
skill_registry.register(
Skill(
name='code_review',
description='程式碼審查模式',
instructions="""你現在是程式碼審查專家。審查時請注意:
1. 命名是否清楚
2. 是否有潛在 bug
3. 效能問題
4. 安全漏洞
以 markdown 表格格式輸出審查結果。""",
)
)
# 啟用 Skill(觸發 Phase 2,完整 instructions 注入)
skill_registry.activate('code_review')
# 注入 Agent
agent = Agent(
config=config,
provider=provider,
skill_registry=skill_registry,
)
Skill 的可見性控制:
# 只註冊不啟用 → Phase 1(描述出現在 system prompt,instructions 不載入)
skill_registry.register(Skill(name='tdd', description='...', instructions='...'))
# 啟用 → Phase 2(完整 instructions 注入 system prompt)
skill_registry.activate('tdd')
# 停用 → 回到 Phase 1
skill_registry.deactivate('tdd')
# 隱藏模式 → Phase 1 也不載入描述(完全隱形)
Skill(name='hidden', description='...', instructions='...', disable_model_invocation=True)
透過 API 啟用/停用(給終端使用者):
除了在程式碼中控制,也可以透過 REST API 讓使用者在對話過程中動態切換 Skill:
# 查看目前的 Skill 狀態
curl http://localhost:8000/api/agent/status
# → {"skills": {"registered": ["code_review", "tdd"], "active": []}}
# 啟用 Skill
curl -X POST http://localhost:8000/api/skills/code_review/activate
# → {"status": "ok", "skill": "code_review", "active": true}
# 停用 Skill
curl -X POST http://localhost:8000/api/skills/code_review/deactivate
# → {"status": "ok", "skill": "code_review", "active": false}
啟用後,下一次對話就會自動注入該 Skill 的 instructions 到 system prompt。
MCP 整合
透過 MCP(Model Context Protocol)接入外部工具伺服器。框架定義了 MCPClient Protocol,只需實作此介面即可接入任何 MCP Server。
from agent_core.mcp import MCPToolAdapter, MCPToolDefinition
from agent_core.tools.registry import ToolRegistry
# 實作 MCPClient Protocol(或使用 mcp SDK)
class MyMCPClient:
server_name = 'weather'
async def list_tools(self) -> list[MCPToolDefinition]:
return [
MCPToolDefinition(
name='get_forecast',
description='取得天氣預報',
input_schema={
'type': 'object',
'properties': {
'city': {'type': 'string'},
},
'required': ['city'],
},
),
]
async def call_tool(self, tool_name, arguments):
return {'forecast': 'sunny', 'temperature': 25}
async def close(self):
pass
# 透過 Adapter 註冊到 ToolRegistry
registry = ToolRegistry()
adapter = MCPToolAdapter(MyMCPClient())
await adapter.register_tools(registry)
# 工具名稱自動加上 server 前綴
print(registry.list_tools()) # ['weather__get_forecast']
MCP + 內建工具混合使用:
# 先建立內建工具
registry = create_default_registry(Path('./workspace'))
# 再追加 MCP 工具
adapter = MCPToolAdapter(my_mcp_client)
await adapter.register_tools(registry)
# Agent 同時擁有 read_file、edit_file... 和 MCP 工具
agent = Agent(config=config, provider=provider, tool_registry=registry)
完整組合範例
import asyncio
from pathlib import Path
from agent_core import (
Agent, AgentCoreConfig, AnthropicProvider,
ProviderConfig, Skill, SkillRegistry,
)
from agent_core.tools.setup import create_default_registry
async def main():
# 1. 配置
config = AgentCoreConfig(
provider=ProviderConfig(model='claude-sonnet-4-20250514'),
system_prompt='你是專業的程式開發助手。',
)
# 2. 工具
registry = create_default_registry(Path('./workspace'))
# 3. 技能
skill_registry = SkillRegistry()
skill_registry.register(
Skill(
name='code_review',
description='程式碼審查',
instructions='審查程式碼並以表格輸出結果。',
)
)
skill_registry.activate('code_review')
# 4. 組裝 Agent
provider = AnthropicProvider(config.provider)
agent = Agent(
config=config,
provider=provider,
tool_registry=registry,
skill_registry=skill_registry,
)
# 5. 對話
async for chunk in agent.stream_message('請讀取 main.py 並審查程式碼'):
if isinstance(chunk, str):
print(chunk, end='', flush=True)
print()
asyncio.run(main())
架構
agent_core/
├── agent.py # Agent 核心(對話迴圈、工具調用)
├── config.py # 配置(ProviderConfig、AgentCoreConfig)
├── main.py # FastAPI 應用(API 層,可選)
├── providers/
│ ├── base.py # LLMProvider Protocol
│ ├── anthropic_provider.py # Anthropic 實作
│ └── exceptions.py # Provider 錯誤型別
├── tools/
│ ├── registry.py # ToolRegistry(工具管理與執行)
│ ├── setup.py # 內建工具工廠
│ ├── file_read.py # 檔案讀取
│ ├── file_edit.py # 檔案編輯
│ ├── file_list.py # 目錄瀏覽
│ ├── grep_search.py # 程式碼搜尋
│ └── bash.py # Bash 執行
├── skills/
│ ├── base.py # Skill dataclass
│ └── registry.py # SkillRegistry(兩階段載入)
├── mcp/
│ ├── client.py # MCPClient Protocol + MCPServerConfig
│ └── adapter.py # MCPToolAdapter(MCP → ToolRegistry 橋接)
└── session/
├── base.py # SessionBackend Protocol
├── memory_backend.py # 記憶體 Session(預設)
└── sqlite_backend.py # SQLite Session
設計原則
Protocol-based 依賴注入:所有外部依賴都透過 Protocol 定義介面,使用者可自行替換實作。
| Protocol | 說明 | 內建實作 |
|---|---|---|
LLMProvider |
LLM API 介面 | AnthropicProvider |
MCPClient |
MCP Server 通訊 | 使用者自行實作 |
LockProvider |
檔案操作鎖定 | 使用者自行實作 |
SessionBackend |
對話持久化 | MemoryBackend、SQLiteBackend |
API 端點
內建 FastAPI 應用提供 REST API,適合搭配前端使用:
uv run uvicorn agent_app.main:app --reload --port 8000
| 方法 | 路徑 | 說明 |
|---|---|---|
| POST | /api/chat/stream |
SSE 串流對話 |
| GET | /api/chat/history |
取得對話歷史 |
| POST | /api/chat/reset |
清除對話 |
| GET | /api/chat/usage |
Token 使用量統計 |
| POST | /api/chat/usage/reset |
重置使用量統計 |
| GET | /api/agent/status |
Agent 配置狀態(model、tools、skills) |
| POST | /api/skills/{name}/activate |
啟用指定 Skill |
| POST | /api/skills/{name}/deactivate |
停用指定 Skill |
| GET | /api/files/tree |
沙箱目錄樹 |
| GET | /api/files/content |
取得檔案內容 |
| GET | /health |
健康檢查 |
開發
本專案採用 Gherkin 驅動的 TDD:功能規格(docs/features/*.feature)→ 紅燈測試 → 綠燈實作 → 重構。
# 測試
uv run pytest
# Lint + 格式化
uv run ruff check .
uv run ruff format .
# 型別檢查
uv run pyright
# Smoke test(需要 API Key,會產生費用)
uv run pytest tests/manual --run-smoke -v
License
MIT
Release files for byoa-core 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| byoa_core-0.1.0.tar.gz | 55.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| byoa_core-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 135.6 kB
Release files / byoa_core-0.1.0.tar.gz
| Download URL | byoa_core-0.1.0.tar.gz |
|---|---|
| Size | 55.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8d4c033f31ca0cfc45ad4e192e7381eaa7a113edac2d097bd5d85971f2975a66
|
|
BLAKE2b-256 checksum How to use checksums |
c8479d68e7e0a62218598d76d1efc8b10d95fba3caf2d397af1cf3ec3f4e2099
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.2
|
Release files / byoa_core-0.1.0-py3-none-any.whl
| Download URL | byoa_core-0.1.0-py3-none-any.whl |
|---|---|
| Size | 79.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2c6dbf182c2bf1f30b89ea53fa0bfa83f75169c529cf577d9005e676e65c2b4
|
|
BLAKE2b-256 checksum How to use checksums |
0df8a7ece37e0df1d542c1e402463bca5a8e7cb80c2f6ba3411eb9dc9ae5430a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.2
|