在使用Claude構建之前

決定是否使用Claude進行支援聊天

以下是一些關鍵指標,表明您應該使用像Claude這樣的LLM來自動化部分客戶支援流程:

選擇Claude而非其他LLM的一些考量因素:

  • 您優先考慮自然、細微的對話:Claude先進的語言理解能力允許更自然、更具情境感知的對話,比其他LLM的聊天感覺更像人類。
  • 您經常收到複雜且開放式的查詢:Claude可以處理廣泛的主題和查詢,無需生成制式回應或需要對用戶表述的各種排列進行大量編程。
  • 您需要可擴展的多語言支援:Claude的多語言能力使其能夠用超過200種語言進行對話,無需為每種支援的語言設置單獨的聊天機器人或進行大量翻譯處理。

定義您理想的聊天互動

概述理想的客戶互動,以定義您期望客戶如何以及何時與Claude互動。這個概述將有助於確定您解決方案的技術要求。

以下是汽車保險客戶支援的示例聊天互動:

  • 客戶:啟動支援聊天體驗
    • Claude:熱情地問候客戶並開始對話
  • 客戶:詢問關於他們新電動車的保險
    • Claude:提供有關電動車保險的相關信息
  • 客戶:詢問與電動車保險相關的獨特需求
    • Claude:提供準確且信息豐富的答案,並提供資料來源的連結
  • 客戶:提出與保險或汽車無關的離題問題
    • Claude:澄清不討論不相關的主題,並引導用戶回到汽車保險話題
  • 客戶:表示對保險報價感興趣
    • Claude:提出一系列問題以確定適當的報價,根據他們的回答進行調整
    • Claude:發送請求使用報價生成API工具以及從用戶收集的必要信息
    • Claude:接收來自API工具使用的回應信息,將信息合成為自然回應,並向用戶呈現提供的報價
  • 客戶:提出後續問題
    • Claude:根據需要回答後續問題
    • Claude:引導客戶進入保險流程的下一步並結束對話
在您為自己的用例編寫的實際示例中,您可能會發現寫出這種互動中的實際文字很有用,這樣您也可以了解您希望Claude具有的理想語調、回應長度和詳細程度。

將互動分解為獨特任務

客戶支援聊天是多種不同任務的集合,從回答問題到信息檢索再到對請求採取行動,所有這些都包含在單一客戶互動中。在開始構建之前,將您理想的客戶互動分解為您希望Claude能夠執行的每項任務。這確保您可以針對每項任務提示和評估Claude,並讓您對編寫測試案例時需要考慮的互動範圍有很好的了解。

客戶有時發現將此視覺化為可能的對話轉折點的互動流程圖很有幫助,這取決於用戶請求。

以下是與上述保險互動示例相關的關鍵任務:

  1. 問候和一般指導

    • 熱情地問候客戶並開始對話
    • 提供有關公司和互動的一般信息
  2. 產品信息

    • 提供有關電動車保險的信息
      這將要求Claude在其上下文中擁有必要的信息,並可能意味著需要RAG整合
    • 回答與電動車保險獨特需求相關的問題
    • 回答關於報價或保險詳情的後續問題
    • 在適當時提供資料來源的連結
  3. 對話管理

    • 保持在主題上(汽車保險)
    • 將離題問題重新引導回相關主題
  4. 報價生成

    • 提出適當的問題以確定報價資格
    • 根據客戶回應調整問題
    • 將收集的信息提交給報價生成API
    • 向客戶呈現提供的報價

建立成功標準

與您的支援團隊合作,定義明確的成功標準並編寫具有可衡量基準和目標的詳細評估

以下是可用於評估Claude執行定義任務的成功程度的標準和基準:

以下是可用於評估使用Claude進行支援的業務影響的標準和基準:

如何將Claude實現為客戶服務代理

選擇合適的Claude模型

模型的選擇取決於成本、準確性和響應時間之間的權衡。

對於客戶支援聊天,claude-opus-4-20250514非常適合平衡智能、延遲和成本。然而,對於包含RAG、工具使用和/或長上下文提示的多提示對話流程,claude-3-haiku-20240307可能更適合優化延遲。

構建強大的提示

使用Claude進行客戶支援需要Claude有足夠的指導和上下文來適當回應,同時具有足夠的靈活性來處理各種客戶查詢。

讓我們從編寫強大提示的元素開始,首先是系統提示:

IDENTITY = """你是Eva,Acme保險公司友好且知識豐富的AI助手。你的角色是熱情地歡迎客戶並提供有關
Acme保險產品的信息,包括汽車保險和電動車保險。你還可以幫助客戶獲取他們保險需求的報價。"""
雖然您可能會傾向於將所有信息放在系統提示中,作為將指令與用戶對話分開的方式,但Claude實際上在大部分提示內容寫在第一個User回合中時效果最佳(唯一的例外是角色提示)。在使用系統提示給Claude一個角色閱讀更多信息。

最好將複雜的提示分解為子部分,並一次編寫一部分。對於每個任務,您可能會通過遵循逐步過程來定義Claude執行任務所需的提示部分,從而獲得更大的成功。對於這個汽車保險客戶支援示例,我們將逐步編寫”問候和一般指導”任務的所有部分。這也使得調試您的提示更容易,因為您可以更快地調整整體提示的各個部分。

我們將把所有這些部分放在一個名為config.py的文件中。

STATIC_GREETINGS_AND_GENERAL = """
<static_context>
Acme汽車保險:您在路上的可信伴侶

關於:
在Acme保險,我們理解您的車輛不僅僅是一種交通工具——它是您生活冒險的通行證。
1985年以來,我們一直在設計汽車保險政策,讓駕駛者能夠自信地探索、通勤和旅行,心中充滿平靜。
無論您是在城市街道上導航還是踏上跨國公路旅行,Acme都在那裡保護您和您的車輛。
我們創新的汽車保險政策旨在適應您的獨特需求,涵蓋從小碰撞到重大事故的一切。
憑藉Acme獲獎的客戶服務和快速理賠解決方案,您可以專注於駕駛的樂趣,而我們處理其餘的事情。
我們不僅僅是保險提供商——我們是您生活旅程中的副駕駛。
選擇Acme汽車保險,體驗優質保障和真誠關懷帶來的保證。因為在Acme,我們不僅僅是為您的車投保——我們為您在開闊道路上的冒險提供動力。

注意:我們還為電動車提供專門的保險,確保所有類型的車輛駕駛者都能受益於我們的保護。

Acme保險提供以下產品:
- 汽車保險
- 電動車保險
- 二輪車保險

營業時間:週一至週五,上午9點至下午5點(東部標準時間)
客戶服務電話:1-800-123-4567
</static_context>
"""

然後我們將對汽車保險和電動車保險信息做同樣的處理。

STATIC_CAR_INSURANCE="""
<static_context>
汽車保險保障:
Acme的汽車保險政策通常涵蓋:
1. 責任保險:支付您對他人造成的人身傷害和財產損失。
2. 碰撞保險:支付事故中您車輛的損壞。
3. 綜合保險:支付非碰撞事件造成的車輛損壞。
4. 醫療費用保險:支付事故後的醫療費用。
5. 無保險/保險不足駕駛者保險:在您被保險不足的駕駛者撞擊時保護您。

可選保障包括:
- 租車報銷
- 道路救援
- 新車更換
</static_context>
"""

STATIC_ELECTRIC_CAR_INSURANCE="""
<static_context>
電動車保險:
我們專門的電動車保險超越了傳統的汽車保險,
為您的高科技投資提供量身定制的保護。除了標準保障外,我們還提供:
- 保護昂貴的電池系統
- 覆蓋家用充電設備
- 適應快速發展的電動車世界

無論您駕駛的是Rivian、Nissan Leaf、Chevrolet Bolt,
還是任何其他電動車,我們知識豐富的代理都準備好為您制定一份政策,
讓您有信心享受每一英里的電力驅動旅程。
</static_context>
"""

現在我們有了靜態內容,讓我們添加至少4-5個”良好”互動的樣本來指導Claude的回應。這些示例應該代表您理想的客戶互動,並可以包括護欄、工具調用等。

EXAMPLES="""
以下是您與客戶互動的幾個示例:

<example 1>
H: 嗨,你們提供小型企業的商業保險嗎?

A: 啊!很遺憾,我們目前不提供商業保險。
但是,我們確實提供一系列個人保險產品,包括汽車保險和電動車保險。
您想了解更多關於這些產品的信息嗎?
</example 1>

<example 2>
H: 嗨,你們的營業時間是什麼?

A: 我們的營業時間是週一至週五,上午9點至下午5點(東部標準時間)。
如果您有任何問題或需要幫助,請在這些時間內隨時聯繫我們。
我今天還能為您提供什麼幫助?
</example 2>

<example 3>
H: 我正在尋找汽車保險。Acme提供什麼?

A: 很好的選擇!Acme的汽車保險政策通常包括:
- 責任保險:在您造成事故時保護您
- 碰撞保險:支付事故中您車輛的損壞
- 綜合保險:涵蓋非碰撞事件如盜竊或破壞
- 醫療費用保險:支付事故後的醫療費用
- 無保險/保險不足駕駛者保險:保護您免受保險不足的駕駛者的傷害

我們還提供可選保障如租車報銷、道路救援和新車更換。
您想了解更多關於這些保障的詳情,還是對為您的車輛投保有特定問題?
</example 3>

<example 4>
H: 我想了解你們的電動車保險。

A: 當然!我們的電動車保險專為滿足電動車車主的獨特需求而設計。
除了我們為普通汽車提供的所有標準保障外,我們的電動車政策還包括:

- 電池保障:保護您車輛昂貴電池系統的損壞或退化
- 科技套餐:涵蓋先進電子設備和車載電腦系統的維修或更換
- 充電站保障:保護家用和便攜式充電設備
- 網絡安全保護:防範黑客攻擊或數字威脅的保障
- 專業道路救援:包括平板拖車以保護車輛底盤

我們涵蓋各種電動車,包括來自Tesla、Rivian、Nissan、Chevrolet等熱門品牌的車型。
您是否有特定的電動車需要投保,或者您想了解更多關於這些保障的詳情?
</example 4>

<example 5>
H: 我想為我的汽車獲取保險報價。

A: 當然!我很樂意幫助您獲取汽車保險報價。
為了提供準確的報價,我需要收集一些關於您的車輛和主要駕駛者的信息。
讓我們從基本信息開始:

1. 您的車輛是什麼品牌和型號?
2. 它是哪一年製造的?
3. 您大約行駛了多少英里?
4. 主要駕駛者的年齡是多少?

一旦您提供這些信息,我將使用我們的報價工具為您生成個性化的保險報價。
</example 5>
"""

您還需要包括任何重要的指示,概述Claude應如何與客戶互動的注意事項和禁忌。 這可能來自品牌護欄或支援政策。

ADDITIONAL_GUARDRAILS = """請遵守以下護欄:
1. 只提供我們產品列表中列出的保險類型的信息。
2. 如果被問及我們不提供的保險類型,請禮貌地說明我們不提供該服務。
3. 不要推測未來的產品供應或公司計劃。
4. 不要做出未經授權的承諾或達成協議。
您只提供信息和指導。
5. 不要提及任何競爭對手的產品或服務。
"""

現在讓我們將所有這些部分組合成一個字符串,用作我們的提示。

TASK_SPECIFIC_INSTRUCTIONS = ' '.join([
   STATIC_GREETINGS_AND_GENERAL,
   STATIC_CAR_INSURANCE,
   STATIC_ELECTRIC_CAR_INSURANCE,
   EXAMPLES,
   ADDITIONAL_GUARDRAILS,
])

通過工具使用添加動態和代理能力

Claude能夠使用客戶端工具使用功能執行操作和動態檢索信息。首先列出提示應使用的任何外部工具或API。

對於此示例,我們將從一個用於計算報價的工具開始。

提醒一下,此工具不會執行實際計算,它只會向應用程序發出信號,表明應該使用具有指定參數的工具。

保險報價計算器示例:

TOOLS = [{
  "name": "get_quote",
  "description": "根據用戶輸入計算保險報價。返回值為每月保費。",
  "input_schema": {
    "type": "object",
    "properties": {
      "make": {"type": "string", "description": "車輛品牌。"},
      "model": {"type": "string", "description": "車輛型號。"},
      "year": {"type": "integer", "description": "車輛製造年份。"},
      "mileage": {"type": "integer", "description": "車輛里程數。"},
      "driver_age": {"type": "integer", "description": "主要駕駛者的年齡。"}
    },
    "required": ["make", "model", "year", "mileage", "driver_age"]
  }
}]

def get_quote(make, model, year, mileage, driver_age):
    """返回每月保費(美元)"""
    # 您可以調用http端點或數據庫來獲取報價。
    # 在這裡,我們模擬1秒的延遲並返回固定報價100。
    time.sleep(1)
    return 100

部署您的提示

如果不在測試生產環境中部署提示並運行評估,很難知道您的提示效果如何,所以讓我們使用我們的提示、Anthropic SDK和streamlit作為用戶界面構建一個小型應用程序。

在名為chatbot.py的文件中,首先設置ChatBot類,該類將封裝與Anthropic SDK的交互。

該類應該有兩個主要方法:generate_messageprocess_user_input

from anthropic import Anthropic
from config import IDENTITY, TOOLS, MODEL, get_quote
from dotenv import load_dotenv

load_dotenv()

class ChatBot:
   def __init__(self, session_state):
       self.anthropic = Anthropic()
       self.session_state = session_state

   def generate_message(
       self,
       messages,
       max_tokens,
   ):
       try:
           response = self.anthropic.messages.create(
               model=MODEL,
               system=IDENTITY,
               max_tokens=max_tokens,
               messages=messages,
               tools=TOOLS,
           )
           return response
       except Exception as e:
           return {"error": str(e)}

   def process_user_input(self, user_input):
       self.session_state.messages.append({"role": "user", "content": user_input})

       response_message = self.generate_message(
           messages=self.session_state.messages,
           max_tokens=2048,
       )

       if "error" in response_message:
           return f"發生錯誤:{response_message['error']}"

       if response_message.content[-1].type == "tool_use":
           tool_use = response_message.content[-1]
           func_name = tool_use.name
           func_params = tool_use.input
           tool_use_id = tool_use.id

           result = self.handle_tool_use(func_name, func_params)
           self.session_state.messages.append(
               {"role": "assistant", "content": response_message.content}
           )
           self.session_state.messages.append({
               "role": "user",
               "content": [{
                   "type": "tool_result",
                   "tool_use_id": tool_use_id,
                   "content": f"{result}",
               }],
           })

           follow_up_response = self.generate_message(
               messages=self.session_state.messages,
               max_tokens=2048,
           )

           if "error" in follow_up_response:
               return f"發生錯誤:{follow_up_response['error']}"

           response_text = follow_up_response.content[0].text
           self.session_state.messages.append(
               {"role": "assistant", "content": response_text}
           )
           return response_text
      
       elif response_message.content[0].type == "text":
           response_text = response_message.content[0].text
           self.session_state.messages.append(
               {"role": "assistant", "content": response_text}
           )
           return response_text
      
       else:
           raise Exception("發生錯誤:意外的回應類型")

   def handle_tool_use(self, func_name, func_params):
       if func_name == "get_quote":
           premium = get_quote(**func_params)
           return f"已生成報價:每月${premium:.2f}"
      
       raise Exception("使用了意外的工具")

構建您的用戶界面

使用Streamlit和主方法測試部署此代碼。這個main()函數設置了基於Streamlit的聊天界面。

我們將在名為app.py的文件中執行此操作

import streamlit as st
from chatbot import ChatBot
from config import TASK_SPECIFIC_INSTRUCTIONS

def main():
   st.title("與Eva聊天,Acme保險公司的助手🤖")

   if "messages" not in st.session_state:
       st.session_state.messages = [
           {'role': "user", "content": TASK_SPECIFIC_INSTRUCTIONS},
           {'role': "assistant", "content": "已理解"},
       ]

   chatbot = ChatBot(st.session_state)

   # 顯示用戶和助手消息,跳過前兩條
   for message in st.session_state.messages[2:]:
       # 忽略工具使用塊
       if isinstance(message["content"], str):
           with st.chat_message(message["role"]):
               st.markdown(message["content"])

   if user_msg := st.chat_input("在此輸入您的消息..."):
       st.chat_message("user").markdown(user_msg)

       with st.chat_message("assistant"):
           with st.spinner("Eva正在思考..."):
               response_placeholder = st.empty()
               full_response = chatbot.process_user_input(user_msg)
               response_placeholder.markdown(full_response)

if __name__ == "__main__":
   main()

使用以下命令運行程序:

streamlit run app.py

評估您的提示

提示通常需要測試和優化才能準備好用於生產。要確定您解決方案的準備程度,請使用結合定量和定性方法的系統過程評估聊天機器人性能。基於您定義的成功標準創建強大的實證評估將使您能夠優化您的提示。

Anthropic控制台現在具有評估工具,允許您在各種情境下測試您的提示。

提高性能

在複雜情境中,除了標準提示工程技術護欄實施策略外,考慮其他策略來提高性能可能會有所幫助。以下是一些常見情境:

使用RAG減少長上下文延遲

在處理大量靜態和動態上下文時,在提示中包含所有信息可能導致高成本、較慢的響應時間和達到上下文窗口限制。在這種情況下,實施檢索增強生成(RAG)技術可以顯著提高性能和效率。

通過使用像Voyage這樣的嵌入模型將信息轉換為向量表示,您可以創建一個更可擴展和響應迅速的系統。這種方法允許基於當前查詢動態檢索相關信息,而不是在每個提示中包含所有可能的上下文。

為支援用例實施RAG RAG配方已被證明可以在具有大量上下文要求的系統中提高準確性、減少響應時間和降低API成本。

通過工具使用整合實時數據

在處理需要實時信息的查詢時,如帳戶餘額或政策詳情,基於嵌入的RAG方法是不夠的。相反,您可以利用工具使用來顯著增強您的聊天機器人提供準確、實時回應的能力。例如,您可以使用工具使用來查找客戶信息、檢索訂單詳情,並代表客戶取消訂單。

這種方法,在我們的工具使用:客戶服務代理配方中概述,允許您將實時數據無縫整合到Claude的回應中,並提供更個性化和高效的客戶體驗。

加強輸入和輸出護欄

在部署聊天機器人時,特別是在客戶服務情境中,防止與誤用、超出範圍的查詢和不適當回應相關的風險至關重要。雖然Claude本身對這些情境具有彈性,但以下是加強聊天機器人護欄的額外步驟:

  • 減少幻覺:實施事實檢查機制和引用,使回應基於提供的信息。
  • 交叉檢查信息:驗證代理的回應與您公司的政策和已知事實一致。
  • 避免合同承諾:確保代理不做出未經授權的承諾或達成協議。
  • 減輕越獄:使用無害性篩選和輸入驗證等方法,防止用戶利用模型漏洞,旨在生成不適當的內容。
  • 避免提及競爭對手:實施競爭對手提及過濾器,以維持品牌焦點,不提及任何競爭對手的產品或服務。
  • 保持Claude的角色:防止Claude改變其上下文風格,即使在長時間、複雜的互動中也是如此。
  • 移除個人身份信息(PII):除非明確要求並授權,否則從回應中刪除任何PII。

通過流式傳輸減少感知響應時間

在處理可能冗長的回應時,實施流式傳輸可以顯著提高用戶參與度和滿意度。在這種情況下,用戶逐步接收答案,而不是等待整個回應生成。

以下是如何實施流式傳輸:

  1. 使用Anthropic流式API支持流式回應。
  2. 設置您的前端以處理傳入的文本塊。
  3. 顯示每個塊,模擬實時打字。
  4. 實施機制保存完整回應,允許用戶在導航離開並返回時查看。

在某些情況下,流式傳輸使得使用具有更高基礎延遲的更高級模型成為可能,因為漸進式顯示減輕了較長處理時間的影響。

擴展您的聊天機器人

隨著聊天機器人複雜性的增長,您的應用程序架構可以相應發展。在向架構添加更多層之前,請考慮以下不太詳盡的選項:

  • 確保您充分利用提示並通過提示工程進行優化。使用我們的提示工程指南編寫最有效的提示。
  • 向提示添加額外的工具(可以包括提示鏈),看看是否可以實現所需功能。

如果您的聊天機器人處理極其多樣化的任務,您可能需要考慮添加單獨的意圖分類器來路由初始客戶查詢。對於現有應用程序,這將涉及創建一個決策樹,通過分類器路由客戶查詢,然後到專門的對話(具有自己的工具集和系統提示)。請注意,此方法需要對Claude進行額外調用,可能增加延遲。

將Claude整合到您的支援工作流程中

雖然我們的示例專注於Streamlit環境中可調用的Python函數,但部署Claude進行實時支援聊天機器人需要API服務。

以下是您可以採取的方法:

  1. 創建API包裝器:圍繞您的分類函數開發一個簡單的API包裝器。例如,您可以使用Flask API或Fast API將您的代碼包裝成HTTP服務。您的HTTP服務可以接受用戶輸入並完整返回助手回應。因此,您的服務可以具有以下特性:

    • 服務器發送事件(SSE):SSE允許從服務器到客戶端的實時回應流。這對於使用LLM時提供流暢、互動的體驗至關重要。
    • 緩存:實施緩存可以顯著提高響應時間並減少不必要的API調用。
    • 上下文保留:當用戶導航離開並返回時維持上下文對於對話的連續性很重要。
  2. 構建網頁界面:實施用戶友好的網頁UI,用於與Claude驅動的代理互動。