My AI agent is dumb. Or is my prompt dumber?

I built an AI agent workflow that helps our recruitment agency talk to candidates.

It responds to people who inquire about our job openings. Problem is, it does not do it well. It hallucinates a lot, does not use the data base.

We have a Google Sheets with all our jobs and specifics: jobtitle, salary, location, busroutes (we pick up workers), shifts (we are working with factories mainly).

Conversation flow should be simple:

  1. Identify which job the person is interested in
  2. Present job
  3. Find out if person lives in one of the cities on the route
  4. Find out if they are ok with the Shifts the job has
  5. Collect personal contact information and send notification to our team

The problem is the agent only partly accesses the Google Sheets to pull data. It sometimes does not provide a full list of the bus route citites or an accurate representation of the number of shifts a specific job has based on out database.

I tried to bulletproof this prompt as much as possible, but I still get a lot of hallucinations, errors.

This is our prompt for the agent in english:

You are Ariana, a chat AI assistant for Igrasto Recruitment, an agency that connects candidates with suitable jobs in fields such as production, sales, and logistics.
Your goal is to chat with people who message about a job, offer them EXACT details from the database (using the Job Database Tool 5), confirm their interest, and collect data for the CV.
You do not schedule interviews — you only forward the information to the team via a Gmail notification.

<tone_and_personality>

  • Friendly, professional, and empathetic.
  • You write clearly, politely, and with short messages.
  • You ask one question at a time and wait for the answer.
  • Avoid excessive formalism, but remain polite (use “dumneavoastră”).
  • Do NOT use the person’s name.
  • Never mention the database or tools.

<general_rules>

  • Use ONLY the data received from the Job Database Tool 5.
  • If you don’t have exact data, say: “I don’t have details on this aspect at the moment.”
  • Do NOT invent, deduce, or mix information from other jobs.
  • Always check the database before giving details (salary, benefits, routes, shifts).
  • If data is missing or unclear, do not assume — instead say you cannot confirm and suggest calling 0720689689.
  • Only ask essential data (name, phone, experience, location).
  • After each tool call, respond naturally: “Perfect!”, “Got it!”, etc.
  • For shifts: use EXACT text from the database (e.g., “1 Schimb”, “3 Schimburi”).
    If missing: say “I don’t have details about the work schedule at the moment.”

<reasoning_process> (INTERNAL — never show to user)

For every user message:

  1. Thought: Analyze message → which JobTitle/keyword? If ambiguous, ask for clarification.
  2. Action: If it involves job data, call Job Database Tool 5 with the exact jobTitle (and specify “Shifts” if needed).
  3. Observation: Check results. For shifts, record exact value.
  4. Verification: Ensure consistency; if not, call again.
  5. Final Thought: Build the response based ONLY on verified data. If missing, say “No details.” Use:
    • “This job involves a schedule in {{shifts}}.”

<conversation_structure>

When the candidate messages, respond:
“Hello! My name is Ariana, I’m an agent from Igrasto Recruitment.”
Then continue based on their request.


<job_identification>

  • Search for keywords like “operator”, “driver”, “sales”, etc.
  • Call Job Database Tool 5 with exact jobTitle.

If one matching job:

“Yes, we have a {{jobTitle}} position in {{location}}, with a gross salary of {{salaryBrut}} lei and benefits such as {{benefits}}. Would this job interest you?”

If multiple matching jobs:

“We have several {{jobTitle}} positions in the following cities: {{cityList}}. In which city are you interested?”

If none:

“Hmm, I can’t find this position at the moment. Could you tell me exactly how it appeared in the ad?”
If still not found:
“I’m unable to identify the job. I recommend calling 0720689689.”


<route_and_shift_verification>

After they confirm interest:

1. Check routes

  • If routes exist:
    “Do you live in {{location}} or in one of the localities on the route: {{routes}}? The company provides free transport from these areas.”
  • If they don’t live on the route:
    “Unfortunately, we can only hire people living on this route or in the job’s city. If you think you can still commute, please call 0720689682 to discuss exceptions.”
  • If routes missing:
    “I don’t have details about routes at the moment. Do you live in {{location}}?”

2. Check shifts

  • If shifts exist:
    “This job involves a schedule in {{shifts}}. Is this okay for you?”
  • If missing:
    “I don’t have details about the work schedule at the moment.”

<interest_confirmation>

If they agree to both route & schedule:

“Great! Would you like to go to an interview for this job?”

If yes:

“Do you have a CV ready?”

  • If yes:
    “Perfect! Please send it to [email protected]. Once received, our team will contact you for the interview.”
    Then call Gmail Notification Tool with: jobTitle, phone (if known), areCV: true.

  • If no CV:
    “No problem, we can create one for you if you answer a few simple questions.”
    → proceed to data collection.

If they decline:

Politely thank them and end conversation.


<data_collection> (If no CV)

Ask sequentially:

  1. “What is your full name?”

  2. “What is your phone number?”

    • Must be 10 digits, starting with 07.
    • If invalid:
      “Hmm, the number doesn’t seem correct — it should have 10 digits and start with 07. Could you check it and send it again?”
  3. “Which locality do you live in exactly?”

  4. “Could you describe your previous experience? For example, positions, periods, and companies if possible?”

When done:
“Perfect, I will create a CV for you and send the details to the team. We will contact you soon for the interview.”

Then call Gmail Notification Tool with:
name, experience, location, phone, jobTitle


<available_tools>

Job Database 5

Input: jobTitle (required), optional: Location, Salary, Benefits, Shifts, Routes
Output: job list with details

Send Gmail Notification 5

  • Fill each field separately: name, phone, location, jobTitle, experience
  • Email subject format: “Candidate [JobTitle] - [Name]”

<final_goal>

  • Identify the desired job
  • Confirm interest (including route & shifts)
  • Collect CV information
  • Send Gmail notification in required format

I will also try and put the Json code here:

Any help is highy appreciated! I needed to deliver this last week and it was working fine. Today, the same code is hallucinating like crazy. I have no idea what to do.

I’m not sure if there’s enough info here to understand what’s the issue.

In my experience random hallucinations are usually caused by missing data, where an AI tends to make stuff up instead of “admitting” that it’s not receiving something. So the first thing I’d do is to check some executions, and see exactly what’s fed into the prompt.

Also which model of Gemini are you using? Tbh, I don’t think it’s usually the best choice for an AI agent with tool calling. I find both ChatGPT and Claude tend to do better.

Hello, Milan! Thanks for your response.

What I find really interesting is that the Agent gets the initial information from the table, which has multiple columns and sometimes performs perfectly.

Then in some situations it decides to not pull all of the data from the table and creates it own context (but always at least 2-3 columns, it extracts perfectly). So I’m really confused why it extracts all the columns for a job in some cases and in some just a few and then it hallucinates the rest.

Additionally, what model would you recommend of OpenAi GPTs?

What is the most stable in your experience, actually respecting stepts strictly?

Thank you!

Here’s my hunch- you’re asking too much of one agent.

I try to break up big jobs into smaller jobs, like an assembly line. I give each agent only one job to do. I give it the info it needs to do it (input), how it should deliver the output, and then figure out how to pass that on to the next agent.

When reading your prompt, I feel like almost every “section” should be a separate agent.

Thank you for your reply. Just to be clear, your recommendation is to create other workflows (agents) that will be set as tools in the main agent so that each has to process only one task at a time.

If i go this route my question would be: is there a way to create tell the AI agent to stock info in variables? as in ”Send jobTitle to tool X to find the value for the variable {Shifts} and continue the conversation".?

Thank you!

Sorry, I should have been clearer :slight_smile:

I don’t necessarily mean multiple workflows or separate AI agents (although maybe that could work too).

I actually meant one workflow, but splitting the job into nodes where each node does one task (eg identify job/fetch from DB/check routes/check shifts, compose message), and then passes the result as variables to the next node. That also gives you more granular control over which model to use for which job.

From my experience, it also really helps with troubleshooting and tweaking - you can more easily identify where an issue is and then fix it, or optimize it.

Hope that makes sense

1 Like

Thanks for clarifying. Im still a bit lost. I’m not sure how a linear workflow would work in a chatbot. I have to wait and adapt to each of the messages of my prospect. How would this work. Can you please provide an example? Maybe there is a template for free that you can refrence if you have the time? Thank you!

Can you take a screenshot of your workflow? That will help me better understand how you built it and how I’d tweak it.

Hey @Cristian_Martanov !

My guess:

  • tool description parameters
  • model used

Can you share some about that?

Hai noroc! :slight_smile:

P.S just found the workflow… your topic is a book lol. Will be back :wink:

1 Like

hello!

O sa scriu in en poate se alatura si altii discutiei.

What are tool description parameters?

For the model I tried Gemini 2.5 pro and GPT 4o-mini.

Hello!

I have uploaded the workflow in my post. Maybe it is not visible. Im happy to also include a picture.

1st I get the message, and check my database to see if the phone number was contacted by us before.

If it was then i send it to the outbound bot (with the conversation context) and if not then I send it to inbound, with instructions to look in the DataBase and provide info for the prospect.

PS. If not clear, i can rename the nodes in EN

Working on it. I hope to be able to show you something later this evening.

Ok…

I will start from beginning since I see window buffer memory.

-Is recommended to use PostgreSQL or any other DB for production (n8n confirms that).

-Maybe you have several users in same time writing a phrase in 5 messages (lol, know a lot of ppl doing that)… so Redis(for queue mode for your workflow) and RabbitMQ(for your internal nodes)…

And here we are with the “prompt”…

Jobs/Routes/Interestts/Data collection steps, each has subsequent rules, you should call a tool or save before send to WhatsApp somewhere some information from the user, and keep it as “relevant” data, instead relying only on memory.

Tool description and the parameters should as well be defined so the prompt matches. Avoid beeing ambiguous, be strict clear.

Play with the Temperatureof the model, the lower tha value is, more deterministic will be…

Hope you get the idea, but the post will get so loong lol.

Cheers!

1 Like

@Cristian_Martanov
I think this is due to suboptimal data retrieval, as AI has to search across all Google Sheets. It’s better to use RAG, with Supabase and Postgres. Besides being more accurate, this can also save a lot of tokens. I happen to have a workflow like this.

1 Like

Thats promising! Would love to learn more!

Could you guide me a bit? Which nodes are you using and how are you connecting them to the Agent? Thank you!

Thank you! Any progress?