ARCHITECTURE.md•5.58 kB
# Trip Planner PoC - Architecture & Flow Guide
This document details the end-to-end workflow, decision-making process, and memory architecture of the Trip Planner application.
## 1. End-to-End Workflow
The application follows a **Hub-and-Spoke** architecture where a central **Orchestrator** coordinates specialized **Agents**.
### Step-by-Step Flow
1. **User Input**:
* **Query**: *"Plan a healthy food itinerary for Udaipur trip and list food preferences for people in Raj’s team."*
2. **Orchestrator (The "Brain")**:
* **Analysis**: The Orchestrator receives the query. In a real LLM app, it would parse this semantic meaning. In this PoC, we simulate extracting:
* `Target Manager`: "Raj"
* `Target Location`: "Udaipur"
* **Planning**: The Orchestrator creates a plan:
1. Find who is in Raj's team.
2. Find what those people like to eat.
3. Find travel info for Udaipur.
4. Combine reports.
3. **Execution Phase (Agent Handoffs)**:
* **Step A: Team Agent (Graph Reasoning)**
* **Goal**: Find direct reports of "Raj".
* **Decision**: Needs to query the Organization Graph.
* **Action**: Generates a **Cypher Query**: `MATCH (m:Person {name: 'Raj'})...`
* **Tool Call**: Invokes `run_cypher_query` on MCP Server.
* **Result**: Returns `['Sarah', 'Mike', 'Priya']`.
* **Step B: Food Agent (Relational Data)**
* **Goal**: Get preferences for `['Sarah', 'Mike', 'Priya']`.
* **Decision**: Needs structured data from the SQL database.
* **Action**: Generates a **SQL Query**: `SELECT ... FROM food_preferences WHERE person_name IN ('Sarah', ...)`
* **Tool Call**: Invokes `run_sql_query` on MCP Server.
* **Result**: Returns `{'Sarah': ['Vegan'], 'Mike': ['Spicy'], ...}`.
* **Step C: Travel Agent (External World)**
* **Goal**: Get info for "Udaipur".
* **Action 1**: Calls internal mock tool `get_trip_recommendations`.
* **Action 2**: Calls external API tool `get_country_info` (RestCountries API) to get currency/capital data.
* **Result**: Returns a combined string of places + country metadata.
4. **Response Generation**:
* The Orchestrator aggregates the outputs from the Team, Food, and Travel agents.
* It formats them into the final readable response printed to the console.
---
## 2. Decision Making Process
In this PoC, "decisions" are simulated in Python code, but they represent how an LLM would behave:
| Component | Decision Type | Implementation in PoC | Real LLM Equivalent |
| :--- | :--- | :--- | :--- |
| **Orchestrator** | **Task Decomposition** | Hardcoded steps in `run_mission` | LLM Chain-of-Thought ("First I need to find the team, then...") |
| **Team Agent** | **Query Generation** | Python f-string `f"MATCH ... {name} ..."` | LLM generating code/query based on schema |
| **Food Agent** | **Data Aggregation** | Python loop over results | LLM summarizing retrieved context |
| **MCP Server** | **Tool Execution** | `@mcp.tool` decorators | Model Context Protocol (Server-side execution) |
---
## 3. Memory & State Management
The application handles "Memory" in two distinct ways:
### A. Short-Term (Working) Memory
* **What it is**: The context of the current specific request.
* **Storage**: Python Variables in `orchestrator.py`.
* **Flow**:
1. `manager_name` is stored.
2. Passed to Team Agent -> returns `team_members`.
3. `team_members` is held in memory and passed to Food Agent.
4. `food_prefs` is held in memory.
* *Note: Once the script finishes, this memory is lost.*
### B. Long-Term (Persistent) Memory
* **What it is**: The "Knowledge Base" of the company.
* **Storage**: Dockerized Databases.
1. **Neo4j (Graph DB)**: Stores **Relationships**.
* *Why?* It "remembers" who works for whom. If Raj hires a new person, we add a node here.
2. **Postgres (SQL DB)**: Stores **Attributes**.
* *Why?* It "remembers" facts like "Sarah is Vegan".
### Visualizing the Data Flow
```mermaid
graph TD
User[User Query] --> Orch[Orchestrator]
subgraph Working Memory (Python)
Orch -- "Raj" --> TeamAg[Team Agent]
TeamAg -- "['Sarah', 'Mike']" --> Orch
Orch -- "['Sarah', 'Mike']" --> FoodAg[Food Agent]
FoodAg -- "{'Sarah': 'Vegan'}" --> Orch
end
subgraph Persistent Memory (Docker)
TeamAg -- "Cypher Query" --> Neo4j[(Neo4j Graph)]
FoodAg -- "SQL Query" --> Postgres[(Postgres DB)]
TravelAg -- "HTTP Request" --> ExtAPI((External API))
end
Orch --> TravelAg[Travel Agent]
TravelAg --> ExtAPI
Orch --> Final[Final Response]
```
# Visual Flow
User: "Plan a trip to Goa for Sarah's team"
↓
Orchestrator (Gemini AI)
↓ [calls ask_team_agent]
TeamAgent (Gemini AI)
↓ [calls get_team_members]
MCP Server → Neo4j Database
↓ [returns "Mike Jones"]
TeamAgent
↓ [returns "Sarah's team: Mike Jones"]
Orchestrator
↓ [calls ask_food_agent]
FoodAgent (Gemini AI)
↓ [calls get_food_preferences]
MCP Server → Postgres Database
↓ [returns preferences]
FoodAgent
↓ [returns formatted preferences]
Orchestrator
↓ [calls ask_travel_agent]
TravelAgent (Gemini AI)
↓ [calls get_trip_recommendations]
MCP Server (mocked data)
↓ [returns "Baga Beach, Fort Aguada..."]
TravelAgent
↓ [returns itinerary]
Orchestrator
↓ [combines all info]
User: [Receives complete trip plan]