
1. Set up the Environment:
%pip install --upgrade --quiet \
"google-cloud-aiplatform[agent_engines,langchain]" \
cloudpickle==3.0.0 \
"pydantic>=2.10" \
langchain-google-community \
google-cloud-discoveryengine \
google-api-python-client
from IPython.display import Markdown, display
from googleapiclient import discovery
from langchain.agents.format_scratchpad.tools import format_to_tool_messages
from langchain.memory import ChatMessageHistory
from langchain_core import prompts
from vertexai import agent_engines
from vertexai.preview.reasoning_engines import LangchainAgent
import requests
import vertexaiPROJECT_ID = "[your-project-id]"
LOCATION = "us-central1"
STAGING_BUCKET = "gs://[your-staging-bucket]" # This can be any bucket that is present in your GCS.
model = "gemini-2.0-flash" # You can use any versions of Gemini Model
vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)
DATA_STORE_ID = "[your-data-store-id]" # Optional
LOCATION_ID = "global" # Optional
2. Create a Vertex AI Search Data Store and Search Engine
Below blog shows how to create a chatbot with Vertex AI Search for RAG on PDFs, using semantic search. It covers data store setup, app connection, and optional Cloud Run deployment. Vertex AI Search simplifies building accurate, scalable conversational experiences.
3. Define Python Functions for External Tools
Implement Python functions to equip your bot with the ability to interact with external systems, allowing it to retrieve information like FAQ responses from Vertex AI Search, cat facts from web APIs, real-time exchange rates, or dynamic data from your databases, such as sales, inventory, or employee leave information.
Practical Advice: Providing a detailed function description is essential for the AI Agent to correctly identify and utilize the appropriate function. If the agent struggles to call the expected function, enhance the description to improve its understanding of the function’s purpose.
def find_faq_answer(query: str) -> str:
"""Search across records in the FAQ document related to HR policies"""
from langchain_google_community import VertexAISearchRetrieverretriever = VertexAISearchRetriever(
project_id=PROJECT_ID,
data_store_id=DATA_STORE_ID,
location_id=LOCATION_ID,
engine_data_type=1,
max_documents=10,
)
result = str(retriever.invoke(query))
return result
def get_cat_fact():
"""
Fetches a random cat fact from the catfact.ninja API.
Returns:
str: A cat fact if the request is successful, otherwise an error message.
"""
url = "https://catfact.ninja/fact"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return data.get("fact", "No fact found.")
else:
return f"Error: Unable to fetch data (Status Code: {response.status_code})"
def get_exchange_rate(currency_from: str, currency_to: str, currency_date: str = "latest"):
"""
Fetches the exchange rate from the Frankfurter API.
Do all the calculation if asked.
Args:
currency_from (str): The base currency (e.g., "USD").
currency_to (str): The target currency (e.g., "INR").
currency_date (str): The date for the exchange rate (e.g., "latest" or "YYYY-MM-DD").
Returns:
float or str: The exchange rate if successful, otherwise an error message.
"""
url = f"https://api.frankfurter.app/{currency_date}"
params = {
"from": currency_from,
"to": currency_to
}
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
return data.get("rates", {}).get(currency_to, "No rate found.")
else:
return "Error: Unable to fetch data."
The system’s functionality can be expanded by incorporating additional custom functions as required.
Make sure to test your functions individually to check if everything is working as expected.
get_exchange_rate("USD", "INR")
# 85.53
4. Build the Gemini Agent with Function Calling
First, we define a prompt template. Think of this as the instructions we give to the chatbot’s language model. It’s like a script that tells the model how to structure its responses.
- History: We tell the chatbot to remember past messages in the conversation, so it can provide contextually relevant answers.
- Input: We include the user’s latest message, so the chatbot knows what to respond to.
- Agent Scratchpad: This is a bit more technical, but it’s where the chatbot keeps track of the steps it’s taking and the results from the tools it uses.
To make the chatbot feel more natural, we want it to remember past interactions. We do this by creating a ChatMessageHistory
object for each conversation session. This allows the chatbot to keep track of what the user has said and what it has responded.
Here’s where things get interesting. We’re giving our chatbot access to external tools, essentially expanding its capabilities.
find_faq_answer
: This tool is the key to leveraging your own data. It connects to a Vertex AI Search engine, allowing the chatbot to efficiently retrieve answers from your prepared knowledge base. This is much more powerful than simple keyword matching, because Vertex AI Search uses semantic search to understand the meaning of the questions.get_cat_fact
: This tool lets the chatbot fetch random cat facts from the internet. It’s a fun way to add some personality and engage users.get_exchange_rate
: This tool allows the chatbot to retrieve real-time exchange rates from an API, enabling it to answer financial questions.
These tools are like extensions to the chatbot’s knowledge and abilities. They allow it to perform actions beyond simply generating text.
Finally, we create a LangchainAgent
. This is the core of our chatbot. We give it the prompt template, the language model, the session history, and the tools we’ve defined. We also set some parameters, such as the temperature (which controls the randomness of the responses).
# Define prompt template
prompt = {
"history": lambda x: x["history"],
"input": lambda x: x["input"],
"agent_scratchpad": (lambda x: format_to_tool_messages(x["intermediate_steps"])),
} | prompts.ChatPromptTemplate.from_messages(
[
prompts.MessagesPlaceholder(variable_name="history"),
("user", "{input}"),
("system", ""), # add appropriate system prompt if required
prompts.MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)# Initialize session history
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
agent = LangchainAgent(
prompt=prompt,
model=model,
chat_history=get_session_history,
model_kwargs={"temperature": 0},
tools=[find_faq_answer,get_cat_fact, get_exchange_rate],
agent_executor_kwargs={"return_intermediate_steps": True},
)
5. Agent Interaction with RAG along with functions
Let’s test our agent.
The API provides exchange rates for 1 Euro against various currencies. The agent utilizes this data to calculate the equivalent of 1 Euro in USD and JPY, and subsequently derives the USD to JPY exchange rate.
response = agent.query(
input="How much is us dollar to Japanese currency today",
config={"configurable": {"session_id": "demo"}},
)Markdown(response["output"])
# The current exchange rate is 1 USD = 150.63 JPY.
response = agent.query(
input="Tell me about cats",
config={"configurable": {"session_id": "demo"}},
)Markdown(response["output"])
# Response:
# Here's a cat fact for you: Unlike other cats, lions have a tuft of hair at the end of their tails.
response = agent.query(
input="What is the work from policy?",
config={"configurable": {"session_id": "demo"}},
)Markdown(response["output"])
# Response:
# You can work from home for 5 days a month, but you'll need approval from your Reporting Manager beforehand.
response = agent.query(
input="Who is the Leave policy of NASA",
config={"configurable": {"session_id": "demo"}},
)Markdown(response["output"])
# Response:
# I do not have access to information about NASA's leave policy. To get accurate information, I recommend visiting NASA's official website or contacting their HR department directly.
When presented with a random or irrelevant query, the bot consistently declines to provide a response.
Agent is also able to ask questions on it’s own if it is not able to get the required parameter from the prompt. See the example below:
response = agent.query(
input="Who is the us dollar rate today",
config={"configurable": {"session_id": "demo"}},
)Markdown(response["output"])
# Response
# Please specify which currency you want to compare with the USD.
response = agent.query(
input="to swedish currecy",
config={"configurable": {"session_id": "demo"}},
)
Markdown(response["output"])
# Response:
# The current exchange rate is 1 USD to 10.0213 SEK.
6. Deploy Agent to Vertex AI
We’ve finished building and testing our agent, defining its logic and tools. Now, we’ll deploy it on Vertex AI Agent Engine. This platform lets us run the agent serverlessly, meaning we don’t manage servers, and it scales automatically. This allows our agent, with its carefully crafted personality and abilities, to be easily accessible to users for conversations and tasks, without us worrying about infrastructure.
remote_agent = agent_engines.create(
agent,
requirements=[
"google-cloud-aiplatform[agent_engines,langchain]",
"cloudpickle==3.0.0",
"pydantic>=2.10",
"langchain-google-community",
"google-cloud-discoveryengine",
],
display_name="demo_langchain_agent",
description="A demo agent"
)
The above command would take around 5 mins to complete. After the execution completes, It will print out something like mentioned below:
projects/
The bold text you see at the end is crucial — it’s your reasoning_engine_resource_id
. Make sure to keep it safe.
7. Access AI Agent from your Application
To access your AI Agent in our application, you will have to use the below code
from vertexai.preview import reasoning_enginesreasoning_engine_id = "5011670756484252288"
remote_agent = reasoning_engines.ReasoningEngine(reasoning_engine_id)
response = remote_agent.query(
input="How much is indian rupee to japanese currecy today",
config={"configurable": {"session_id": "demo"}},
)
Markdown(response["output"])
# Response:
# Today, 1 Indian Rupee equals 1.7611 Japanese Yen.
And with that, your AI agent is live, serverlessly deployed and ready for seamless integration, with simple tool-based updates moving forward.
The Agent Engine and Vertex AI Search queries will be the main cost drivers.
Vertex AI Agent Engine — Given 1,000 API calls per day, and using Gemini 2.0-flash, this could range from $5 to $30 per day, depending on the complexity of the requests and responses.
Vertex AI Search — If a significant portion of the 1,000 daily calls involve search queries, this could add $1 to $5 per day.
Application Hosting/Integration — For a simple web application or API endpoint to access the agent, you might incur $1 to $5 per day, depending on traffic and complexity.
Cloud Storage (GCS) — Negligible, likely less than $1 per month.
Source Credit: https://medium.com/google-cloud/ai-agents-built-in-minutes-vertex-ai-agent-engine-makes-it-happen-16c0aab0c71e?source=rss—-e52cf94d98af—4