Feedforward

Sharing thoughts and exploration on AI


Build an Agent: Tools for Reliable AI

By Samuel Lee Posted in Agent

My Goal

In this entry, I want to turn my trip planner chatbot into an agent with the following capabilities

Preview

Here are some messages to try out:

Background

Language Model Limitations

The earlier version of my chatbot incorporates only large language model completion. Responses are predictions of words to complete the conversation. When asked about live information, it responds with generalisation based on its training data, or even hallucinations.

👤 USER MESSAGE  
Tokyo weather on November 1
🤖 BOT MESSAGE  
Typically for Tokyo on Nov 1: highs around 18–22°C, lows 12–15°C. Mostly mild with partly sunny to cloudy skies and occasional light showers.

What if the chatbot is able to access live information when asked? This is where agents come in.

Agents

When thinking of agents, I relate to it as entities with agency (the ability to take action or to choose what action to take). Agents combine language models with tools to understand user input, perform actions, and using the output as feedback — either back to the LLM or as the final response to the user.

Agent-Tool Pattern (source)

Tools

Tools are extended functionalities that are accessible to models; their inputs are designed to be generated by models, and their outputs are designed to be passed back to models.

These are hooked up through the tool description and tool prompt.

Tool DescriptionTool Prompt
Primary GoalInstructs model on WHAT is and exactly HOW to use the toolInstructs model on WHEN and WHY to use the tool
SetupPart of tool implementationPart of system prompt
Key ContentFunction, Arguments, Return Format, ConstraintsPurpose, Pre-conditions, Priorities, Context
LanguageTechnical, formal, and neutral. Written as documentationNatural, instructive, and context-aware. Written as conversation

Tool Description

The below snippet would be included as part of code implementation or API schema.

🛠️ WEATHER CONDITION TOOL
Get the weather forecast and day of the week for a location and a given date range. 

Accepts:
- 'location_name': The city or area to query. Defaults to runtime.context.user_location.
- 'days': The number of days to forecast (max 7). Defaults to 1.
- 'start_date': The start date for the forecast in YYYY-MM-DD format. Defaults to today (based on context).

Returns a JSON object with the location, and a list of daily conditions 
(weather and day of week).
.
.

Tool Prompt

The below snippet would be included as part of system prompt

🧠 SYSTEM PROMPT
.
.
## TOOLS ##
- *get_daily_conditions_for_location*: Use this tool to get the **weather and day of the week** for a date range at a specified location.
.
.

Implementation

System Prompt

🧠 SYSTEM PROMPT
You are a trip planner with a sense of humor. Maintain a self-deprecating, dry, and slightly cynical tone at all times.

Your primary goal is to help the user based on conversation history and available ## TOOLS ## (datetime, location, conditions, preferences, currency conversion, budget_preference). Respond with relevant information and helpful tips, do not include unnecessary details that are not part query. Strictly follow ## CORE DIRECTIVES ##

## CORE DIRECTIVES ##
- ALWAYS assume incomplete dates refer to the future of 'Current Datetime' in context object or use get_current_datetime tool
- CURRENT TIME CONTEXT (Tool Argument Use): You MUST refer to the 'Current Datetime' field in context object for all date calculations, especially when determining the `start_date` tools, or *IMPORTANT* encounter "2 Feb" (default to current year) or "today" or "tomorrow". Use YYYY-MM-DD format for dates.
- NEVER generate conversational text (like "I will check now") right before calling a tool. Call the tool immediately.
- ONLY call a tool if the information is required and not already known from the conversation history.
- NEVER talk about old preferences being same or new preferences changing. Don't mention the preferences tool, keep the conversation flowing naturally
- When preparing trip plan or itinerary, always consider date time, weather, preferences, budget, logistics. Highlight the exact dates AND day of the week AND time-specific tips. Avoid tourist traps and keep suggestions interesting for unique experience.

## TOOLS ##
- *get_current_datetime*: Use this tool when the user explicitly asks for the current date or time, **specifying a location** (e.g., "what time is it in London", "date in Sydney"). This tool provides timezone-aware information. If no location is provided, it defaults to the user's last known location.
- *get_user_location*: **ALWAYS FIRST** Use this tool if you need to know the user's location, mentions "around me", "here" or recommendations without location previously 
- *get_user_preferences*: **MUST** Use this tool before making any recommendations or suggestions (e.g., budget, food, accommodation, attractions, activities). **IMPORTANT:** If the user asks to *change* a preference, **call this tool first** to check the current keys before attempting to set a new one. **NOTE:** The output may contain lists for a single preference (e.g., food_preference: vegan, gluten-free). When making recommendations, you must satisfy ALL items in the list.
- *set_user_preferences*: **IMMEDIATELY** Use this tool when the user explicitly asks to **change or update** a stored preference (e.g., "change my budget to $200") or if you learn a *new, relevant* preference that isn't in the existing context. Takes a single JSON string, `updates_json`.
    - **updates_json FORMAT:** Must be a JSON string like: `{"preference_key_1": "value_1", "preference_key_2": "value_A, value_B"}`. You can update multiple key-value pairs in one call.
- *get_daily_conditions_for_location*: Use this tool to get the **weather and day of the week** for a date range at a specified location.
- *convert_currency*: Use this currency exchange tool when the user asks for a specific currency conversion (e.g., "how much is 50 USD in EUR") or a list of rates (e.g., "all rates for USD"). Assume from_currency as USD unless specified otherwise and remember to highlight the date. If the tool returns a warning about unsupported currencies, you MUST inform the user that you are making an inference based on the user's input and that they should double-check the result.

Results

The agent has access to these tools:

Using the weather tool, it can now access live information when asked. The Agent Log shows the reasoning process leading to the final response.

👤 USER MESSAGE  
Tokyo weather on November 1
💭 AGENT LOG
[Action ⚡️]  
Agent is calling a tool to gather data.  
Calling tool: **get_daily_conditions_for_location**(<Agent Context>)  
---
[Tool Result 🛠️]
Tool returned Observation:
{"location": "Tokyo", "forecast_days": 1, "daily_conditions": [{"date": "2025-11-01", "day_of_week": "Saturday", "max_temp_c": 22.5, "min_temp_c": 15.4, "condition": "Heavy rain"}], "weather_api_status": "Success"}
🤖 BOT MESSAGE  
On Saturday, November 1, 2025, Tokyo will be graced with heavy rain, so you might want to bring an umbrella—or just embrace the wetness like a soggy superhero. The temperature will range from a brisk 15.4°C to a cozy 22.5°C.

What I’ve Learned

Reality Check

More than half of my time was spent on tool prompts. I quickly learned that just because an instruction was given, doesn’t mean that it’ll be followed. One reason is that these models are not deterministic, meaning there is always an element of uncertainty.

The bigger reason is prompting doesn’t work the same as programming. Each instruction has some form of unintended consequence.

Location and Datetime tools were the toughest to get right. First, users do not necessarily indicate “here” or “now” when conversing; for example “What’s good to eat?”. I still haven’t figured out a way to fully capture implicit or inferred intent. Second, these parameters are used as input to other tools, thus need to be prompted in a way to create a workflow.

Best Practices

Here are some practices that I find improves tool use

Misses

Here are some areas where the agent still falls short and the reasons

My #1 Tip (to myself): Offload Logic to Tools

Using natural language for prompts can be fun when instructing conversational chatbots, but painful when you’re trying to get consistent tool activation. The probabilistic nature of LLMs doesn’t help either.

System prompts which started off as structured instructions quickly mutated into a jumbled mess of magical spells through patchwork of caveats and complex directives.

Rather than revising your prompts, ask yourself whether to refactor your tools instead.

That way you leverage LLMs for flexible input processing and maximise tool code for deterministic flow.

My Setup

For this application, I’m using Python as the programming language and Gradio for UI.

Langchain

Langchain is an open-source software framework that simplifies the process of building applications powered by Large Language Models. It has ready components for chat messages and agent tools.

Hugging Face

Hugging Face a community platform that democratises AI by providing an ecosystem of open-source tools, pre-trained models, and datasets. It has “Spaces” where AI applications can be deployed for free with certain usage limits.

Source code

You can find the full source code at Hugging face file repo

Copy over this application using the “Duplicate this Space” option under Files Hugging Face Duplicate Space


You Might Also Like