Skip to content

Commit f1e57aa

Browse files
committed
feat: multi-agent architecture proposal with agent scaffolds
Proposes refactoring the monolithic Workbench backend (~10K lines) into 5 discoverable sub-agents using @app_agent + AI Dev Kit, with a thin supervisor routing frontend API calls. Additive only — no existing code is modified. New files: - docs/architecture-proposal.md: full proposal with migration phases - agents.yaml: multi-agent deployment config - agents/{scorer,analyzer,creator,optimizer,fixer}/app.py: agent scaffolds - agents/{scorer,analyzer,creator,optimizer,fixer}/app.yaml: per-agent config
1 parent e431977 commit f1e57aa

12 files changed

Lines changed: 1332 additions & 0 deletions

File tree

agents.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Multi-agent deployment configuration for Genie Workbench.
2+
#
3+
# Deploy all agents:
4+
# dbx-agent-app deploy --config agents.yaml
5+
#
6+
# Deploy a single agent:
7+
# dbx-agent-app deploy --config agents.yaml --agent scorer
8+
#
9+
# Each agent is a standalone Databricks App that exposes:
10+
# - /invocations (Responses Agent protocol)
11+
# - /.well-known/agent.json (A2A discovery)
12+
# - /health (liveness probe)
13+
# - MCP server (tool integration)
14+
15+
project:
16+
name: genie-workbench
17+
workspace_path: /Workspace/Shared/apps
18+
19+
agents:
20+
- name: scorer
21+
source: ./agents/scorer
22+
description: "IQ scoring for Genie Spaces — scan, history, stars"
23+
24+
- name: analyzer
25+
source: ./agents/analyzer
26+
description: "LLM-powered deep analysis of Genie Space configurations"
27+
28+
- name: creator
29+
source: ./agents/creator
30+
description: "Conversational wizard for building new Genie Spaces"
31+
32+
- name: optimizer
33+
source: ./agents/optimizer
34+
description: "Optimization suggestions from benchmark labeling feedback"
35+
36+
- name: fixer
37+
source: ./agents/fixer
38+
description: "AI fix agent — generates and applies config patches"
39+
40+
- name: supervisor
41+
source: .
42+
description: "Supervisor — serves React SPA and routes to sub-agents"
43+
depends_on: [scorer, analyzer, creator, optimizer, fixer]
44+
url_env_map:
45+
scorer: SCORER_URL
46+
analyzer: ANALYZER_URL
47+
creator: CREATOR_URL
48+
optimizer: OPTIMIZER_URL
49+
fixer: FIXER_URL

agents/analyzer/app.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"""genie-analyzer — LLM-powered deep analysis of Genie Space configurations.
2+
3+
Extracted from:
4+
- backend/routers/analysis.py (fetch, analyze, stream, query, SQL endpoints)
5+
- backend/services/analyzer.py (GenieSpaceAnalyzer, section analysis, synthesis)
6+
- backend/synthesizer.py (cross-section synthesis)
7+
- backend/services/genie_client.py (space fetching)
8+
9+
Streaming: Yes (SSE for multi-section analysis)
10+
LLM: Yes (section analysis + synthesis)
11+
"""
12+
13+
from __future__ import annotations
14+
15+
from dbx_agent_app import AgentRequest, AgentResponse, app_agent
16+
17+
18+
@app_agent(
19+
name="genie-analyzer",
20+
description=(
21+
"Deep LLM-powered analysis of Genie Space configurations. Evaluates "
22+
"each section (tables, instructions, SQL snippets, etc.) against a "
23+
"checklist, synthesizes findings, and provides actionable recommendations."
24+
),
25+
)
26+
async def analyzer(request: AgentRequest) -> AgentResponse:
27+
"""Route incoming agent requests to analysis tools."""
28+
# TODO: Parse intent from request.messages and dispatch to tools
29+
...
30+
31+
32+
# ── Tools ────────────────────────────────────────────────────────────────────
33+
34+
35+
@analyzer.tool(
36+
description=(
37+
"Fetch and parse a Genie Space by ID. Returns the space data "
38+
"and list of sections with their data."
39+
),
40+
)
41+
async def fetch_space(genie_space_id: str) -> dict:
42+
"""Source: backend/routers/analysis.py::fetch_space"""
43+
# Uses genie_client.get_serialized_space (moved as-is)
44+
raise NotImplementedError("Phase 4: move genie_client + analyzer here")
45+
46+
47+
@analyzer.tool(
48+
description=(
49+
"Analyze a single section of a Genie Space configuration. "
50+
"Returns findings, score, and recommendations for that section."
51+
),
52+
)
53+
async def analyze_section(
54+
section_name: str,
55+
section_data: dict | list | None,
56+
full_space: dict,
57+
) -> dict:
58+
"""Source: backend/services/analyzer.py::GenieSpaceAnalyzer.analyze_section"""
59+
raise NotImplementedError("Phase 4: move analyzer.py here")
60+
61+
62+
@analyzer.tool(
63+
description=(
64+
"Analyze all sections with cross-sectional synthesis. Returns "
65+
"section analyses plus a synthesis result for full analysis."
66+
),
67+
)
68+
async def analyze_all(
69+
sections: list[dict],
70+
full_space: dict,
71+
) -> dict:
72+
"""Source: backend/routers/analysis.py::analyze_all_sections"""
73+
raise NotImplementedError("Phase 4: move analyzer.py + synthesizer.py here")
74+
75+
76+
@analyzer.tool(
77+
description=(
78+
"Query a Genie Space with a natural language question. "
79+
"Returns the generated SQL if successful."
80+
),
81+
)
82+
async def query_genie(genie_space_id: str, question: str) -> dict:
83+
"""Source: backend/services/genie_client.py::query_genie_for_sql"""
84+
raise NotImplementedError("Phase 4: move genie_client.query_genie_for_sql here")
85+
86+
87+
@analyzer.tool(
88+
description=(
89+
"Execute a read-only SQL query on a Databricks SQL Warehouse. "
90+
"Returns tabular results limited to 1000 rows."
91+
),
92+
)
93+
async def execute_sql(sql: str, warehouse_id: str | None = None) -> dict:
94+
"""Source: backend/sql_executor.py::execute_sql
95+
96+
Phase 8: Replace with databricks_tools_core.sql.execute_sql
97+
"""
98+
raise NotImplementedError("Phase 4: move sql_executor.py (then Phase 8: replace with AI Dev Kit)")
99+
100+
101+
@analyzer.tool(
102+
description="Parse pasted Genie Space JSON from the API response.",
103+
)
104+
async def parse_space_json(json_content: str) -> dict:
105+
"""Source: backend/routers/analysis.py::parse_space_json"""
106+
raise NotImplementedError("Phase 4: move parse logic here")
107+
108+
109+
# ── Standalone entry point ───────────────────────────────────────────────────
110+
111+
app = analyzer.app

agents/analyzer/app.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Databricks Apps configuration for genie-analyzer agent.
2+
#
3+
# LLM-powered deep analysis — needs LLM endpoint + SQL warehouse.
4+
# No Lakebase dependency (stateless analysis).
5+
6+
command:
7+
- "uvicorn"
8+
- "app:app"
9+
- "--host"
10+
- "0.0.0.0"
11+
- "--port"
12+
- "8000"
13+
14+
env:
15+
# LLM serving endpoint
16+
- name: LLM_MODEL
17+
value: "databricks-claude-sonnet-4-6"
18+
19+
# SQL Warehouse for execute_sql tool
20+
- name: SQL_WAREHOUSE_ID
21+
valueFrom: sql-warehouse
22+
23+
# MLflow Tracing
24+
- name: MLFLOW_TRACKING_URI
25+
value: "databricks"
26+
- name: MLFLOW_REGISTRY_URI
27+
value: "databricks-uc"

0 commit comments

Comments
 (0)