END-TO-END CONVERSATIONAL AI AGENT BUILDS

Conversational AI &
Washington State Ferries

An ongoing experiential project integrating large language models with conversational AI systems, rich multimodal content, and robust seagull management.

introduction

SAAB
Story.

Fun fact:

I grew up on Bainbridge Island with my father, a daily walk-on commuter who took the ferry to Downtown Seattle 300 days a year.

Once a year or so, my father would have to run an errand in the city after work, so he’d drive his SAAB onto the ferry and head upstairs. When the ferry arrived in Seattle, he’d fold up his newspaper and walk off the ferry, just like he did the other 299 days a year.

The mortified screams usually came just before lunch: “Oh my God, I LEFT MY CAR ON THE FERRY.”

My father did this — twice.

It’s a weekly occurrence aboard Washington State Ferries, so they’re much more forgiving than say, your own children.

Twenty years later, when my father has difficulty finding a place to park, I still like to ask him “Should we just drive it onto a ferry and leave it there?”

While my father’s mistake was small, harmless, and lifelong fuel for mockery, it proves running on autopilot can sneak up on the best of us. Designers might recycle an inefficient flow, overlook a crucial synonym, or forget to address a critical pain point. And in conversational AI, that means users get stuck, annoyed, and, worst case —they sigh.

To keep my own work out of autopilot, I follow a few rules:

Sighs matter. So do eye rolls. I don’t want either from users, so I obsess about conversational efficiency.

Never ask twice. Don’t repeat information.

Don’t make users do the work an agent can handle.

Ruthlessly optimize the most fluid path from intent to solution. Period. Every time.

Finally, never leave users at a dead end. Always provide options and let the user determine when the conversation ends.

Live Conversational Agents.

LANGGRAPH CUSTOM ARCHITECTURE

v2. LangGraph Custom Architecture

Built from scratch with LangGraph’s multi-agent state machine architecture. Demonstrates advanced prompt engineering, deferred tool execution, and zero training phrase design—letting LLMs handle intent recognition, conversation routing, and intelligent information gathering.

google conversational agents

v1. Google Conversational Agents

A cutting-edge Dialogflow CX-based agent powered entirely by large language models for intent recognition and conversational routing. Custom Python functions handle complex terminal synonyms and time parsing, while advanced prompt engineering manages the conversational flow.

the llm experience

v2. LangGraph Architecture

Structure agents to deliver a single comprehensive response when a user makes multiple requests

Before the paint was even dry on my Dialogflow CX-based WSF agents, I began exploring new challenges: Most chatbots work great when a user signals one intent, but natural requests often contain two different asks at once.

How could I build an agent that identifies both requests and delivers one complete answer?

LangGraph’s custom state machine architecture made this possible.

Unlike platform-based agents that route to immediate responses, LangGraph lets you design exactly how the agent collects information, when it calls tools, and how it assembles the final response. The agent tracks all required information on a whiteboard, waits until it has everything it needs, then calls multiple tools simultaneously to formulate one complete, natural response.

You can try it below. Ask the agent something like:

“I’d like to take my wife to dinner tomorrow night on Orcas. Can you please get me a schedule and recommend a few restaurants?”

The agent will collect the missing information it needs, then deliver everything in one cohesive package. Sound easy? It isn’t! Carefully orchestrated prompts guide the agent on how to gather, organize, and present the information, right down to the format.

You can also try blunt requests like:

“Ferry to Bainbridge tomorrow 6 pm and fares please.”

“When is the next ferry to Kingston and can you check the traffic cam for me?”

SoundHopper Online

System Status

Awaiting route selection...

Welcome to SoundHopper!

I can help you find schedules, discover fares, check terminal traffic cameras, and more.

What can I help you with today?

the llm experience

v1. Google Conversational Agents

Build agents that deliver one complete response when a user makes multiple requests

After spending several months learning the ins and outs of Dialogflow CX, I wanted to explore Google’s new Playbooks architecture: What if I could eliminate training phrases entirely and let an LLM handle intent recognition?

v1 (Google Conversational Agents) is that experiment. Zero training phrases. Custom Python functions manage terminal synonyms and time parsing. Advanced prompts guide the conversation.

The agent delivers rich, multimodal responses including dynamic images, voice integration, and intelligent follow-up questions all powered by LLM-based path matching and routing.

Try it below with prompts like:

“I need a ferry to Southworth”

Select a departure terminal and any time of day (like “afternoon” or “4pm”). The agent will output a curated list of departure times, dynamically display an image of your arrival terminal, and offer contextual follow-up options based on your conversation history.

Need to search for services at your destination?

The agent integrates Google Places API to help you find restaurants, gas stations, coffee shops, and more:

You can try:

“Are there any coffee shops near the Anacortes terminal?”

Washington State Ferries Information
🔇 Sound Off

WASHINGTON STATE FERRIES

Surface Level Conversational Challenges.

Some challenges you can identify from day one. Others blindside you mid-build.

A constant mindset of “how can I make this more thoughtful and efficient” requires tackling unexpected challenges as they surface.

Challenges #1 and #2 below I planned before the build. Challenges #3 and #4 required creative pivots I hadn’t anticipated.

challenge #1: you say potato

There's a million ways to ask for the same ferry.

CHALLENGE

Users can refer to the exact same ferry departure in a dozen different ways (“ferry leaving Bainbridge” vs “ferry to Seattle” vs “Winslow to Downtown” – all referring to the same boat), creating complex NLU challenges and potential disambiguation loops.

SOLUTION

  • Built extensive NLU training data to capture linguistic variations
  • Evolved to strategic rich content chip placement for common requests
  • Maintained conversational feel while guiding user input

RESULT

  • Eliminated disambiguation loops and clarification exchanges
  • Reduced conversation length for faster task completion
  • Users reach information through guided selection vs. guessing correct phrasing

challenge #2: auto slot filling

Don't ask if you don't need to.

CHALLENGE

50% of Washington State ferry routes link single-destination terminals. If a user asks for single destination terminal schedule, how do I eliminate the need to ask for the opposite terminal?

SOLUTION

  • Built intelligent slot-filling function that analyzes terminal type upon user input
  • Auto-populates the destination for single-route terminals
  • Dynamically generates contextual follow-up questions for multi-destination routes
  • Function determines departure vs. arrival input, then only asks for missing information when appropriate

RESULT

  • Eliminates unnecessary questions for obvious routes
  • Helps tourists discover destination options they didn’t know existed
  • Context-aware conversations that adapt to actual user needs
  • Faster task completion through conditional logic

challenge #3: anticipate user needs

There's no place like home.

CHALLENGE

85% of ferry riders are commuters making same-day round trips, but requesting their return leg would require the user to re-enter their terminal information and sift through irrelevant departure times to build their return journey.

SOLUTION

  • Created “Return Trip” function that auto switches terminal parameters and repeats API call for return options
  • Built intelligent time filtering returning only departures after estimated arrival time
  • Organized results into morning/afternoon/evening rich content accordian dropdowns for easier scanning

RESULT

  • Transformed multi-step re-entry process into single click
  • Eliminated cognitive load of filtering impossible departure times
  • Optimized for the 85% use case while serving all users.

challenge #4: less is more

Trim the fat.

CHALLENGE

Washington State Ferry APIs return massive datasets, but conversational interfaces offer limited screen real estate. Dumping raw data can overwhelm users and kill engagement.

SOLUTION

  • Prioritized display shows next 3 departures on same-day requests with countdown timer to nearest departure.
  • Dynamic safety warnings for departures under 5 minutes to prevent speeding accidents
  • Progressive disclosure using accordion dropdowns for additional options
  • Context-sensitive organization: same-day by priority, future dates by time periods
  • Applied same accordion approach to complex fare structures

RESULT

  • Users see what they most likely need immediately
  • Reduced cognitive load while preserving all options
  • Built-in safety considerations for real-world usage
  • Faster task completion for majority of users

Tech Stacks.

v2 Featuring:

Dialogflow CX + Playbooks (now Google Conversational Agents), Google Cloud Platform, Gemini 2.5, Claude Sonnet 3.5, Python, Pinecone, Github, Node.js, Imagen, Veo3, Google Places API, Google Chirp 3: HD Voices

v3 Featuring:

LangGraph Multi-Agent Architecture, React + Tailwind CSS, Google Cloud Platform, Gemini 3 Flash Preview, Claude Sonnet 4.5, Python, FastAPI, LangChain, Google Places API, Google Cloud Storage, WSDOT Ferry API, Cursor IDE, GitHub Coming soon: Google Chirp 3: HD Voices