前言
本教程基于吴恩达与 Harrison Chase 的公开课《LangChain for LLM Application Development》改编。由于 LangChain 已更新至 1.0,原视频中的许多方法已被弃用,故本教程采用新版进行重新整理。
Lesson 1:模型,提示词和输出解析(Models, Prompts and Output Parsers)
Model
创建模型
from dotenv import load_dotenv, find_dotenv
import os
from langchain.chat_models import init_chat_model
_ = load_dotenv(find_dotenv())
model_name = os.environ['MODEL_NAME']
api_key = os.environ['API_KEY']
temperature = 0.0
chat = init_chat_model(model=model_name, api_key=api_key, temperature=temperature)Prompt template
使用提示词
template_string = """Translate the text \
that is delimited by triple backticks \
into a style that is {style}. \
text: ```{text}```
"""
from langchain_core.prompts import ChatPromptTemplate
prompt_template = ChatPromptTemplate.from_template(template_string)
customer_style = """American English \
in a calm and respectful tone
"""
customer_email = """
Arrr, I be fuming that me blender lid \
flew off and splattered me kitchen walls \
with smoothie! And to make matters worse, \
the warranty don't cover the cost of \
cleaning up me kitchen. I need yer help \
right now, matey!
"""
customer_messages = prompt_template.format_messages(
style=customer_style,
text=customer_email,)
print(customer_messages[0])
customer_response = chat.invoke(customer_messages)
print(customer_response.content)Output Parser
使用JsonOutputParser定义输出样式
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
class ReviewOutput(BaseModel):
gift: bool = Field(
description="Was the item purchased as a gift for someone else? Answer True if yes,False if not or unknown."
)
delivery_days: int = Field(
description="How many days did it take for the product to arrive? If this information is not found,output -1."
)
price_value: list[str] = Field(
description="Extract any sentences about the value or price, and output them as a comma separated Python list."
)
output_parser = JsonOutputParser(pydantic_object=ReviewOutput)
format_instructions = output_parser.get_format_instructions()输入提示词文本
customer_review = """\
This leaf blower is pretty amazing. It has four settings:\
candle blower, gentle breeze, windy city, and tornado. \
It arrived in two days, just in time for my wife's \
anniversary present. \
I think my wife liked it so much she was speechless. \
So far I've been the only one using it, and I've been \
using it every other morning to clear the leaves on our lawn. \
It's slightly more expensive than the other leaf blowers \
out there, but I think it's worth it for the extra features.
"""
review_template = """\
For the following text, extract the following information:
gift: Was the item purchased as a gift for someone else? \
Answer True if yes, False if not or unknown.
delivery_days: How many days did it take for the product\
to arrive? If this information is not found, output -1.
price_value: Extract any sentences about the value or price,\
and output them as a comma separated Python list.
text: {text}
{format_instructions}
"""方法一:手动调用方式
prompt = ChatPromptTemplate.from_template(template=review_template)
messages = prompt.format_messages(text=customer_review,
format_instructions=format_instructions)
response = chat.invoke(messages)方法二:链式解析方式
prompt = ChatPromptTemplate.from_template(template=review_template).partial(format_instructions=format_instructions)
chain = prompt | chat | output_parser
response = chain.invoke({"text": customer_review})
print(response)Lesson 2:记忆(Memory)
ConversationBufferMemory
保存完整的对话历史,每次调用模型时,把之前所有对话原文都传给模型。
现版本取消了ConversationBufferMemory的方法,改为使用langgraph.checkpoint.memory 的InMemorySaver
创建基础Agent
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver
from dotenv import load_dotenv, find_dotenv
import os
_ = load_dotenv(find_dotenv())
model_name = os.environ['MODEL_NAME']
api_key = os.environ['API_KEY']
temperature = 0.0
llm = init_chat_model(model=model_name, api_key=api_key, temperature=temperature)
memory = InMemorySaver()
conversation = create_agent(
model=llm,
tools=[],
checkpointer=memory,
)
config = {"configurable": {"thread_id": "user_001"}}多轮对话测试
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "Hi, my name is Andrew"
}
]
},
config=config
)
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "What is 1+1?"
}
]
},
config=config
)
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "What is my name?"
}
]
},
config=config
)
# 查看历史对话
state = conversation.get_state(config)
for message in state.values["messages"]:
print(message)手动增加历史对话
from langchain_core.messages import HumanMessage, AIMessage
history = [
HumanMessage(content="Hi"),
AIMessage(content="What's up"),
HumanMessage(content="Not much, just hanging"),
AIMessage(content="Cool"),
]
conversation.update_state(
config=config,
values={"messages": history}
)
# 查看历史对话
state = conversation.get_state(config)
for message in state.values["messages"]:
print(message)ConversationBufferWindowMemory
只保留最近k轮对话,更早的对话直接丢弃。相当于一个“滑动窗口”。
现版本的LangChain已经不存在ConversationBufferWindowMemory方法,该方法已经被拆分成了langchain_core.messages的trim_messages和langgraph.checkpoint.memory 的InMemorySaver
创建基础Agent
from langchain_core.messages import HumanMessage, AIMessage, trim_messages, RemoveMessage
from langchain.agents.middleware import before_model
from langgraph.checkpoint.memory import InMemorySaver
# 控制模型保留消息能力
trimmer = trim_messages(
max_tokens=2,
token_counter=len,
strategy="last",
start_on="human",
include_system=False,
)
# 模型调用前裁剪历史
@before_model
def trim_history(state, runtime):
trimmed = trimmer.invoke(state["messages"])
keep_ids = {m.id for m in trimmed}
message = {"messages": [RemoveMessage(id=m.id) for m in state["messages"] if m.id not in keep_ids]}
return message
memory = InMemorySaver()
conversation = create_agent(
model=llm,
tools=[],
checkpointer=memory,
middleware=[trim_history],
)
config = {"configurable": {"thread_id": "user_002"}}
conversation.update_state(config, {"messages": [
HumanMessage("Hi"),
AIMessage("What's up"),
]})
conversation.update_state(config, {"messages": [
HumanMessage("Not much, just hanging"),
AIMessage("Cool"),
]})
# 查看注入对话
print([m.content for m in conversation.get_state(config).values["messages"]])多轮对话测试
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "Hi, my name is Andrew"
}
]
},
config=config
)
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "What is 1+1?"
}
]
},
config=config
)
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "What is my name?"
}
]
},
config=config
)
# 查看历史对话
state = conversation.get_state(config)
for message in state.values["messages"]:
print(message)ConversationTokenBufferMemory
不按“轮数”限制,而是按Token数量 限制保留最近的对话。超过设定token上限后,从最旧的消息开始丢弃。
现版本的LangChain已经不存在ConversationTokenBufferMemory方法,该方法已经被拆分成了langchain_core.messages的trim_messages和langgraph.checkpoint.memory 的InMemorySaver
创建基础Agent
from langchain_core.messages import HumanMessage, AIMessage, trim_messages, RemoveMessage
from langchain.agents.middleware import before_model
from langgraph.checkpoint.memory import InMemorySaver
# 控制模型保留消息能力
trimmer = trim_messages(
max_tokens=30,
token_counter="approximate",
strategy="last",
start_on="human",
include_system=False,
)
# 模型调用前裁剪历史
@before_model
def trim_history(state, runtime):
trimmed = trimmer.invoke(state["messages"])
keep_ids = {m.id for m in trimmed}
message = {"messages": [RemoveMessage(id=m.id) for m in state["messages"] if m.id not in keep_ids]}
return message
memory = InMemorySaver()
conversation = create_agent(
model=llm,
tools=[],
checkpointer=memory,
middleware=[trim_history],
)
config = {"configurable": {"thread_id": "user_003"}}
conversation.update_state(config, {"messages": [
HumanMessage("Hi"),
AIMessage("What's up"),
]})
conversation.update_state(config, {"messages": [
HumanMessage("Not much, just hanging"),
AIMessage("Cool"),
]})
conversation.update_state(config, {"messages": [
HumanMessage("What is on the schedule today?"),
AIMessage(schedule),
]})
# 查看注入对话
print([m.content for m in conversation.get_state(config).values["messages"]])多轮对话测试
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "Hi, my name is Andrew"
}
]
},
config=config
)
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "What is 1+1?"
}
]
},
config=config
)
conversation.invoke(
{
"messages": [
{
"role": "user",
"content": "What is my name?"
}
]
},
config=config
)
# 查看历史对话
state = conversation.get_state(config)
for message in state.values["messages"]:
print(message)ConversationSummaryMemory
不保存完整对话原文,而是用 LLM 把历史对话不断总结成一段摘要。之后传给模型的是摘要,而不是原始对话。
现版本的LangChain已经不存在ConversationSummaryMemory方法,该方法已经被拆分成了langchain.agents.middleware的SummarizationMiddleware和langgraph.checkpoint.memory 的InMemorySaver
创建基础Agent
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware
from langgraph.checkpoint.memory import InMemorySaver
summary_history = SummarizationMiddleware(
model=llm,
trigger=("tokens", 100),
keep=("messages", 2),
)
conversation = create_agent(
model=llm,
tools=[],
checkpointer=InMemorySaver(),
middleware=[summary_history,],
)
config = {"configurable": {"thread_id": "user_004"}}注入历史消息
conversation.update_state(config, {"messages": [
HumanMessage("Hi"),
AIMessage("What's up"),
]})
conversation.update_state(config, {"messages": [
HumanMessage("Not much, just hanging"),
AIMessage("Cool"),
]})
schedule = "There is a meeting at 8am with your product team. \
You will need your powerpoint presentation prepared. \
9am-12pm have time to work on your LangChain \
project which will go quickly because Langchain is such a powerful tool. \
At Noon, lunch at the italian resturant with a customer who is driving \
from over an hour away to meet you to understand the latest in AI. \
Be sure to bring your laptop to show the latest LLM demo."
conversation.update_state(config, {"messages": [
HumanMessage("What is on the schedule today?"),
AIMessage(schedule),
]})
# 查看注入消息
print([m.content for m in conversation.get_state(config).values["messages"]])测试压缩情况
conversation.invoke(
{"messages": [HumanMessage("What would be a good demo to show?")]},
config,
)
state = conversation.get_state(config)
for message in state.values["messages"]:
print(message)Lesson 3:链式(Chains)
LangChain
from langchain.chat_models import init_chat_model
from langchain_core.prompts import ChatPromptTemplate
from dotenv import load_dotenv, find_dotenv
import os
_ = load_dotenv(find_dotenv())
model_name = os.environ['MODEL_NAME']
api_key = os.environ['API_KEY']
temperature = 0.9
llm = init_chat_model(model=model_name, api_key=api_key, temperature=temperature)
prompt = ChatPromptTemplate.from_template(
"What is the best name to describe \
a company that makes {product}?"
)
chain = prompt | llm
product = "Queen Size Sheet Set"
chain.invoke({"product": product})SimpleSequentialChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# prompt template 1
first_prompt = ChatPromptTemplate.from_template(
"What is the best name to describe a company that makes {product}?"
)
# Chain 1
chain_one = first_prompt | llm | StrOutputParser()
# prompt template 2
second_prompt = ChatPromptTemplate.from_template(
"Write a 20 words description for the following company: {company_name}"
)
# chain 2
chain_two = second_prompt | llm | StrOutputParser()
overall_simple_chain = {"company_name": chain_one} | chain_two
product = "Queen Size Sheet Set"
overall_simple_chain.invoke({"product": product})SequentialChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# prompt template 1: translate to english
first_prompt = ChatPromptTemplate.from_template(
"Translate the following review to english:"
"\n\n{Review}"
)
# chain 1: input= Review and output= English_Review
chain_one = first_prompt | llm | StrOutputParser()
second_prompt = ChatPromptTemplate.from_template(
"Can you summarize the following review in 1 sentence:"
"\n\n{English_Review}"
)
# chain 2: input= English_Review and output= summary
chain_two = second_prompt | llm | StrOutputParser()
# prompt template 3: translate to english
third_prompt = ChatPromptTemplate.from_template(
"What language is the following review:\n\n{Review}"
)
# chain 3: input= Review and output= language
chain_three = third_prompt | llm | StrOutputParser()
# prompt template 4: follow up message
fourth_prompt = ChatPromptTemplate.from_template(
"Write a follow up response to the following "
"summary in the specified language:"
"\n\nSummary: {summary}\n\nLanguage: {language}"
)
# chain 4: input= summary, language and output= followup_message
chain_four = fourth_prompt | llm | StrOutputParser()
overall_chain = (RunnablePassthrough.assign(English_Review=chain_one)
| RunnablePassthrough.assign(summary=chain_two)
| RunnablePassthrough.assign(language=chain_three)
| RunnablePassthrough.assign(followup_message=chain_four)
)
review = df.Review[5]
overall_chain.invoke({"Review": review})Router Chain
专家prompt
physics_template = """You are a very smart physics professor. \
You are great at answering questions about physics in a concise\
and easy to understand manner. \
When you don't know the answer to a question you admit\
that you don't know.
Here is a question:
{input}"""
math_template = """You are a very good mathematician. \
You are great at answering math questions. \
You are so good because you are able to break down \
hard problems into their component parts,
answer the component parts, and then put them together\
to answer the broader question.
Here is a question:
{input}"""
history_template = """You are a very good historian. \
You have an excellent knowledge of and understanding of people,\
events and contexts from a range of historical periods. \
You have the ability to think, reflect, debate, discuss and \
evaluate the past. You have a respect for historical evidence\
and the ability to make use of it to support your explanations \
and judgements.
Here is a question:
{input}"""
computerscience_template = """ You are a successful computer scientist.\
You have a passion for creativity, collaboration,\
forward-thinking, confidence, strong problem-solving capabilities,\
understanding of theories and algorithms, and excellent communication \
skills. You are great at answering coding questions. \
You are so good because you know how to solve a problem by \
describing the solution in imperative steps \
that a machine can easily interpret and you know how to \
choose a solution that has a good balance between \
time complexity and space complexity.
Here is a question:
{input}"""
prompt_infos = [
{
"name": "physics",
"description": "Good for answering questions about physics",
"prompt_template": physics_template
},
{
"name": "math",
"description": "Good for answering math questions",
"prompt_template": math_template
},
{
"name": "History",
"description": "Good for answering history questions",
"prompt_template": history_template
},
{
"name": "computer science",
"description": "Good for answering computer science questions",
"prompt_template": computerscience_template
}
]定义Agent路由
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnableBranch, RunnableLambda
from pydantic import BaseModel, Field
from typing import Literal
destination_chains = {
p["name"]: ChatPromptTemplate.from_template(p["prompt_template"]) | llm | StrOutputParser()
for p in prompt_infos
}
default_chain = ChatPromptTemplate.from_template("{input}") | llm | StrOutputParser()
class Route(BaseModel):
"""Route a user query to the most relevant expert."""
destination: Literal["physics", "math", "History", "computer science", "DEFAULT"] = Field(
description="The expert best suited for the question, or DEFAULT if none fits."
)
next_inputs: str = Field(
description="A potentially revised version of the original input."
)构建路由链
destinations_str = "\n".join(f"{p['name']}: {p['description']}" for p in prompt_infos)
router_prompt = ChatPromptTemplate.from_messages([
("system",
"Given a raw text input to a language model, select the prompt best suited for it.\n"
"You may also revise the original input if that leads to a better response.\n\n"
"<< CANDIDATE PROMPTS >>\n{destinations}"),
("human", "{input}"),
])
router_chain = (
router_prompt.partial(destinations=destinations_str)
| llm.with_structured_output(Route)
)
overall_chain = (
router_chain
| {
"destination": RunnableLambda(lambda x: x.destination),
"input": RunnableLambda(lambda x: x.next_inputs)
}
| RunnableBranch(
(lambda s: s["destination"] == "physics", destination_chains["physics"]),
(lambda s: s["destination"] == "math", destination_chains["math"]),
(lambda s: s["destination"] == "History", destination_chains["History"]),
(lambda s: s["destination"] == "computer science", destination_chains["computer science"]),
default_chain
)
)
overall_chain.invoke({"input": "What is black body radiation?"})Lesson 4:Q&A
加载第三方库
from langchain_huggingface import HuggingFaceEmbeddings
# 根据你的Embedding模型进行选择,这里使用huggingface的做快速验证
# from langchain_openai import OpenAIEmbeddings
from langchain.chat_models import init_chat_model
from langchain_community.document_loaders import CSVLoader
from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from IPython.display import display, Markdown
from dotenv import load_dotenv, find_dotenv
import os
from langchain.chat_models import init_chat_model
_ = load_dotenv(find_dotenv())
model_name = os.environ['MODEL_NAME']
api_key = os.environ['API_KEY']
temperature = 0.0
llm = init_chat_model(model=model_name, api_key=api_key, temperature=temperature)加载文档
file = 'OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file,encoding="utf-8")
docs = loader.load()
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2",
model_kwargs={"device": "cuda"},
encode_kwargs={"normalize_embeddings": True},
)
# embeddings = OpenAIEmbeddings()
vectorstore = DocArrayInMemorySearch.from_documents(docs, embeddings)
retriever = vectorstore.as_retriever()构建Q&A
自动版本
prompt = ChatPromptTemplate.from_template(
"基于以下上下文回答问题:\n\n{context}\n\n问题:{question}"
)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
query = "Please list all your shirts with sun protection in a table in markdown and summarize each one."
response = rag_chain.invoke(query)
display(Markdown(response))手动版本
存储向量
embed = embeddings.embed_query("Hi my name is Harrison")
print(len(embed))
print(embed[:5])
db = DocArrayInMemorySearch.from_documents(docs, embeddings)
query = "Please suggest a shirt with sunblocking"
docs = db.similarity_search(query)
retriever = db.as_retriever()测试提问
qdocs = "".join([docs[i].page_content for i in range(len(docs))])
response = llm.invoke(f"{qdocs} Question: Please list all your shirts with sun protection in a table in markdown and summarize each one.")
display(Markdown(response.content))Lesson 5:评估(Evaluation)
加载大模型
from dotenv import load_dotenv, find_dotenv
import os
from langchain.chat_models import init_chat_model
from langchain_huggingface import HuggingFaceEmbeddings
# 根据你的Embedding模型进行选择,这里使用huggingface的做快速验证
# from langchain_openai import OpenAIEmbeddings
from langchain_community.document_loaders import CSVLoader
from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_classic.chains import create_retrieval_chain
from langchain_classic.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
_ = load_dotenv(find_dotenv())
model_name = os.environ['MODEL_NAME']
api_key = os.environ['API_KEY']
temperature = 0.0
llm = init_chat_model(model=model_name, api_key=api_key, temperature=temperature)加载文本
file = 'OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file,encoding="utf-8")
docs = loader.load()
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2",
model_kwargs={"device": "cuda"},
encode_kwargs={"normalize_embeddings": True},
)
# embeddings = OpenAIEmbeddings()
vectorstore = DocArrayInMemorySearch.from_documents(docs, embeddings)
retriever = vectorstore.as_retriever()构建RAG链
system_prompt = (
"Use the following pieces of context to answer the user's question. "
"If you don't know the answer, just say that you don't know, "
"don't try to make up an answer.\n"
"----------------\n"
"{context}"
)
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
])
question_answer_chain = create_stuff_documents_chain(
llm,
prompt,
document_separator="<<<<>>>>>"
)
qa_chain = create_retrieval_chain(retriever, question_answer_chain)测试查询
examples = [
{
"query": "Do the Cozy Comfort Pullover Set have side pockets?",
"answer": "Yes"
},
{
"query": "What collection is the Ultra-Lofty 850 Stretch Down Hooded Jacket from?",
"answer": "The DownTek collection"
}
]
result = qa_chain.invoke({"input": examples[0]["query"]})
print(result["answer"])构建测试用例
from langchain_core.output_parsers import StrOutputParser
example_gen_prompt = ChatPromptTemplate.from_messages([
("system",
"You are a teacher. Given a document, generate one question and answer "
"based on the document. Output in JSON format with keys 'query' and 'answer'."),
("human", "{doc}")
])
example_gen_chain = example_gen_prompt | llm | StrOutputParser()
import json
new_examples = []
for doc in docs[:5]:
raw = example_gen_chain.invoke({"doc": doc.page_content})
parsed = json.loads(raw.strip("```json").strip("```"))
new_examples.append(parsed)
examples += new_examples评估
eval_prompt = ChatPromptTemplate.from_messages([
("system",
"You are a teacher grading a quiz. You are given a question, the ground truth "
"answer, and a student's answer. Grade the student's answer as CORRECT or INCORRECT.\n\n"
"Question: {query}\n"
"Ground truth: {answer}\n"
"Student answer: {result}"),
])
eval_chain = eval_prompt | llm | StrOutputParser()
predictions = [{"query": e["query"], "result": qa_chain.invoke({"input": e["query"]})["answer"]} for e in examples]
for i, (eg, pred) in enumerate(zip(examples, predictions)):
grade = eval_chain.invoke({
"query": eg["query"],
"answer": eg["answer"],
"result": pred["result"]
})
print(f"Example {i}: {grade}")Lesson 6:Agents
加载模型
from dotenv import load_dotenv, find_dotenv
import os
from langchain.chat_models import init_chat_model
_ = load_dotenv(find_dotenv())
model_name = os.environ['MODEL_NAME']
api_key = os.environ['API_KEY']
temperature = 0.0
llm = init_chat_model(model=model_name, api_key=api_key, temperature=temperature)LangChain自带工具
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
# Wikipedia 工具
wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
# DuckDuckGo 搜索工具
from langchain_community.tools import DuckDuckGoSearchRun
duckduckgo = DuckDuckGoSearchRun()调用工具
from langchain.agents import create_agent
from langchain_core.messages import HumanMessage
tools = [wikipedia, duckduckgo]
agent = create_agent(
model=llm,
tools=tools,
system_prompt="You are a helpful assistant. Use tools when needed."
)
# 调用方式:传入 messages 列表
result = agent.invoke({
"messages": [HumanMessage(content="What is the 25% of 300?")]
})
print(result["messages"][-1].content)
result = agent.invoke({
"messages": [HumanMessage(content="What is the Apple Inc.?")]
})
print(result["messages"][-1].content)通过LangSmith观察情况


可以看到当询问苹果公司的时候大模型去调用了维基百科的工具
自定义工具
from langchain_core.tools import tool
from datetime import date
@tool
def time(text: str) -> str:
"""Returns today's date. Use this for any questions related to
knowing today's date. The input should always be an empty string,
and this function will always return today's date - any date
mathematics should occur outside this function."""
return str(date.today())调用工具
tools_with_time = [wikipedia, duckduckgo, time]
agent_with_time = create_agent(
model=llm,
tools=tools_with_time,
system_prompt="You are a helpful assistant with access to web search, Wikipedia, and date tools."
)
try:
result = agent_with_time.invoke({
"messages": [HumanMessage(content="What's the date today?")]
})
print(result["messages"][-1].content)
except Exception as e:
print(f"exception: {e}")通过LangSmith观察情况
