Tools 就是外部功能的接口,Agent 可以根據需求主動呼叫:
👉 Agent 會判斷「何時使用工具」並將結果整合回回答。
pip install langchain-google-genai faiss-cpu langchain_community sentence-transformers requests
建立一個 faq.txt
檔案,內容如下:
Q: 什麼是 LangChain?
A: LangChain 是一個幫助開發者快速構建 LLM 應用的框架。
Q: 我可以用哪些 LLM 搭配 LangChain?
A: 可以用 OpenAI、Gemini、Claude、Llama 等多種模型。
Q: LangChain 的核心功能有哪些?
A: 包含 Chains、Memory、Tools、Agents。
Q: LangChain 的 Tools 有什麼用?
A: Tools 可以讓 Agent 呼叫外部工具,例如計算器、API、資料庫。
Q: LangChain 的 Agents 有什麼特色?
A: Agents 可以根據問題,自動決定要不要使用工具,並給出答案。
import os, requests, time
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.tools import Tool
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.agents import initialize_agent, AgentType
os.environ["GOOGLE_API_KEY"] = "" # Gemini API Key
API_KEY = "" # OpenWeatherMap API Key
UNITS, LANG = "metric", "zh_tw"
# 讀取 FAQ
with open("faq.txt", "r", encoding="utf-8") as f:
text = f.read()
# 切分文件
splitter = CharacterTextSplitter(chunk_size=200, chunk_overlap=50)
docs = splitter.create_documents([text])
# 建 Embeddings 與向量資料庫
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
vectorstore = FAISS.from_documents(docs, embeddings)
⚠️ 這裡用 eval
只是教學用,實務上要改成安全的 parser(例如 sympy
或 asteval
)。
def calculate(expression: str) -> str:
try: return str(eval(expression))
except Exception as e: return f"計算錯誤:{e}"
calc_tool = Tool(
name="Calculator",
func=calculate,
description="計算數學運算式,例如 2+3*5"
)
def get_weather(city: str, retries: int = 3, delay: int = 2) -> str:
url = "https://api.openweathermap.org/data/2.5/weather"
params = {"q": city, "appid": API_KEY, "units": UNITS, "lang": LANG}
for attempt in range(1, retries+1):
try:
r = requests.get(url, params=params, timeout=10)
data = r.json()
if data.get("cod") == 200:
w = data["weather"][0]["description"]
t, t_min, t_max = data["main"]["temp"], data["main"]["temp_min"], data["main"]["temp_max"]
return f"{data['name']} 天氣:{w}, 現在 {t}°C (範圍 {t_min}°C ~ {t_max}°C)"
else:
return f"取得天氣失敗:{data.get('message', '未知錯誤')}"
except Exception as e:
print(f"⚠️ 第 {attempt} 次錯誤: {e}")
if attempt < retries: time.sleep(delay)
return f"取得天氣失敗:重試 {retries} 次仍無法獲取 {city} 天氣"
weather_tool = Tool(
name="Weather",
func=get_weather,
description="查詢指定城市天氣,例如 '台北' 或 'Tokyo'"
)
def search_faq(query: str) -> str:
docs = vectorstore.similarity_search(query, k=3)
return "\n".join([d.page_content for d in docs]) if docs else ""
faq_tool = Tool(
name="FAQ",
func=search_faq,
description="查詢 FAQ 文件,用於回答技術或產品相關問題"
)
llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash", temperature=0)
agent = initialize_agent(
tools=[calc_tool, weather_tool, faq_tool],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # 讓 Agent 自動判斷是否使用工具
verbose=True
)
def hybrid_agent(query: str) -> str:
context = search_faq(query)
if context:
augmented = f"FAQ內容如下:\n{context}\n\n問題:{query}\n你可以使用 FAQ 或工具來回答。"
return agent.run(augmented)
return agent.run(query)
# 測試問題
questions = [
"什麼是 LangChain?", # FAQ → RAG
"2+3*5 等於多少?", # Calculator
"幫我查詢目前台北的天氣" # Weather
]
for q in questions:
print(f"> 問題: {q}")
print(f"> 回答: {hybrid_agent(q)}\n")
> 問題: 什麼是 LangChain?
> 回答: LangChain 是一個幫助開發者快速構建 LLM 應用的框架。
> 問題: 2+3*5 等於多少?
> 回答: 17
> 問題: 幫我查詢目前台北的天氣
> 回答: 台北天氣:晴, 現在 29.7°C (範圍 28°C ~ 31°C)
👉 你的 Agent 已經能做到 「思考 + 行動」 🎯
明天會先介紹Gradio後天再將我們的內容加上 互動式 UI(Gradio),讓使用者可以直接對話!