用 AI Bot 打造顧問團隊(二):三條路線的實作步驟與範例程式碼

前言

上一篇 我們比較了三條技術路線的優缺點。本篇進入動手實作,每條路線都包含:

  1. 環境設定
  2. 角色(Agent)定義
  3. 實際執行範例
  4. 關鍵注意事項

路線 A:Claude Code + AGENTS.md + Skills

1. 環境設定

1# 安裝 Claude Code CLI
2npm install -g @anthropic-ai/claude-code
3
4# 確認版本
5claude --version
6
7# 登入(需要 Anthropic 帳號)
8claude auth login

建立專案目錄:

1mkdir ai-consultant-team && cd ai-consultant-team

2. 建立 AGENTS.md(團隊憲章)

AGENTS.md 是整個 Agent 團隊的「組織架構圖」,定義各角色的職責與協作方式。

 1# AI 顧問團隊 - 組織架構
 2
 3## 團隊宗旨
 4協助中小企業做出明智的 AI 導入決策,提供從需求診斷到執行規劃的完整顧問服務。
 5
 6## 角色定義
 7
 8### Coordinator(協調員)
 9- **職責**:接收初始需求,判斷複雜度,分派給對應 Agent
10- **不做**:不直接撰寫報告,不做技術分析
11- **輸出格式**:JSON,包含 task_id、assigned_agent、priority
12
13### Intake Agent(需求收集師)
14- **職責**:與客戶對話,收集結構化需求資訊
15- **問題清單**:產業、公司規模、現有系統、痛點、預算範圍、時程
16- **輸出格式**:Markdown 的需求摘要文件
17
18### Analyst Agent(問題分析師)
19- **職責**:根據需求摘要,診斷問題根源,評估 AI 導入可行性
20- **輸出格式**:包含 feasibility_score (1-10)、risks[]、opportunities[] 的分析報告
21
22### Strategist Agent(策略顧問)
23- **職責**:設計 AI 解決方案,評估 ROI,排列優先順序
24- **輸出格式**:方案比較表 + 建議路徑
25
26### Writer Agent(報告撰寫師)
27- **職責**:整合所有 Agent 的輸出,產出最終顧問報告
28- **格式**:Executive Summary + 詳細分析 + 行動計畫

3. 建立各 Agent 的 Skill 檔案

1mkdir -p .claude/skills

.claude/skills/intake.md

 1# Skill: 客戶需求收集
 2
 3你是 Intake Agent,AI 顧問公司的需求收集師。
 4
 5## 你的任務
 6透過結構化問題,收集客戶的完整需求。每個問題問完後等待客戶回答,不要一次列出所有問題。
 7
 8## 問題清單(依序提問)
 91. 請問貴公司主要的業務是什麼?目前的規模大概多少人?
102. 您目前遇到最大的業務痛點是什麼?
113. 您對 AI 導入的期望是什麼?(降低成本、提升效率、新產品還是其他?)
124. 目前公司使用哪些主要的軟體系統?(ERP、CRM、資料庫等)
135. 預計的投資預算範圍大概是?(不需要精確,粗估即可)
146. 希望在多久內看到初步成果?
15
16## 輸出格式
17收集完畢後,產出以下格式的需求摘要:
18
19```json
20{
21  "company": {
22    "industry": "",
23    "size": "",
24    "current_systems": []
25  },
26  "pain_points": [],
27  "ai_expectations": [],
28  "budget_range": "",
29  "timeline": "",
30  "priority_level": "high|medium|low"
31}

**`.claude/skills/diagnose.md`**

```markdown
# Skill: 問題診斷分析

你是 Analyst Agent,AI 顧問公司的問題分析師。

## 輸入
你會收到 Intake Agent 產出的 JSON 需求摘要。

## 你的任務
1. 分析客戶的痛點,找出可以用 AI 解決的核心問題
2. 評估每個問題的 AI 可行性(技術成熟度、資料可得性、ROI 潛力)
3. 識別潛在風險(資料品質、組織阻力、技術債)

## 輸出格式
```json
{
  "diagnosis": {
    "core_problems": [
      {
        "problem": "問題描述",
        "ai_solution_type": "自動化|預測|生成|分類",
        "feasibility_score": 8,
        "data_readiness": "high|medium|low",
        "estimated_roi": "高/中/低"
      }
    ],
    "risks": [
      {
        "risk": "風險描述",
        "severity": "high|medium|low",
        "mitigation": "緩解策略"
      }
    ],
    "recommended_focus": "最建議優先處理的問題"
  }
}

### 4. 設定 `.claude/settings.json`

```json
{
  "permissions": {
    "allow": [
      "Read",
      "Write",
      "Bash(mkdir:*)",
      "Bash(cat:*)",
      "Bash(echo:*)"
    ]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo '[LOG] Agent 產出新文件: $CLAUDE_TOOL_OUTPUT' >> workspace/activity.log"
          }
        ]
      }
    ]
  }
}

5. 實際執行

1# 啟動協調員,開始顧問流程
2claude "根據 AGENTS.md 的角色定義,你是 Coordinator。
3有一位新客戶想要諮詢 AI 導入。請先呼叫 Intake Agent(使用 /skills/intake skill)
4收集需求,再呼叫 Analyst Agent 進行診斷。"

路線 B:Gemini CLI + Google Workspace

1. 環境設定

 1# 安裝 Gemini CLI
 2npm install -g @google/gemini-cli
 3
 4# 或使用 Python 版
 5pip install google-generativeai google-auth google-auth-oauthlib
 6
 7# 設定 API Key
 8export GEMINI_API_KEY="your-api-key-here"
 9
10# Google Workspace 整合需要 OAuth
11gcloud auth application-default login

2. 定義 Agent System Prompts

建立一個 prompts/ 目錄存放各 Agent 的 System Prompt:

prompts/consultant_agent.txt(參考 ai_consultant repo 的設計)

You are a professional AI consultant with a strong blend of business acumen and technical expertise.
You approach problems with the mindset of a C-suite executive while remaining practical and grounded
like an SMB manager responsible for day-to-day execution.

You think in terms of outcomes, ROI, and competitive advantage—not just technology for its own sake.

In every response, you:
* Clarify the business objective before suggesting solutions
* Frame trade-offs (cost, speed, risk, scalability)
* Provide structured, actionable recommendations
* Anticipate implementation challenges
* Focus on measurable impact and sustainability

3. Python 整合腳本

 1# consultant_team.py
 2import google.generativeai as genai
 3from google.oauth2.credentials import Credentials
 4from googleapiclient.discovery import build
 5import json
 6import os
 7
 8genai.configure(api_key=os.environ["GEMINI_API_KEY"])
 9
10class ConsultantAgent:
11    def __init__(self, role: str, system_prompt: str):
12        self.role = role
13        self.model = genai.GenerativeModel(
14            model_name="gemini-2.0-flash",
15            system_instruction=system_prompt
16        )
17        self.chat = self.model.start_chat(history=[])
18
19    def process(self, input_text: str) -> str:
20        response = self.chat.send_message(input_text)
21        return response.text
22
23
24class ConsultantTeam:
25    def __init__(self):
26        self.intake = ConsultantAgent(
27            role="intake",
28            system_prompt=open("prompts/intake.txt").read()
29        )
30        self.analyst = ConsultantAgent(
31            role="analyst",
32            system_prompt=open("prompts/analyst.txt").read()
33        )
34        self.strategist = ConsultantAgent(
35            role="strategist",
36            system_prompt=open("prompts/consultant_agent.txt").read()
37        )
38
39    def run_full_consultation(self, client_input: str) -> dict:
40        print(f"[Intake] 收集需求...")
41        intake_result = self.intake.process(client_input)
42
43        print(f"[Analyst] 診斷問題...")
44        analyst_result = self.analyst.process(
45            f"請分析以下需求:\n{intake_result}"
46        )
47
48        print(f"[Strategist] 設計策略...")
49        strategy_result = self.strategist.process(
50            f"需求摘要:{intake_result}\n\n診斷結果:{analyst_result}\n\n請提出具體的 AI 導入策略。"
51        )
52
53        return {
54            "intake": intake_result,
55            "analysis": analyst_result,
56            "strategy": strategy_result
57        }
58
59
60# 使用範例
61if __name__ == "__main__":
62    team = ConsultantTeam()
63    result = team.run_full_consultation(
64        "我們是一家 50 人的製造業公司,想要用 AI 減少品管的人力成本。"
65    )
66    print(json.dumps(result, ensure_ascii=False, indent=2))

4. 寫入 Google Docs

 1# google_docs_writer.py
 2from googleapiclient.discovery import build
 3from google.oauth2 import service_account
 4
 5def write_report_to_docs(report_content: str, title: str) -> str:
 6    """將顧問報告寫入 Google Docs,回傳文件 URL"""
 7    creds = service_account.Credentials.from_service_account_file(
 8        "service_account.json",
 9        scopes=["https://www.googleapis.com/auth/documents"]
10    )
11    service = build("docs", "v1", credentials=creds)
12
13    # 建立新文件
14    doc = service.documents().create(
15        body={"title": title}
16    ).execute()
17    doc_id = doc["documentId"]
18
19    # 寫入內容
20    service.documents().batchUpdate(
21        documentId=doc_id,
22        body={
23            "requests": [
24                {
25                    "insertText": {
26                        "location": {"index": 1},
27                        "text": report_content
28                    }
29                }
30            ]
31        }
32    ).execute()
33
34    return f"https://docs.google.com/document/d/{doc_id}"

路線 C:LangGraph + LLM(完整程式碼)

1. 環境設定

1pip install langgraph langchain langchain-anthropic langchain-openai
2pip install psycopg2-binary redis  # 狀態持久化
3
4# 設定環境變數
5export ANTHROPIC_API_KEY="your-key"
6export LANGCHAIN_API_KEY="your-langsmith-key"  # 可觀測性
7export LANGCHAIN_TRACING_V2=true

2. 定義狀態結構

 1# state.py
 2from typing import TypedDict, Annotated, List
 3from langgraph.graph.message import add_messages
 4
 5class ConsultantState(TypedDict):
 6    # 對話歷史
 7    messages: Annotated[list, add_messages]
 8    # 客戶需求(結構化)
 9    client_requirements: dict
10    # 診斷結果
11    diagnosis: dict
12    # 策略方案
13    strategy: dict
14    # 最終報告
15    final_report: str
16    # 當前階段
17    current_phase: str
18    # 錯誤訊息
19    error: str | None

3. 定義各 Agent 節點

  1# agents.py
  2from langchain_anthropic import ChatAnthropic
  3from langchain_core.messages import SystemMessage, HumanMessage
  4from state import ConsultantState
  5import json
  6
  7llm = ChatAnthropic(model="claude-sonnet-4-6", temperature=0.3)
  8
  9INTAKE_PROMPT = """你是 AI 顧問公司的需求收集師。
 10根據客戶的描述,提取並結構化以下資訊:
 11- 產業與公司規模
 12- 核心痛點(最多 3 個)
 13- AI 期望(自動化/預測/生成/其他)
 14- 現有系統
 15- 預算與時程
 16
 17以 JSON 格式回覆,key 使用英文。"""
 18
 19ANALYST_PROMPT = """你是 AI 顧問公司的問題分析師。
 20根據客戶需求,評估 AI 導入的可行性。
 21對每個痛點給出:
 22- feasibility_score (1-10)
 23- 所需資料類型
 24- 預估 ROI
 25- 主要風險
 26
 27以 JSON 格式回覆。"""
 28
 29STRATEGIST_PROMPT = """你是資深 AI 顧問。
 30根據需求診斷,設計具體的 AI 導入策略:
 311. 建議的第一個 AI 專案(Quick Win)
 322. 6 個月的路線圖
 333. 所需資源(人力、技術、預算)
 344. 成功指標(KPI)
 35
 36用繁體中文,以 Markdown 格式回覆。"""
 37
 38
 39def intake_agent(state: ConsultantState) -> ConsultantState:
 40    """需求收集 Agent"""
 41    messages = [
 42        SystemMessage(content=INTAKE_PROMPT),
 43        HumanMessage(content=str(state["messages"][-1].content))
 44    ]
 45    response = llm.invoke(messages)
 46
 47    try:
 48        requirements = json.loads(response.content)
 49    except json.JSONDecodeError:
 50        requirements = {"raw": response.content}
 51
 52    return {
 53        "client_requirements": requirements,
 54        "current_phase": "analysis",
 55        "messages": [response]
 56    }
 57
 58
 59def analyst_agent(state: ConsultantState) -> ConsultantState:
 60    """問題診斷 Agent"""
 61    messages = [
 62        SystemMessage(content=ANALYST_PROMPT),
 63        HumanMessage(content=json.dumps(state["client_requirements"], ensure_ascii=False))
 64    ]
 65    response = llm.invoke(messages)
 66
 67    try:
 68        diagnosis = json.loads(response.content)
 69    except json.JSONDecodeError:
 70        diagnosis = {"raw": response.content}
 71
 72    return {
 73        "diagnosis": diagnosis,
 74        "current_phase": "strategy",
 75        "messages": [response]
 76    }
 77
 78
 79def strategist_agent(state: ConsultantState) -> ConsultantState:
 80    """策略設計 Agent"""
 81    context = f"""
 82客戶需求:
 83{json.dumps(state['client_requirements'], ensure_ascii=False, indent=2)}
 84
 85診斷結果:
 86{json.dumps(state['diagnosis'], ensure_ascii=False, indent=2)}
 87"""
 88    messages = [
 89        SystemMessage(content=STRATEGIST_PROMPT),
 90        HumanMessage(content=context)
 91    ]
 92    response = llm.invoke(messages)
 93
 94    return {
 95        "strategy": {"content": response.content},
 96        "current_phase": "report",
 97        "messages": [response]
 98    }
 99
100
101def writer_agent(state: ConsultantState) -> ConsultantState:
102    """報告撰寫 Agent"""
103    report = f"""# AI 導入顧問報告
104
105## Executive Summary
106{state['strategy'].get('content', '')}
107
108---
109*報告由 AI 顧問團隊自動生成*
110*日期:{__import__('datetime').date.today()}*
111"""
112    return {
113        "final_report": report,
114        "current_phase": "done",
115        "messages": []
116    }

4. 組裝 Graph(核心邏輯)

 1# graph.py
 2from langgraph.graph import StateGraph, END
 3from langgraph.checkpoint.memory import MemorySaver
 4from state import ConsultantState
 5from agents import intake_agent, analyst_agent, strategist_agent, writer_agent
 6
 7
 8def route_after_analysis(state: ConsultantState) -> str:
 9    """根據診斷結果決定下一步"""
10    diagnosis = state.get("diagnosis", {})
11    # 如果可行性分數平均低於 5,建議先做資料準備
12    scores = [
13        item.get("feasibility_score", 5)
14        for item in diagnosis.get("core_problems", [{}])
15    ]
16    avg_score = sum(scores) / len(scores) if scores else 5
17
18    if avg_score < 4:
19        return "low_feasibility"  # 未來可加入特殊處理節點
20    return "strategist"
21
22
23def build_consultant_graph():
24    graph = StateGraph(ConsultantState)
25
26    # 加入節點
27    graph.add_node("intake", intake_agent)
28    graph.add_node("analyst", analyst_agent)
29    graph.add_node("strategist", strategist_agent)
30    graph.add_node("writer", writer_agent)
31
32    # 定義流程
33    graph.set_entry_point("intake")
34    graph.add_edge("intake", "analyst")
35    graph.add_conditional_edges(
36        "analyst",
37        route_after_analysis,
38        {
39            "strategist": "strategist",
40            "low_feasibility": "strategist"  # 目前都走同一路
41        }
42    )
43    graph.add_edge("strategist", "writer")
44    graph.add_edge("writer", END)
45
46    # 加入記憶體(可換成 PostgreSQL)
47    memory = MemorySaver()
48    return graph.compile(checkpointer=memory)
49
50
51# 執行
52if __name__ == "__main__":
53    from langchain_core.messages import HumanMessage
54
55    app = build_consultant_graph()
56
57    config = {"configurable": {"thread_id": "client-001"}}
58    result = app.invoke(
59        {
60            "messages": [HumanMessage(content=(
61                "我們是一家台灣的中型製造商,約 200 人。"
62                "目前最大的問題是品管效率太低,每天要花 5 個工人做外觀檢測。"
63                "希望能用 AI 自動化這個流程,預算大概 100-300 萬台幣。"
64            ))],
65            "current_phase": "intake",
66            "error": None
67        },
68        config=config
69    )
70
71    print(result["final_report"])

5. 加入人機協作(Human-in-the-Loop)

對於高風險決策,可以加入人工審核節點:

 1from langgraph.graph import interrupt
 2
 3def human_review_node(state: ConsultantState) -> ConsultantState:
 4    """讓人類審核策略後再繼續"""
 5    # 這會暫停執行,等待人類輸入
 6    human_feedback = interrupt({
 7        "question": "請審核以下 AI 策略建議,是否同意送出給客戶?",
 8        "strategy": state["strategy"]
 9    })
10
11    if human_feedback.get("approved"):
12        return {"current_phase": "report"}
13    else:
14        # 根據人類反饋修正
15        return {
16            "strategy": {
17                "content": human_feedback.get("revised_strategy", ""),
18                "human_approved": True
19            }
20        }
21
22# 在 graph 中加入此節點
23graph.add_node("human_review", human_review_node)
24graph.add_edge("strategist", "human_review")
25graph.add_edge("human_review", "writer")

三條路線的 System Prompt 設計原則

不管選哪條路線,好的 System Prompt 是關鍵。以下是設計原則:

原則 1:明確角色邊界

✅ 好的寫法:
"你是需求收集師。你只負責提問和整理需求,
不要給建議,不要做分析,不要撰寫報告。"

❌ 不好的寫法:
"你是一個 AI 助理,幫助客戶解決 AI 問題。"

原則 2:定義輸出格式

✅ 好的寫法:
"回覆必須是合法的 JSON,schema 如下:
{ 'pain_points': string[], 'budget': string, 'timeline': string }"

❌ 不好的寫法:
"用結構化的方式回覆。"

原則 3:處理邊界情況

✅ 好的寫法:
"如果客戶的問題超出 AI 顧問範疇(例如法律、財務),
回覆:'這個問題需要專業[法律/財務]顧問,我可以協助介紹。'"

原則 4:Few-shot 範例

在 System Prompt 中加入 2-3 個好的輸入/輸出範例,能大幅提升一致性。


小結

路線最難的部分最容易踩的坑
A(Claude Code)多 Agent 狀態同步Skill 呼叫不穩定
B(Gemini CLI)Google OAuth 設定Context 太大時回應變慢
C(LangGraph)State 設計與 routingJSON 解析失敗中斷流程

通用建議: 每個 Agent 的輸入/輸出都要有 schema 驗證,錯誤時要有 fallback,不要讓一個 Agent 的失敗癱瘓整個團隊。

下一篇(第三篇):如何評估系統效能、監控、部署與持續改善。


本系列文章: