from typing import Annotated
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import Runnable, RunnableConfig
from typing_extensions import TypedDict
from langgraph.graph.message import AnyMessage, add_messages
messages: Annotated[list[AnyMessage], add_messages]
def __init__(self, runnable: Runnable):
self.runnable = runnable
def __call__(self, state: State, config: RunnableConfig):
result = self.runnable.invoke(state)
# 如果LLM碰巧返回了一个空响应,我们将重新提示它
if not result.tool_calls and (
or isinstance(result.content, list)
and not result.content[0].get("text")
messages = state["messages"] + [("user", "请给出真实的输出。")]
state = {**state, "messages": messages}
messages = state["messages"] + [("user", "请给出真实的输出。")]
state = {**state, "messages": messages}
return {"messages": result}
# llm = ChatAnthropic(model="claude-3-haiku-20240307")
llm = ChatAnthropic(model="claude-3-sonnet-20240229", temperature=1)
# from langchain_openai import ChatOpenAI
# llm = ChatOpenAI(model="gpt-4-turbo-preview")
assistant提示 = ChatPromptTemplate.from_messages(
" 使用提供的工具搜索航班、公司政策和其他信息以协助用户的查询。"
" 当搜索时,要坚持不懈。如果第一次搜索没有结果,扩大你的查询范围。"
" 如果搜索空手而归,请在放弃之前扩大你的搜索。"
"\n\n当前用户:\n<User>\n{user_info}\n</User>"
("placeholder", "{messages}"),
).partial(time=datetime.now())
# "阅读"仅工具(例如检索器)不需要用户确认即可使用
TavilySearchResults(max_results=1),
fetch_user_flight_information,
search_trip_recommendations,
part_3_sensitive_tools = [
update_ticket_to_new_flight,
sensitive_tool_names = {t.name for t in part_3_sensitive_tools}
# 我们的LLM不需要知道它必须路由到哪个节点。在它的"思维"中,它只是在调用函数。
part_3_assistant_runnable = assistant_prompt | llm.bind_tools(
part_3_safe_tools + part_3_sensitive_tools