Exercise: intelligent travel assistant agent (with solution)
- Source
- From the RAG & Agents Engineering course
- By
- Sourav Banerjee
- Last updated
- 9 Nov 2026
The project: an intelligent travel assistant
What you'll build
- A weather tool over a public weather API that returns a short summary or a readable error.
- A web-search tool that finds pages about a destination and returns the start of each page's text.
- A ReAct agent built with the agent factory, a use-case system prompt and a model-call cap.
- A check of tool selection before the agent exists, to see whether the tool descriptions lead the model to both tools.
The user types one word, a city such as Kolkata, and gets back the top attractions as bullet points plus a line on the current weather. The exercise notebook sets four tasks with a check after each; the solution works them.
The project adds no new pattern: lesson 2 of T7.2's agent factory and call cap, on two tools that reach the live web. What changes is that tools now fail in ordinary ways (an unknown city, a slow page, a site that refuses to be read) and return far more text than a stub.
Architecture
Figure 1: The travel assistant. The agent chooses the tools; each tool talks to one outside service.
| Piece | What it does | Built on |
|---|---|---|
| Weather tool | Calls the weather API in metric units and returns temperature, condition, humidity and wind, or the API's own reason for failing | The tool contract of lesson 3 of T7.1 |
| Web-search tool | Finds three pages, fetches them in parallel with a 15-second wait each, converts each to text and keeps the first 1,500 characters | Lesson 3 of T7.1's tool contract; lesson 5 of T7.1's errors returned as text |
| System prompt | States the use case: for any destination, search for attractions, get the weather, answer as bullets plus a weather summary | Lesson 2 of T7.2's factory |
| The agent | The factory's ReAct loop with a model-call cap of 6 that ends the run quietly | Lessons 1 and 2 of T7.2 |
Table 1: The four pieces.
The exercise brief names the LangChain 0.x agent executor; the notebooks use the 1.x factory (lesson 2 of T7.2's migration table).
Following a one-word request
Ask Kolkata. Nothing in the word says what to fetch; the system prompt supplies that. The solution expects the run to take this shape:
| Model call | What the model does | What comes back |
|---|---|---|
| 1 | Requests both tools in one turn, since neither needs the other | Two tool messages: the weather summary, and three page texts or short error strings |
| 2 | Reads both observations | The answer: attraction bullets, then the weather |
| 3 and on (only if a result is thin) | Searches again with other words | More page text, until the cap of 6 |
Table 2: The expected call order for a destination query.
Results change by the hour, so the notebooks print no fixed answer; the solution prints the tools called and the model-call count, which is what a check can rely on. Before building the agent it binds both tools and asks Show me local attractions in Bangalore and the weather in Bangalore: the model should return two tool calls. If it returns one, fix the descriptions, not the agent.
Design choices worth copying
| Choice | Why |
|---|---|
| Fail soft in every tool | An exception ends the run; an error string such as "Timeout extracting from" a page lets the agent answer from the pages that did load |
| Cut each page to 1,500 characters | Three full pages can fill the context window, and attractions usually sit near the top of a travel page (lesson 1 of T7.1's context creep) |
| Fetch pages in parallel and stop waiting | One slow site would otherwise stall the whole answer; stragglers are abandoned after 15 seconds |
| Cap model calls at 6 | Bounds cost if the agent keeps searching on a thin result (lesson 2 of T7.2's runaway loop) |
| No Thought and Action format in the prompt | Native tool calls need none, and the format would leak into the answer (lesson 1 of T7.2) |
Table 3: Five choices and what each protects against.
The first row has lesson 5 of T7.1's cost: an error returned as text reaches the model as a normal result, so monitoring that counts errors never sees it.
Limits
- No expected answer. Live search and weather mean a test can check behaviour (both tools called, then an answer) but not the text.
- Single turn. No checkpointer, so a follow-up starts from nothing; the exercise's bonus tasks add memory, more tools, several cities and streaming.
- Blind truncation. The first 1,500 characters can be a cookie banner rather than attractions.
The notebooks need an OpenAI key, a Tavily key for search and an OpenWeatherMap key for weather.
Run the notebooks
The code for this lesson is in these notebooks. Colab runs one in your browser: install the packages its first cell imports and set the API keys it reads. To run every notebook as written, clone the repository and use its uv environment.
| Notebook | GitHub | Colab |
|---|---|---|
| Intelligent travel assistant agent (optional) | Open on GitHub | Open in Colab |
| Intelligent travel assistant solution (optional) | Open on GitHub | Open in Colab |
Key Takeaways
- A use-case system prompt, two well-described tools and the agent factory with a call cap are the whole agent; the work is in making the tools behave on the live web.
- Tools over live sources must fail soft, cap what they return and stop waiting for slow pages, or one call can end the run or flood the context.
- Check tool selection with one bound call before building the loop, and test the agent on its call order, since the answer text changes every run.
Check yourself
1. The user types only Kolkata. Why does the agent call both tools, and why usually in a single model turn?
The system prompt says that any destination needs attractions and the current weather, so the model knows what the word asks for. Neither tool needs the other's result, so the model can request both in one reply and the tool node runs them before the model's second call.
2. Three pages come back from a search: one loads, one times out after 15 seconds and one blocks the request. What does the agent receive, and why is that better than an exception?
It receives the first 1,500 characters of the page that loaded and two short error strings for the others. An exception would end the run; error strings let the model answer from the page it has. The cost is that monitoring which counts exceptions never sees those failures.
3. In the tool-selection check, the model asks only for the web search when the question names attractions and weather. Where do you look first?
At the weather tool's description, because the model chooses tools from their names and descriptions. A description that does not say to use it whenever a destination, the weather or the temperature comes up leaves the model guessing. Fix it and repeat the one bound call before building the agent.