import os import gradio as gr from typing import TypedDict, Annotated from langgraph.graph.message import add_messages from langchain_core.messages import AnyMessage, AIMessage, HumanMessage from langgraph.prebuilt import ToolNode from langgraph.graph import START, StateGraph from langgraph.prebuilt import tools_condition from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace from tools import DuckDuckGoSearchRun, weather_info_tool, hub_stats_tool from retriever import guest_info_tool hf_token = os.getenv("HF_TOKEN") # 初始化网络搜索工具 search_tool = DuckDuckGoSearchRun() # 生成包含工具的聊天接口 llm = HuggingFaceEndpoint( repo_id="Qwen/Qwen2.5-Coder-32B-Instruct", huggingfacehub_api_token=hf_token, ) chat = ChatHuggingFace(llm=llm, verbose=True) tools = [guest_info_tool, search_tool, weather_info_tool, hub_stats_tool] chat_with_tools = chat.bind_tools(tools) # 生成 AgentState 和 Agent 图 class AgentState(TypedDict): messages: Annotated[list[AnyMessage], add_messages] def assistant(state: AgentState): return { "messages": [chat_with_tools.invoke(state["messages"])], } ## 构建流程图 builder = StateGraph(AgentState) # 定义节点:执行具体工作 builder.add_node("assistant", assistant) builder.add_node("tools", ToolNode(tools)) # 定义边:控制流程走向 builder.add_edge(START, "assistant") builder.add_conditional_edges( "assistant", # 如果最新消息需要工具调用,则路由到 tools 节点 # 否则直接响应 tools_condition, ) builder.add_edge("tools", "assistant") alfred = builder.compile() def predict(message, history): history_langchain_format = [] for msg in history: if msg['role'] == "user": history_langchain_format.append(HumanMessage(content=msg['content'])) elif msg['role'] == "assistant": history_langchain_format.append(AIMessage(content=msg['content'])) history_langchain_format.append(HumanMessage(content=message)) gpt_response = alfred.invoke({"messages": history_langchain_format}) return gpt_response["messages"][-1].content if __name__ == "__main__": demo = gr.ChatInterface( predict, type="messages" ) demo.launch()