This project is a minimal weather app built to show where LangGraph differs from plain LangChain.
Instead of letting a chain or agent decide everything in one implicit flow, this app makes the workflow explicit:
- Classify the user's intent with an LLM.
- Route execution to a graph node based on that intent.
- Call a real weather tool backed by Open-Meteo only for weather requests.
- Return a final response from the selected branch.
If you already know LangChain, the key difference in this example is control flow.
LangChaingives you the building blocks: prompts, models, tools, structured output.LangGraphadds explicit workflow orchestration: state, nodes, edges, and routing.
In this app:
- The intent classifier is a normal LangChain-style LLM call.
- The Open-Meteo weather tool is a normal LangChain tool.
- The router and branch execution are the LangGraph part.
That means you can see and control exactly how the program moves from one step to the next.
LangChain mirror project:
Essential difference:
- This LangGraph project models control flow explicitly with state + nodes + conditional edges.
- The LangChain mirror project relies on an agent loop where tool-use control flow is implicit.
START
|
v
classify_intent
|
+--> weather --> weather_node --> END
|
+--> chat ----> chat_node -----> END
|
+--> unknown -> unknown_node --> END
- Python 3.9+
MOONSHOT_API_KEYset in your environment
This demo uses:
- model:
kimi-k2.5 - temperature:
1.0 - base URL:
https://api.moonshot.cn/v1
python3 -m venv .venv
source .venv/bin/activate
pip install -e .This project is intended to run inside its local .venv only.
python3 app.pyExample prompts:
What's the weather in Shanghai tomorrow?Will it rain in Beijing?HelloHelp me write a SQL query
app.py: thin entrypoint that starts the CLIconfig.py: runtime constants and environment lookupmodels.py: shared state and structured output schemaslogging_utils.py: logging configuration and decoratorsllm.py: Moonshot client setup and LLM exchange loggingweather.py: Open-Meteo integration and weather formattinggraph.py: LangGraph nodes, routing, and graph assemblycli.py: interactive CLI loopdoc/design.md: design notes and function-by-function explanationpyproject.toml: project metadata and dependencies
- The weather tool resolves the location with Open-Meteo Geocoding and then fetches current plus short-range forecast data from Open-Meteo Forecast.
- The LLM is only used for intent classification and location extraction.
- The routing logic is explicit and deterministic after classification.
- The app logs function inputs, return values, LLM request/response payloads, and Open-Meteo HTTP request/response payloads.
- Logging is off by default. Set
APP_LOGGING=trueto enable detailed traces. - You can override the default endpoint with
MOONSHOT_BASE_URL. kimi-k2.5only accepts temperature1, so this project defaults to1.0.