Expert Team
Basic Structure
my-team/
├── .codebuddy-plugin/
│ └── plugin.json # ★ 配置文件(必须)
├── avatars/ # ★ 头像目录(必须)
│ ├── team.png # 团队头像
│ ├── team-lead.png # 主理人头像
│ ├── member-a.png # 成员头像
│ └── member-b.png # 成员头像
├── agents/ # ★ Agent 定义(必须)
│ ├── {team}-team-lead.md # 主理人(名称须加专家团前缀,不可用通用 team-lead)
│ ├── member-a.md # 成员 A
│ └── member-b.md # 成员 B
├── skills/ # 共享技能(可选)
│ └── {skill-name}/
│ ├── SKILL.md
│ ├── references/
│ ├── scripts/
│ └── templates/
├── .mcp.json # 内置 MCP / 连接器依赖声明(可选,见第六节)
├── bin/ # 可执行文件(可选)
├── settings.json # ★ 设置主理人(必须)
└── README.md # 说明文档(推荐)
Configuration File
plugin.json is the core configuration file for an expert team. It includes runtime settings and marketplace display information.
Example
{
"name": "trading-agent",
"version": "1.0.0",
"description": "13 specialized roles collaborate across 5 phases for stock investment analysis",
"author": {
"name": "Your Name",
"email": "you@example.com"
},
"agents": [
"./agents/trading-team-lead.md",
"./agents/market-analyst.md",
"./agents/fundamentals-analyst.md",
"./agents/news-analyst.md",
"./agents/sentiment-analyst.md",
"./agents/bull-researcher.md",
"./agents/bear-researcher.md",
"./agents/research-manager.md",
"./agents/trader.md",
"./agents/aggressive-risk-analyst.md",
"./agents/conservative-risk-analyst.md",
"./agents/neutral-risk-analyst.md",
"./agents/risk-manager.md"
],
"expertType": "team",
"agentName": "trading-team-lead",
"teamInfo": {
"leadAgent": "trading-team-lead",
"memberAgents": [
"market-analyst", "fundamentals-analyst", "news-analyst", "sentiment-analyst",
"bull-researcher", "bear-researcher", "research-manager", "trader",
"aggressive-risk-analyst", "conservative-risk-analyst", "neutral-risk-analyst", "risk-manager"
]
},
"displayName": { "en": "Trading Analysis Team", "zh": "交易分析团队" },
"profession": { "en": "A-Share / HK / US Stock Investment Analysis Team", "zh": "A股/港股/美股投资分析团队" },
"displayDescription": {
"en": "13 specialized roles collaborate across 5 phases: technical, fundamental, news & sentiment analysis → bull-bear debate → trading decision → 3-way risk assessment → final report, delivering BUY/SELL/HOLD recommendations with actionable plans",
"zh": "13位专业角色分5阶段协作完成投资分析:技术面、基本面、新闻面、情绪面数据采集 → 多空辩论 → 交易决策 → 三方风险评估 → 最终报告,输出 BUY/SELL/HOLD 建议及完整操作方案"
},
"avatar": "avatars/team.png",
"categoryId": "08-FinanceInvestment",
"defaultInitPrompt": {
"zh": "帮我分析下XX股票该不该买",
"en": "Should I buy Maotai? Please analyze."
},
"plugin": "trading-agent",
"tags": [
{ "en": "Stock Analysis", "zh": "股票分析" },
{ "en": "Investment", "zh": "投资决策" },
{ "en": "Risk Assessment", "zh": "风险评估" },
{ "en": "Bull-Bear Debate", "zh": "多空辩论" }
],
"quickPrompts": [
{ "en": "Should I buy Maotai?", "zh": "帮我分析下XX该不该买" },
{ "en": "Analyze Tesla stock", "zh": "帮我分析XX的投资价值" },
{ "en": "Review my portfolio risk", "zh": "评估下我的持仓风险" }
],
"members": [
{ "id": "trading-team-lead", "name": {"en":"Captain","zh":"队长"}, "profession": {"en":"Team Lead & Orchestrator","zh":"主理人"}, "avatar": "avatars/team-lead.png", "role": "lead" },
{ "id": "market-analyst", "name": {"en":"Marco","zh":"Marco"}, "profession": {"en":"Technical Analyst","zh":"技术分析师"}, "avatar": "avatars/market-analyst.png", "role": "member" },
{ "id": "fundamentals-analyst", "name": {"en":"Fiona","zh":"Fiona"}, "profession": {"en":"Fundamentals Analyst","zh":"基本面分析师"}, "avatar": "avatars/fundamentals-analyst.png", "role": "member" },
{ "id": "news-analyst", "name": {"en":"Nina","zh":"Nina"}, "profession": {"en":"News Analyst","zh":"新闻分析师"}, "avatar": "avatars/news-analyst.png", "role": "member" },
{ "id": "sentiment-analyst", "name": {"en":"Stella","zh":"Stella"}, "profession": {"en":"Sentiment Analyst","zh":"情绪分析师"}, "avatar": "avatars/sentiment-analyst.png", "role": "member" },
{ "id": "bull-researcher", "name": {"en":"Bruno","zh":"Bruno"}, "profession": {"en":"Bull Researcher","zh":"多头研究员"}, "avatar": "avatars/bull-researcher.png", "role": "member" },
{ "id": "bear-researcher", "name": {"en":"Barry","zh":"Barry"}, "profession": {"en":"Bear Researcher","zh":"空头研究员"}, "avatar": "avatars/bear-researcher.png", "role": "member" },
{ "id": "research-manager", "name": {"en":"Reed","zh":"Reed"}, "profession": {"en":"Research Manager","zh":"研究主管"}, "avatar": "avatars/research-manager.png", "role": "member" },
{ "id": "trader", "name": {"en":"Tyler","zh":"Tyler"}, "profession": {"en":"Trader","zh":"交易员"}, "avatar": "avatars/trader.png", "role": "member" },
{ "id": "aggressive-risk-analyst", "name": {"en":"Aiden","zh":"Aiden"}, "profession": {"en":"Aggressive Risk Analyst","zh":"激进风险分析师"}, "avatar": "avatars/aggressive-risk-analyst.png", "role": "member" },
{ "id": "conservative-risk-analyst", "name": {"en":"Clara","zh":"Clara"}, "profession": {"en":"Conservative Risk Analyst","zh":"保守风险分析师"}, "avatar": "avatars/conservative-risk-analyst.png", "role": "member" },
{ "id": "neutral-risk-analyst", "name": {"en":"Noel","zh":"Noel"}, "profession": {"en":"Neutral Risk Analyst","zh":"中性风险分析师"}, "avatar": "avatars/neutral-risk-analyst.png", "role": "member" },
{ "id": "risk-manager", "name": {"en":"Rex","zh":"Rex"}, "profession": {"en":"Risk Manager","zh":"风险主管"}, "avatar": "avatars/risk-manager.png", "role": "member" }
]
}
Field Descriptions
Basic Fields
| Field | Required | Type | Description |
| name | ✅ | string | Unique expert identifier (lowercase letters and hyphens, e.g. "design-experts") |
| expertType | ✅ | string | Set to "team" |
| version | ✅ | string | Version number (semantic versioning, e.g. "1.0.0") |
| description | ✅ | string | Short English description (one sentence) |
| author | ✅ | object | {name, email} author information |
| agents | ✅ | string[] | List of Agent definition file paths (e.g. ["./agents/my-expert.md"]) |
| agentName | ✅ | string | Name of the lead Agent (matches the MD filename under agents/, without .md) |
| teamInfo | ✅ | object | See below |
| skills | No | string[] | List of skill directory paths (e.g. ["./skills/my-skill"]) |
| homepage | No | string | Project homepage URL |
| license | No | string | License |
| keywords | No | string[] | Search tags |
teamInfo structure:
{
"leadAgent": "主 Agent 名称",
"memberAgents": ["成员A名称", "成员B名称", "..."]
}
Display Fields
| Field | Required | Type | Description |
| displayName | ✅ | {en, zh} | Marketplace display name |
| profession | ✅ | {en, zh} | Job title: must match displayName |
| displayDescription | ✅ | {en, zh} | Marketplace description: the Chinese text must be 40–50 characters and highlight the expert team's core capabilities |
| avatar | ✅ | string | Avatar path (relative path, e.g. "avatars/expert.png") |
| categoryId | ✅ | string | Industry category |
| defaultInitPrompt | ✅ | {en, zh} | Default prompt for the user's first conversation. Must match the first item in quickPrompts |
| plugin | ✅ | string | Associated Plugin name (must match the name field) |
| tags | ✅ | {en, zh}[] | Domain tags the expert specializes in (exactly 3), used for search and marketplace display |
| quickPrompts | ✅ | {en, zh}[] | Suggested prompts (exactly 3), shown on the expert card to help users ask questions quickly |
Expert Team Member Fields
| Field | Required | Type | Description |
| members | ✅ | array | List of all team members (including the team lead) |
Each member object:
| Field | Required | Type | Description |
| id | ✅ | string | Member identifier (matches the Agent MD filename, without .md) |
| name | ✅ | {en, zh} | Member name |
| profession | ✅ | {en, zh} | Member job title |
| avatar | ✅ | string | Member avatar path |
| role | ✅ | string | "lead" (team lead) or "member" (member) |
Agent Definition Files
Lead Agent Example File
---
name: trading-team-lead
description: Trading analysis team lead - orchestrates 5-phase investment analysis workflow
displayName:
en: "He"
zh: "何执舟"
profession:
en: "Chief Strategist"
zh: "首席策略官"
maxTurns: 200
---
# 交易分析团队 - 主理人
你是交易分析专家团的主理人,负责协调 12 位专业角色按照标准流程完成投资分析。
**你不直接做投资分析**,而是:
1. 确认分析目标(标的、分析深度)
2. 按阶段调度成员执行
3. 收集各成员产出,传递给下一阶段
4. 整合最终报告
## 团队协作机制(铁律)
你必须走正式的**团队协作流程**,严禁简化或跳过:
1. **建立团队**:任务开始时由主理人亲自创建本次任务的团队(建议命名 `trading-<标的简称>`),明确本次协作的边界与上下文。**团队创建(TeamCreate)必须且只能由主理人执行,严禁委派任何成员创建团队**
2. **调度成员**:按 SOP 阶段将每位团队成员拉入协作、下发独立任务;团队成员作为独立协作方基于分析任务输出专业产出,不得由主理人代写
3. **消息中转**:成员的产出需回传给你,由你汇总、转交给下一阶段成员;所有跨成员的信息流必须经主理人中转,不得互相直连
4. **成员结论为准**:任何专业产出(技术分析/财报分析/多空论证/风险诊断/交易决策)必须由对应成员输出后再采信,主理人只做编排与汇编
### 严禁行为
- ❌ 禁止跳过"建立团队"的正式流程,直接自己模拟成员发言或并行写出多角色内容
- ❌ 禁止自己代写任何团队成员的专业产出
- ❌ 禁止未完成前序阶段就跳到后续阶段
- ❌ 禁止让成员互相直连通信,所有跨成员信息流必须经主理人中转
- ❌ 禁止 spawn 主理人自己
## 团队成员
### 数据采集组
| 成员 | 名字 | 职责 |
|------|------|------|
| market-analyst | Marco | 技术分析:K线形态、均线系统、量价关系、技术指标 |
| fundamentals-analyst | Fiona | 基本面分析:财报分析、估值模型、行业对比 |
| news-analyst | Nina | 新闻分析:政策新闻、行业动态、公司公告 |
| sentiment-analyst | Stella | 情绪分析:市场情绪指标、资金流向、社交媒体舆情 |
### 研究辩论组
| 成员 | 名字 | 职责 |
|------|------|------|
| bull-researcher | Bruno | 多头研究:寻找看涨论据 |
| bear-researcher | Barry | 空头研究:寻找看跌论据 |
| research-manager | Reed | 研究主管:综合多空观点,形成研究结论 |
### 交易决策组
| 成员 | 名字 | 职责 |
|------|------|------|
| trader | Tyler | 交易员:制定具体交易计划(入场点、止损、止盈、仓位) |
### 风险评估组
| 成员 | 名字 | 职责 |
|------|------|------|
| aggressive-risk-analyst | Aiden | 激进风险分析:评估激进策略的风险收益 |
| conservative-risk-analyst | Clara | 保守风险分析:评估保守策略的风险收益 |
| neutral-risk-analyst | Noel | 中性风险分析:评估中性策略的风险收益 |
| risk-manager | Rex | 风险主管:综合三方风险评估,给出最终风控建议 |
## 标准工作流程(SOP)
### Phase 1: 数据采集
并行调用 market-analyst、fundamentals-analyst、news-analyst、sentiment-analyst。
### Phase 2: 多空辩论
调用 bull-researcher 和 bear-researcher,然后调用 research-manager 综合观点。
### Phase 3: 交易决策
调用 trader,基于研究结论制定具体交易计划。
### Phase 4: 风险评估
并行调用三方风险分析师,然后调用 risk-manager 综合评估。
### Phase 5: 最终报告
综合所有分析结果,输出 BUY/SELL/HOLD 建议及完整操作方案。
## 协作规则
1. **正式团队协作流程**:所有成员调度必须经过"建立团队 → 调度成员 → 成员回传"流程
2. **信息传递**:每阶段结束后,将完整产出原文传递给下一阶段成员
3. **进度通报**:每完成一个阶段向用户简要通报
4. **语言一致**:所有输出使用与用户原始需求相同的语言
5. **子任务命名**:调度每位成员时,在 Agent 工具的 `name` 参数中传入该成员的角色名称(中文)
6. **决策果断**:研究主管和风险主管必须给出明确 Buy/Sell/Hold,不得以"双方都有道理"为由默认 Hold
Member Agent Example
agents/market-analyst.md:
---
name: market-analyst
description: Technical analyst - analyzes charts, indicators, and price patterns
displayName:
en: "Marco"
zh: "Marco"
profession:
en: "Technical Analyst"
zh: "技术分析师"
maxTurns: 50
---
# 技术分析师 - Marco
你是一位经验丰富的技术分析师,擅长通过图表和技术指标分析股票走势。
## 分析维度
1. **K线形态**:识别头肩顶/底、双顶/底、三角形、旗形等
2. **均线系统**:MA5/10/20/60/120/250 的排列关系和金叉死叉
3. **量价关系**:成交量配合价格走势的背离或确认
4. **技术指标**:MACD、RSI、KDJ、布林带等
## 输出格式
- 当前趋势判断(上升/下降/震荡)
- 关键支撑位和压力位
- 技术指标信号汇总
- 技术面综合评分(1-10)
- 短期/中期/长期技术展望
About Tools
Developers cannot add tools themselves: all tool permissions are assigned by the system.
Built-in system tools (for reference only; assigned automatically by the system):
| Tool | Description |
| Read | Read files |
| Write | Write files |
| Grep | Search file contents |
| Glob | Find files by pattern |
| Bash | Run command-line commands |
| WebSearch | Search the internet |
| WebFetch | Fetch web page content |
| AgentTool | Call other Agents (available to the lead Agent) |
| SendMessage | Send messages (available to the lead Agent) |
Built-in MCP and Connector Dependencies (Optional)
An expert can declare MCP services or existing WorkBuddy connectors that it depends on at runtime. After the declaration, WorkBuddy shows an inline guidance card before the user summons that expert (or expert team), walking the user through each connection; the conversation starts only after connections are complete. Built-in MCPs for the expert are managed under Connectors → Custom connectors after they are connected.
Simple experts do not need a dependency declaration. Declare dependencies only when the expert must call external MCP tools or enterprise connectors to work.
How to Declare
Declare dependencies in the dependencies field of plugin.json, or in a .mcp.json file at the plugin root.
Method 1: declare in plugin.json (recommended)
{
"dependencies": {
"mcpServers": "./.mcp.json",
"connectors": ["tencent-docs", "feishu"]
}
}
| Field | Type | Description |
| dependencies.mcpServers | string | string[] | object | Built-in MCP declaration. Can be: a relative path string (pointing to an MCP config file), an array of paths, or an inline { "service-name": {...} } object |
| dependencies.connectors | string[] | List of existing WorkBuddy connector IDs this expert depends on (e.g. "tencent-docs") |
Method 2: .mcp.json at the plugin root
If plugin.json does not declare dependencies.mcpServers, the system automatically reads .mcp.json at the plugin root as a fallback. The file format matches standard MCP configuration. Each server may include x-workbuddy metadata (see 6.3):
{
"mcpServers": {
"huijin-workflow": {
"url": "https://huijin-workflow.mcp.example.com",
"x-workbuddy": {
"displayName": { "zh": "汇金流程 MCP", "en": "Huijin Workflow MCP" },
"description": { "zh": "连接后可查询流程列表、待办流程单并创建流程单。", "en": "..." },
"icon": "./avatars/huijin.svg",
"auth": { "type": "oauth" }
}
}
}
}
MCP Server Configuration
Basic fields under each server in mcpServers follow the standard MCP protocol:
| Field | Description |
| url | Remote MCP (SSE / Streamable HTTP) service URL |
| type | Transport type, e.g. "http"; can be omitted for remote SSE |
| headers | Request headers. For token auth, use ${VAR} placeholders here (see 6.4), e.g. { "Authorization": "Bearer ${SIYUAN_TOKEN}" } |
| x-workbuddy | WorkBuddy-private display and auth metadata (see 6.3); not written into the user's final connector configuration |
x-workbuddy Metadata
x-workbuddy describes how this MCP is shown on the guidance card and how it authenticates. All copy fields support Chinese and English.
| Field | Type | Description |
| displayName | LocalizedString | Card title. Falls back to the server name if omitted |
| description | LocalizedString | Card description. Falls back to url if omitted |
| icon | string | Card icon. Supports a network URL (https://), a data: URL, or a local path relative to the plugin root (e.g. "./avatars/xxx.svg"; placing it under avatars/ is recommended). When icon is set, the avatar background is transparent; otherwise a placeholder is generated from the first character of the display name plus a hashed background color |
| auth.type | string | Auth method: "oauth" / "token" / "none" |
| auth.tokenSchema | object | When auth.type is "token", describes the credential form the user must fill in (see 6.4) |
LocalizedString convention: every copy field can be a plain string or a { zh, en } bilingual object. With a bilingual object, WorkBuddy shows the user's current UI language, falling back zh → en if a language is missing; a plain string is shown the same in both Chinese and English. This convention matches expert displayName / profession.
Token Authentication
When the MCP requires the user to provide an API Token / Key to connect, declare a form with auth.type: "token" plus tokenSchema. When the user clicks Connect, a unified Token authorization dialog appears. After the user fills it in, the system substitutes the values into ${VAR} placeholders in headers and completes the connection.
{
"mcpServers": {
"siyuan": {
"type": "http",
"url": "http://127.0.0.1:36796/mcp",
"headers": {
"Authorization": "Bearer ${SIYUAN_TOKEN}"
},
"x-workbuddy": {
"displayName": { "zh": "思源笔记 MCP", "en": "SiYuan Note MCP" },
"description": { "zh": "连接后可读取和操作本地思源笔记内容。", "en": "..." },
"auth": {
"type": "token",
"tokenSchema": {
"title": { "zh": "配置思源访问 Token", "en": "Configure SiYuan Token" },
"description": { "zh": "请输入思源笔记 API Token。", "en": "..." },
"docUrl": "https://example.com/guide",
"docLabel": { "zh": "如何获取 Token?", "en": "How to get a token?" },
"fields": [
{
"key": "SIYUAN_TOKEN",
"label": { "zh": "思源 Token", "en": "SiYuan Token" },
"placeholder": { "zh": "请输入 API Token", "en": "Enter API token" },
"type": "password",
"required": true,
"description": { "zh": "将写入 Authorization Header", "en": "..." }
}
]
}
}
}
}
}
}
tokenSchema fields:
| Field | Type | Description |
| title | LocalizedString | Dialog title |
| description | LocalizedString | Dialog description |
| docUrl | string | "How to get" help documentation URL (not copy; not localized) |
| docLabel | LocalizedString | Help link display text |
| fields | array | Form field list; see below |
Each item in fields:
| Field | Type | Description |
| key | string | Field identifier, corresponding to the ${key} placeholder in headers (not copy) |
| label | LocalizedString | Field label |
| placeholder | LocalizedString | Input placeholder |
| type | string | "text" or "password" (use password for sensitive credentials) |
| required | boolean | Whether the field is required |
| description | LocalizedString | Additional description below the field |
Connector Dependencies
If the expert depends on a connector already listed in WorkBuddy (rather than a bundled MCP), list the connector IDs in dependencies.connectors. The guidance card name, description, and icon come from the connector itself; you do not need to redeclare them in the expert package.
{
"dependencies": {
"connectors": ["tencent-docs"]
}
}
Notes
- x-workbuddy is a WorkBuddy-private field. It is stripped when the connection is written to the user's Custom connectors configuration and will not pollute the user's local mcp.json
- Already-connected dependencies are not prompted again when the user summons an expert with the same name
- Tokens are stored locally by the user after they are entered. Never hard-code any real Token / secret in the expert package
- Relative icon paths are resolved from the directory that contains the MCP declaration file; in .mcp.json at the plugin root, ./avatars/xxx.svg points to avatars/ at the plugin root
Avatar Guidelines
| Item | Requirement |
| Format | PNG (recommended) or JPG |
| Size | 512×512 px (square) |
| File size | No more than 500KB per image |
| Style | Consistent comic/illustration style; professional and natural |
| Content | Fits the role; no prohibited content |
Storage Location
Place all avatars in the avatars/ directory and reference them with relative paths in plugin.json:
avatars/
├── team.png # 团队头像
├── team-lead.png # 主理人头像
├── market-analyst.png # 成员头像
├── fundamentals-analyst.png
└── ...
Template Files
Download file: trading-team.zip
Download link: https://codebuddy-platform-1258344699.cos.ap-beijing.myqcloud.com/open/static/files/trading-team.zip
