chore: rename multiple files to improve importability and module structure
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import os
|
||||
from config import OPENAI_API_KEY,LANGCHAIN_API_KEY
|
||||
from langchain_core.messages import HumanMessage
|
||||
from langchain.tools import tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langgraph.graph import StateGraph, MessagesState, END,START
|
||||
from langgraph.prebuilt import ToolNode
|
||||
from langchain_core.messages import SystemMessage
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
os.environ["LANGCHAIN_TRACING_V2"] = "true" # 总开关,决定启用追踪功能
|
||||
os.environ["LANGCHAIN_PROJECT"] = "demo02" # 自定义项目名
|
||||
os.environ["LANGCHAIN_API_KEY"] = LANGCHAIN_API_KEY
|
||||
|
||||
# LLM配置
|
||||
llm = ChatOpenAI(
|
||||
model="deepseek-chat",
|
||||
api_key=OPENAI_API_KEY,
|
||||
base_url="https://api.deepseek.com"
|
||||
)
|
||||
|
||||
# Prompt配置
|
||||
sys_prompt = "你是一个强大的助手,能查天气,也能回答一般问题。请使用中文回答。"
|
||||
|
||||
# 工具定义
|
||||
@tool
|
||||
def get_weather(loaction):
|
||||
"""模拟获取天气"""
|
||||
return f'{loaction}当前天气:23℃,晴,风力2级'
|
||||
|
||||
|
||||
tools = [get_weather]
|
||||
llm_with_tools = llm.bind_tools(tools) # 让llm学会调用工具节点
|
||||
|
||||
|
||||
# --- 核心组件:拆解AgentExecutor ---
|
||||
# ReAct Step1:Thought(LLM决策)
|
||||
def call_model(state:MessagesState):
|
||||
# 构造带system prompt 的完整消息列表(仅用于本次LLM调用)
|
||||
message_for_llm = [SystemMessage(content=sys_prompt)]+state["messages"]
|
||||
response = llm_with_tools.invoke(message_for_llm)
|
||||
# 此处只会返回新生成的消息,不包含prompt,防止污染历史
|
||||
return {"messages":[response]} # 新消息追加到状态
|
||||
|
||||
|
||||
# ReAct Step2-3:Action + Observation
|
||||
tool_node = ToolNode(tools)
|
||||
|
||||
# ReAct Step4:Loop Controller(是否循环)
|
||||
def should_continue(state:MessagesState):
|
||||
last_msg = state["messages"][-1]
|
||||
if hasattr(last_msg,"tool_calls") and last_msg.tool_calls:
|
||||
return "tools" # 有工具调用 -> 执行工具
|
||||
return END # 无工具调用 -> 返回答案
|
||||
|
||||
|
||||
# --- 构建 ReAct 循环图---
|
||||
workflow = StateGraph(MessagesState)
|
||||
|
||||
workflow.add_node("agent",call_model) # Thought
|
||||
workflow.add_node("tools",tool_node) # Action + Observation
|
||||
|
||||
workflow.add_edge(START,"agent")
|
||||
|
||||
# 条件边:Thought -> 决定下一步
|
||||
workflow.add_conditional_edges(
|
||||
"agent", # 从哪个节点出发
|
||||
should_continue, # 决定下一步去哪
|
||||
{
|
||||
"tools":"tools", # 如果返回tools,去tools节点
|
||||
END:END # 如果返回END,直接结束工作流
|
||||
}
|
||||
)
|
||||
|
||||
workflow.add_edge("tools","agent")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 编译时启用记忆
|
||||
app = workflow.compile(checkpointer=MemorySaver())
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
session_id = "user123"
|
||||
config = {
|
||||
"configurable":{"thread_id":session_id}
|
||||
}
|
||||
while 1:
|
||||
user_input = input('\n你:')
|
||||
if user_input.strip().lower() == 'quit':
|
||||
break
|
||||
|
||||
result = app.invoke(
|
||||
{'messages':[HumanMessage(content=user_input)]},
|
||||
config=config
|
||||
)
|
||||
|
||||
ai_msg = result["messages"][-1]
|
||||
print(f'AI:{ai_msg.content}')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
from config import OPENAI_API_KEY,LANGCHAIN_API_KEY
|
||||
from langchain_core.messages import HumanMessage
|
||||
from langchain.tools import tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langgraph.graph import StateGraph, MessagesState, END,START
|
||||
from langgraph.prebuilt import ToolNode
|
||||
import os
|
||||
|
||||
os.environ["LANGCHAIN_TRACING_V2"] = "true" # 总开关,决定启用追踪功能
|
||||
os.environ["LANGCHAIN_PROJECT"] = "demo01" # 自定义项目名
|
||||
os.environ["LANGCHAIN_API_KEY"] = LANGCHAIN_API_KEY
|
||||
|
||||
# LLM配置
|
||||
llm = ChatOpenAI(
|
||||
model="deepseek-chat",
|
||||
api_key=OPENAI_API_KEY,
|
||||
base_url="https://api.deepseek.com"
|
||||
)
|
||||
|
||||
# 工具定义
|
||||
@tool
|
||||
def get_weather(loaction):
|
||||
"""模拟获取天气"""
|
||||
return f'{loaction}当前天气:23℃,晴,风力2级'
|
||||
|
||||
|
||||
tools = [get_weather]
|
||||
llm_with_tools = llm.bind_tools(tools) # 让llm学会调用工具节点
|
||||
|
||||
|
||||
# --- 核心组件:拆解AgentExecutor ---
|
||||
# ReAct Step1:Thought(LLM决策)
|
||||
def call_model(state:MessagesState):
|
||||
response = llm_with_tools.invoke(state['messages'])
|
||||
return {"messages":[response]} # 新消息追加到状态
|
||||
|
||||
|
||||
# ReAct Step2-3:Action + Observation
|
||||
tool_node = ToolNode(tools) # 工具节点函数,langgraph已封装
|
||||
|
||||
# ReAct Step4:Loop Controller(是否循环)
|
||||
def should_continue(state:MessagesState):
|
||||
last_msg = state["messages"][-1]
|
||||
if hasattr(last_msg,"tool_calls") and last_msg.tool_calls:
|
||||
return "tools" # 有工具调用 -> 执行工具
|
||||
return END # 无工具调用 -> 返回答案
|
||||
|
||||
|
||||
# --- 构建 ReAct 循环图---
|
||||
workflow = StateGraph(MessagesState)
|
||||
|
||||
workflow.add_node("agent",call_model) # Thought
|
||||
workflow.add_node("tools",tool_node) # Action + Observation
|
||||
|
||||
workflow.add_edge(START,"agent")
|
||||
|
||||
# 条件边:Thought -> 决定下一步
|
||||
workflow.add_conditional_edges(
|
||||
"agent", # 从哪个节点出发
|
||||
should_continue, # 决定下一步去哪
|
||||
{
|
||||
"tools":"tools", # 如果返回tools,去tools节点
|
||||
END:END # 如果返回END,直接结束工作流
|
||||
}
|
||||
)
|
||||
|
||||
workflow.add_edge("tools","agent") # 工具调用的结果再返回给agent节点
|
||||
|
||||
app = workflow.compile()
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 触发工具
|
||||
result = app.invoke(
|
||||
{"messages":[
|
||||
HumanMessage(content="北京天气如何?")
|
||||
]}
|
||||
)
|
||||
print('工具调用结果:',result['messages'][-1].content)
|
||||
# 不触发工具
|
||||
result = app.invoke({"messages":HumanMessage(content="你好")})
|
||||
print('直接回答:',result['messages'][-1].content)
|
||||
@@ -0,0 +1,43 @@
|
||||
from config import LANGCHAIN_API_KEY
|
||||
from typing import TypedDict
|
||||
from langgraph.graph import StateGraph,END,START
|
||||
import os
|
||||
|
||||
os.environ["LANGCHAIN_TRACING_V2"] = "true" # 总开关,决定启用追踪功能
|
||||
os.environ["LANGCHAIN_PROJECT"] = "my_demo" # 自定义项目名
|
||||
os.environ["LANGCHAIN_API_KEY"] = LANGCHAIN_API_KEY
|
||||
|
||||
|
||||
# 1. 定义State(状态) -- 白板上只有一个字段"count"
|
||||
class State(TypedDict):
|
||||
count:int
|
||||
|
||||
# 2. 编写Node(节点) -- 两个"工人"
|
||||
def node_a(state:State):
|
||||
# 接收当前State状态,返回要更新的部分
|
||||
print(f'[Node A]收到状态:{state}')
|
||||
return {"count":state["count"]+1}
|
||||
|
||||
def node_b(state:State):
|
||||
print(f'[Node B]收到状态:{state}')
|
||||
return {"count":state["count"]+1}
|
||||
|
||||
|
||||
# 3. 添加Node到图中
|
||||
workflow = StateGraph(State) # 创建画布
|
||||
workflow.add_node("A",node_a) # 添加节点A
|
||||
workflow.add_node("B",node_b) # 添加节点B
|
||||
|
||||
# 4. 用Edge连线
|
||||
workflow.add_edge(START,"A") # START -> A
|
||||
workflow.add_edge("A","B") # A -> B
|
||||
workflow.add_edge("B",END) # B -> END
|
||||
|
||||
# 编译成可运行应用
|
||||
app = workflow.compile()
|
||||
|
||||
# 传入初始状态,执行工作流
|
||||
print("---开始执行---")
|
||||
result = app.invoke({"count":1})
|
||||
print("最终状态:",result) # 输出{'count':4}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
from typing import TypedDict # 定义数据类型
|
||||
from langgraph.graph import StateGraph,END,START
|
||||
|
||||
|
||||
# 1. 定义State(状态) -- 白板上只有一个字段"count"
|
||||
class State(TypedDict):
|
||||
count:int
|
||||
|
||||
# 2. 编写Node(节点) -- 两个"工人"
|
||||
def node_a(state:State):
|
||||
# 接收当前State状态,返回要更新的部分
|
||||
print(f'[Node A]收到状态:{state}')
|
||||
return {"count":state["count"]+1}
|
||||
|
||||
def node_b(state:State):
|
||||
print(f'[Node B]收到状态:{state}')
|
||||
return {"count":state["count"]+1}
|
||||
|
||||
|
||||
# 3. 添加Node到图中
|
||||
workflow = StateGraph(State) # 创建画布
|
||||
workflow.add_node("A",node_a) # 添加节点A
|
||||
workflow.add_node("B",node_b) # 添加节点B
|
||||
|
||||
# 4. 用Edge连线
|
||||
workflow.add_edge(START,"A") # START -> A
|
||||
workflow.add_edge("A","B") # A -> B
|
||||
workflow.add_edge("B",END) # B -> END
|
||||
|
||||
# 编译成可运行应用
|
||||
app = workflow.compile()
|
||||
|
||||
# 传入初始状态,执行工作流
|
||||
print("---开始执行---")
|
||||
result = app.invoke({"count":1})
|
||||
print("最终状态:",result) # 输出{'count':4}
|
||||
|
||||
|
||||
# 保存可视化架构图
|
||||
with open('workflow.png', 'wb') as f:
|
||||
f.write(app.get_graph().draw_mermaid_png())
|
||||
print("图表已保存为 workflow.png")
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
Reference in New Issue
Block a user