Skip to main content

Serko Northsky AI Orchestration

The Serko Northsky AI orchestration layer powers the conversational travel planning experience, coordinating multiple AI agents and tools to deliver personalized trip recommendations.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────────────┐
│ Chat Endpoint │
│ (WebSocket / SSE Stream) │
└─────────────────────────────────┬───────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────────────┐
│ Chat Orchestrator │
│ Coordinates conversation flow and agent execution │
└───────────────┬────────────────────────────────────────┬────────────────────┘
│ │
┌────────▼────────┐ ┌──────────▼──────────┐
│ Context Agent │ │ Conversational Agent │
│ (Trip Context) │ │ (User Dialogue) │
└────────┬────────┘ └──────────┬───────────┘
│ │
│ ┌──────────▼───────────┐
│ │ Trip Planner Agent │
│ │ (Search & Plan) │
│ └──────────┬───────────┘
│ │
└────────────────┬───────────────────────┘

┌────────────▼─────────────┐
│ Search Orchestrators │
│ (Flight / Accommodation) │
└────────────┬─────────────┘

┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ QPX │ │ Booking │ │ Sabre │
│ Connect │ │ .com │ │ GDS │
└──────────┘ └──────────┘ └──────────┘

Core Components

Chat Orchestrator

The ChatOrchestrator is the central coordinator that manages the conversation flow.

The orchestrator executes a multi-step response flow:

  1. Load Context — Fetch user, conversation history, trip state, preferences
  2. Run Context Agent — Extract and update trip requirements from user message
  3. Run Conversational Agent — Generate response and trigger planning tools
  4. Save Messages — Persist assistant messages to database
  5. Update Traces — Send observability data to Langfuse

AI Agents

The system uses three specialized agents built with Pydantic AI.

Source Code Locations

ComponentLocation
Context Agentcore/agents/context_agent/
Conversational Agentcore/agents/conversational_agent/
Trip Planner Agentcore/agents/trip_planner_agent/

Context Agent

Extracts and maintains trip context from the conversation.

ResponsibilityDescription
Trip InformationExtract dates, destinations, purpose
Trip StepsCreate flight and accommodation requirements
PreferencesCapture user preferences for scoring

Toolsets — See context_agent/toolsets/:

Conversational Agent

Manages user dialogue and orchestrates trip planning.

ResponsibilityDescription
User InteractionRespond to questions, provide recommendations
Planning TriggersInvoke trip planner when search is needed
Result PresentationFormat and explain search results

Toolset — See ConversationalAgentToolset:

  • plan_trip — Initiate search for all trip steps
  • new_trip_step_search — Run additional searches for specific steps

Trip Planner Agent

Executes searches and generates recommendations.

ResponsibilityDescription
Search ExecutionCall flight and accommodation APIs
Result RetrievalFetch and sort search results by score
RecommendationsSelect and highlight top options

Toolset — See TripPlannerAgentToolset:

  • search_accommodations — Search Booking.com and Sabre
  • search_flights — Search QPX Connect
  • get_search_results — Retrieve ranked results
  • recommend_options — Select top 3 recommendations

Agent Tools

Each toolset implements BaseAgentToolset which exposes tools to the Pydantic AI agent.

Tool Reference Table

AgentToolPurposeSource
Contextupdate_trip_infoUpdate trip name, purpose, datestrip_edition_context_agent_toolset.py
Contextcreate_trip_stepAdd flight or accommodation steptrip_edition_context_agent_toolset.py
Contextupdate_trip_stepModify existing trip steptrip_edition_context_agent_toolset.py
Contextdelete_trip_stepRemove a trip steptrip_edition_context_agent_toolset.py
Contextadd_preferenceAdd trip-specific preferencepreference_edition_context_agent_toolset.py
Contextupdate_preferenceModify preference weight/valuepreference_edition_context_agent_toolset.py
Contextdelete_preferenceRemove a preferencepreference_edition_context_agent_toolset.py
Conversationalplan_tripTrigger search for all trip stepsconversational_agent_toolset.py
Conversationalnew_trip_step_searchRun new search for specific stepconversational_agent_toolset.py
Trip Plannersearch_accommodationsSearch Booking.com + Sabretrip_planner_agent_toolset.py
Trip Plannersearch_flightsSearch QPX Connecttrip_planner_agent_toolset.py
Trip Plannerget_search_resultsRetrieve sorted resultstrip_planner_agent_toolset.py
Trip Plannerrecommend_optionsSelect top recommendationstrip_planner_agent_toolset.py

Search Orchestrators

Orchestrators coordinate multi-provider searches. See detailed documentation:

OrchestratorSourcePurpose
FlightSearchOrchestratorcore/orchestrators/flight_search_orchestrator.pyQPX Connect flight search
AccommodationSearchOrchestratorcore/orchestrators/accommodation_search_orchestrator.pyMulti-provider hotel search

Data Flow

Complete Search Flow

User: "I need a flight from Montreal to Paris next month"

├── 1. Context Agent extracts requirements
│ └── Creates TripStep (flight: YUL → CDG, March 15-22)

├── 2. Conversational Agent triggers planning
│ └── Calls plan_trip tool

├── 3. Trip Planner Agent executes search
│ ├── Creates TripSearch entity
│ ├── Calls search_flights tool
│ │ └── FlightSearchOrchestrator → QPX API
│ ├── Calls get_search_results tool
│ │ └── Returns scored, sorted options
│ └── Calls recommend_options tool
│ └── Selects top 3 with highlights

└── 4. Conversational Agent presents results
└── "I found 47 flights. Here are my top 3 picks..."

Agent Dependencies

Agents receive dependencies via typed Deps dataclasses. See source files:

Dependency ClassSource
ContextAgentDepscontext_agent/agent_runner.py
ConversationalAgentDepsconversational_agent/agent_runner.py
TripPlannerAgentDepstrip_planner_agent/agent_runner.py

Key dependencies include:

  • event_sender — SSE streaming to frontend
  • trip / trip_step — Current trip context
  • trip_preferences — User preferences for scoring
  • company_policy_rules — Policy constraints

Error Handling

Tools use Pydantic AI's ModelRetry exception to handle recoverable errors. The LLM receives the error message and can retry or explain to the user.

Observability

All agent operations are traced with Langfuse using the @observe decorator:

  • Agent execution spans
  • Individual tool calls
  • LLM token usage
  • Errors and retries

Transaction Management

Agent tools run outside the request-scoped UoW. They create their own UoW using the factory and wrap operations in background_context().

See Unit of Work for details.

Important

Agent tools must create their own UoW via the factory to avoid race conditions with the request-scoped UoW.