用LangChain建立一個簡單的Agent,讓LLM根據使用者輸入決定是否呼叫工具(Tool),再將工具結果整理成自然語言回覆。
環境
Windows 11。
事前要求
Anthropic Claude Code取得API key。
LangChain 設定ANTHROPIC_API_KEY環境變數。
撰寫程式
開啟專案下的main.py,撰寫內容如下。
main.py
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_agent(
model="claude-sonnet-4-6",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
說明
首先定義一個get_weather函式模擬城市天氣查詢服務,此函式會在下面作為agent的tools參數的值,也就是Agent的可用工具(Tools)。函式中的docstring是給模型看的描述,讓模型理解此工具的用途並知道什麼時候該使用此工具。
呼叫LangChain的create_agent函式建立agent,輸入以下參數:
model:指定要使用的語言模型(Models)。tools:指定要使用的工具函式。system_prompt:給模型的系統提示詞,會被加在給模型的所有提示詞的最前面。
呼叫agent的invoke函式並傳入提示詞,agent的模型會根據輸入的提示詞判斷要調用的工具函式,並執行此工具函式並把函式的回傳結果重新組織為自然語言回傳為result為字典(dict),然後用result["messages"][-1].content_blocks取得最後一則訊息。
運作流程如下:
- 使用者輸入訊息給Agent
- Agent將訊息傳給模型
- 模型判斷需要呼叫工具並回傳工具呼叫請求
- Agent執行工具函式
- 工具函式回傳結果給Agent
- Agent將工具函式回傳結果再傳給模型
- 模型根據工具函式回傳結果產生最終回應
下面為result的內容,可以看到整個Agent的執行訊息鍊,即為Chain:
{
"messages": [
HumanMessage(
content="What's the weather in San Francisco?",
additional_kwargs={},
response_metadata={},
id="2740b058-d48f-4492-bf1b-10a34fc24b7b",
),
AIMessage(
content=[
{
"text": "I'll check the weather in San Francisco for you right away!",
"type": "text",
},
{
"id": "toolu_01P4XY4wKuTMhCZLksjFGMBm",
"caller": {"type": "direct"},
"input": {"city": "San Francisco"},
"name": "get_weather",
"type": "tool_use",
},
],
additional_kwargs={},
response_metadata={
"id": "msg_01TaTezo7NcoZMzQKWU9aZcD",
"container": None,
"model": "claude-sonnet-4-6",
"stop_details": None,
"stop_reason": "tool_use",
"stop_sequence": None,
"usage": {
"cache_creation": {
"ephemeral_1h_input_tokens": 0,
"ephemeral_5m_input_tokens": 0,
},
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"inference_geo": "global",
"input_tokens": 572,
"output_tokens": 68,
"output_tokens_details": None,
"server_tool_use": None,
"service_tier": "standard",
},
"model_name": "claude-sonnet-4-6",
"model_provider": "anthropic",
},
id="lc_run--019eb469-bbec-7871-ac3d-c1b96c11dc92-0",
tool_calls=[
{
"name": "get_weather",
"args": {"city": "San Francisco"},
"id": "toolu_01P4XY4wKuTMhCZLksjFGMBm",
"type": "tool_call",
}
],
invalid_tool_calls=[],
usage_metadata={
"input_tokens": 572,
"output_tokens": 68,
"total_tokens": 640,
"input_token_details": {
"cache_read": 0,
"cache_creation": 0,
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 0,
},
},
),
ToolMessage(
content="It's always sunny in San Francisco!",
name="get_weather",
id="7ecd7c32-fc60-4f30-93f9-6979e250cf70",
tool_call_id="toolu_01P4XY4wKuTMhCZLksjFGMBm",
),
AIMessage(
content="It looks like the weather in **San Francisco** is **sunny**! ☀️ It's a great day to head outside and enjoy the city. Is there anything else you'd like to know?",
additional_kwargs={},
response_metadata={
"id": "msg_01AaghU5JcDkof1RQDvGzMve",
"container": None,
"model": "claude-sonnet-4-6",
"stop_details": None,
"stop_reason": "end_turn",
"stop_sequence": None,
"usage": {
"cache_creation": {
"ephemeral_1h_input_tokens": 0,
"ephemeral_5m_input_tokens": 0,
},
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"inference_geo": "global",
"input_tokens": 659,
"output_tokens": 46,
"output_tokens_details": None,
"server_tool_use": None,
"service_tier": "standard",
},
"model_name": "claude-sonnet-4-6",
"model_provider": "anthropic",
},
id="lc_run--019eb469-c7da-7510-8564-f64b1e4f95ae-0",
tool_calls=[],
invalid_tool_calls=[],
usage_metadata={
"input_tokens": 659,
"output_tokens": 46,
"total_tokens": 705,
"input_token_details": {
"cache_read": 0,
"cache_creation": 0,
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 0,
},
},
),
]
}
測試
輸入uv run main.py執行,但我還沒買Anthropic Claude API的Credit所以跳出下面錯誤。
C:\langchain-demo>uv run main.py
anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.'}, 'request_id': 'req_011CbuHxjfNirc1WC2PdcdVz'}
若是沒設定API key,則出現以下錯誤。
TypeError: "Could not resolve authentication method. Expected one of api_key, auth_token, or credentials to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted"
若沒問題則執行結果如下。
C:\langchain-demo>uv run main.py
[{'type': 'text', 'text': "The weather in San Francisco is looking great — it's sunny! ☀️ Perfect weather to get outside and enjoy the city. Let me know if you'd like weather information for any other location!"}]
沒有留言:
張貼留言