@app.route("/travel/plan",methods=["POST"])defplan():data=request.get_json()origin=data.get("origin","Seattle")destination=data.get("destination","Paris")user_request=data.get("user_request",f"Planning a week-long trip from {origin} to {destination}. ""Looking for boutique hotel, flights and unique experiences.",)travellers=int(data.get("travellers",2))result=plan_travel_internal(origin=origin,destination=destination,user_request=user_request,travellers=travellers)returnjsonify(result),200
この流れを分かりやすく説明すると、次のようになります
Flask がリクエストを受信します
plan_travel_internal() がワークフローの状態を構築します
LangGraph がノードを実行します
各ノードが状態を更新します
最終的な旅程が JSON として返されます
知識チェック
この API フローにおいて、LangGraph のワークフローは実際にどこで実行が開始されますか?
このアプリにおける LangGraph のノードは、state を受け取り、更新された state を返す Python 関数です。
例えば、flight specialist は以下のようになります:
defflight_specialist_node(state:PlannerState)->PlannerState:llm=_create_llm("flight_specialist",temperature=0.4,session_id=state["session_id"])step=(f"Find an appealing flight from {state['origin']} to {state['destination']} "f"departing {state['departure']} for {state['travellers']} travellers.")messages=[SystemMessage(content="You are a flight booking specialist. Provide concise options."),HumanMessage(content=step),]result=llm.invoke(messages)state["flight_summary"]=result.contentstate["messages"].append(result)state["current_agent"]="hotel_specialist"returnstate
これは一般的なノードパターンを示しています:
LLM を作成またはアクセスする
構造化された state からプロンプトを構築する
モデルを呼び出す
結果を state に保存する
次のノードを設定する
hotel ノードと activity ノードも同じ構造に従っているため、ワークフローの説明が容易です。
messages=[SystemMessage(content="You are a flight booking specialist. Provide concise options."),HumanMessage(content=step),]result=llm.invoke(messages)
System message: AI の動作に関するルールとコンテキストを設定します。インタラクション全体を通じてモデルがどのように応答すべきかを導く指示、制約、トーン、および目標を定義します。
Human message: ユーザーからの入力です。AI が応答すべき質問、リクエスト、または情報を含みます。
AI message: モデルの応答です。システムの指示とユーザーの入力に基づいて、アシスタントが生成した出力を表します。
4.7 LLMの作成
LLMの作成
LLM自体はここで作成されます
def_create_llm(agent_name:str,*,temperature:float,session_id:str)->AzureChatOpenAI:azure_deployment_name=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME")azure_openai_api_version=os.getenv("AZURE_OPENAI_API_VERSION")returnAzureChatOpenAI(azure_deployment=azure_deployment_name,openai_api_version=azure_openai_api_version,temperature=temperature,model_name=azure_deployment_name,# AZURE_OPENAI_API_KEY and AZURE_OPENAI_ENDPOINT environment variables will be used to connect to the LLM)
def_create_llm(agent_name:str,*,temperature:float,session_id:str)->ChatOpenAI:model_name=os.getenv("OPENAI_MODEL_NAME","gpt-4o-mini")returnChatOpenAI(model=model_name,temperature=temperature,# Uses OPENAI_API_KEY automatically from environment)
4.8 Decomposition Pattern
シンセサイザーが分解パターンを示します
最後のノードは、各専門エージェントの出力を1つの回答にまとめます。
defplan_synthesizer_node(state:PlannerState)->PlannerState:llm=_create_llm("plan_synthesizer",temperature=0.3,session_id=state["session_id"])content=json.dumps({"flight":state["flight_summary"],"hotel":state["hotel_summary"],"activities":state["activities_summary"],},indent=2,)response=llm.invoke([SystemMessage(content="You are the travel plan synthesiser. Combine the specialist insights into a concise, structured itinerary."),HumanMessage(content=(f"Traveller request: {state['user_request']}\n\n"f"Origin: {state['origin']} | Destination: {state['destination']}\n"f"Dates: {state['departure']} to {state['return_date']}\n\n"f"Specialist summaries:\n{content}")),])state["final_itinerary"]=response.contentstate["messages"].append(response)state["current_agent"]="completed"returnstate