AI Agent开发学习系列 - LangGraph(10): 带有循环的Looping Graph(练习解答)
在AI Agent开发学习系列 - LangGraph(9): 带有循环的Looping Graph中,我们学习了如何创建带有循环的Looping Graph。为了巩固学习,我们来做一个练习。
用LangGraph创建如下图的一个Agent:
要求:
- 输入玩家姓名
- 通过输入的上限值和下限值之间,随机出一个目标值,该目标值对玩家不可见。
- 大模型通过不断的猜目标值直到猜中
- 每猜一次目标值如果没猜中,给出猜大了还是猜小了,并且调整上限或者下限值
- 记录尝试次数
解答:
from typing import TypedDict, List
from langgraph.graph import StateGraph, END
import randomclass AgentState(TypedDict):player_name: strtarget_number: intguesses: List[int]attempts: intlower_bound: intupper_bound: intdef setup_node(state: AgentState) -> AgentState:"""Setup the game state"""state["target_number"] = random.randint(state["lower_bound"], state["upper_bound"])state["guesses"] = []state["attempts"] = 0state["lower_bound"] = state["lower_bound"]state["upper_bound"] = state["upper_bound"]state["player_name"] = f"Hi, {state["player_name"]}. Please start the game. Guess a number between {state["lower_bound"]} and {state["upper_bound"]}.\n================================================"print(state["player_name"])return statedef guess_node(state: AgentState) -> AgentState:"""Guess the number"""state["attempts"] += 1print(f"Guess attempts: {state['attempts']}")state["guesses"].append(random.randint(state["lower_bound"], state["upper_bound"]))print(f"I guess: {state['guesses'][-1]}")return statedef hint_node(state: AgentState) -> AgentState:"""Give a hint based on the guess"""if state["guesses"][-1] == state["target_number"]:print("Your guess is correct!")elif state["guesses"][-1] < state["target_number"]:state["lower_bound"] = state["guesses"][-1]print(f"Your guess is lower than the target number. Please guess a number between {state['lower_bound']} and {state['upper_bound']}.")else:state["upper_bound"] = state["guesses"][-1]print(f"Your guess is higher than the target number. Please guess a number between {state['lower_bound']} and {state['upper_bound']}.")return statedef should_continue(state: AgentState) -> AgentState:"""Function to decide what to do next"""if state["attempts"] < 7 and state["guesses"][-1] != state["target_number"]:print("Please guess again.")print("\n--------------------------------\n")return "loop"elif state["attempts"] >= 7 and state["guesses"][-1] != state["target_number"]:print(f"Game over! The target number is {state['target_number']}.")return "exit"else:return "exit"graph = StateGraph(AgentState)graph.add_node("setup", setup_node)
graph.add_node("guess", guess_node)
graph.add_node("hint", hint_node)graph.set_entry_point("setup")
graph.add_edge("setup", "guess")
graph.add_edge("guess", "hint")graph.add_conditional_edges("hint",should_continue,{"loop": "guess","exit": END,}
)app = graph.compile()from IPython.display import Image, display
display(Image(app.get_graph().draw_mermaid_png()))result = app.invoke({"player_name": "Alex", "lower_bound": 1, "upper_bound": 20})
# print(result)
运行结果(每一次运行结果有随机性,可能都不一样):
Hi, Alex. Please start the game. Guess a number between 1 and 20.
================================================
Guess attempts: 1
I guess: 10
Your guess is lower than the target number. Please guess a number between 10 and 20.
Please guess again.--------------------------------Guess attempts: 2
I guess: 16
Your guess is lower than the target number. Please guess a number between 16 and 20.
Please guess again.--------------------------------Guess attempts: 3
I guess: 18
Your guess is correct!