Spring AI Alibaba DataAgent Documentation

repository·main·Indexed 25 days ago

https://github.com/spring-ai-alibaba/dataagent

An enterprise-grade intelligent data analysis agent built on Spring AI Alibaba Graph, featuring Text-to-SQL, Python-based deep data analysis, automated ECharts reporting, and Model Context Protocol (MCP) support. The documentation covers the Nuxt-based frontend, including UI components like BaseDrawer and ConfirmDialog, composables such as useConfirm and useCrudPage, and services for agent and data source management.

Tokens
106.3K
Snippets
212
Records
419
Agent score
81%

What's inside Spring AI Alibaba DataAgent

  1. Overview of Spring AI Alibaba DataAgent Core Features

    main

    DataAgent is an enterprise-grade intelligent data analysis agent built on Spring AI Alibaba Graph. It goes beyond simple Text-to-SQL by providing deep analysis capabilities and automated reporting.

    Key Capabilities

    • Intelligent Data Analysis: Uses StateGraph for Text-to-SQL conversion, supporting complex multi-table queries and multi-turn dialogue.
    • Python Deep Analysis: Executes generated code within task-level containers using the Spring AI Alibaba Sandbox. It supports PEP 723 dynamic dependencies, resource limits, failure retries, and automatic cleanup.
    • Smart Report Generation: Automatically summarizes analysis results into HTML/Markdown reports containing ECharts visualizations.
    • Human-in-the-loop: Includes a feedback mechanism allowing users to intervene and adjust plans during the generation phase.
    • RAG (Retrieval-Augmented Generation): Integrates with vector databases to perform semantic retrieval on business metadata and terminology, improving SQL accuracy.
    • Multi-Model Orchestration: Features a model registry that allows runtime switching between different LLMs and Embedding models (compatible with OpenAI specifications, e.g., Qwen, Deepseek).
    • MCP Server Support: Implements the Model Context Protocol, allowing DataAgent to act as a Tool Server for ecosystems like Claude Desktop, providing NL2SQL and agent management capabilities.
    • API Key Management: Provides lifecycle management and fine-grained permission control for API keys.
  2. Overview of the DataAgent TDD Test Implementation Plan

    main

    The DataAgent TDD (Test-Driven Development) implementation plan aims to achieve 80%+ backend test coverage using a 7-phase bottom-up approach. The strategy involves cleaning up 'fake' tests (stubs that don't test real logic), restoring real tests, and then adding new tests layer by layer following this hierarchy:

    1. Utilities
    2. Dispatchers
    3. Nodes
    4. Services
    5. Controllers/Connectors
    6. Integration

    Tech Stack:

    • Testing Frameworks: JUnit 5, Mockito (using LENIENT strictness), reactor-test
    • Infrastructure: Testcontainers (MySQL 8.0)
    • Coverage: JaCoCo
    • Spring Testing: Spring WebFluxTest
  3. Overview of DataAgent System Architecture

    main

    DataAgent is organized into several functional layers that facilitate an AI-driven data analysis workflow:

    • Clients: Includes the data-agent-frontend-nuxt UI, an Admin Console, and MCP Clients.
    • Access Layer: Provides communication via REST API and SSE Stream (Server-Sent Events).
    • Management (Spring Boot): The core engine containing controllers (GraphController, AgentController, PromptConfigController, ModelConfigController), services for LLM management (LlmService, AiModelRegistry), vector retrieval (AgentVectorStoreService), and a StateGraph Workflow for agent orchestration.
    • Data Storage: Persists business data (Business DB), management metadata (Management DB), vector embeddings (Vector Store), and unstructured knowledge (Knowledge Files).
    • LLM Providers: Supports various Chat and Embedding models.
    • Python Sandbox Runtime: A secure execution environment using SAA SandboxService and Docker Engine to run generated Python code in task-scoped sandboxes.
  4. How the DataAgent Runtime Main Flow works

    main

    The DataAgent operates using a structured workflow (StateGraph) that moves from intent recognition to final reporting. The main lifecycle follows these stages:

    1. Context & Intent: Builds multi-turn context and uses an IntentRecognitionNode to determine if analysis is required.
    2. Retrieval & Enhancement: Uses EvidenceRecallNode, QueryEnhanceNode, SchemaRecallNode, and TableRelationNode to gather necessary metadata and schema information.
    3. Planning: Performs a FeasibilityAssessmentNode check. If feasible, a PlannerNode creates a plan, which is validated by PlanExecutor. A HumanGate allows for manual review/feedback.
    4. Execution Loops:
      • SQL Path: SqlGenerateNode $\rightarrow$ SemanticConsistencyNode $\rightarrow$ SqlExecuteNode. If execution fails, it retries generation.
      • Python Path: PythonGenerateNode $\rightarrow$ PythonExecuteNode $\rightarrow$ PythonAnalyzeNode.
    5. Reporting: The ReportGeneratorNode synthesizes the results into a final report.
  5. Assess DataAgent workflow node complexity

    main

    DataAgent workflow nodes are categorized by complexity levels based on their logic and external dependencies. This classification helps in planning testing strategies and resource allocation.

    • Very Low: Nodes with pure logic and no external dependencies (e.g., PlanExecutorNode, HumanFeedbackNode).
    • Low: Nodes with a single LLM dependency (e.g., IntentRecognitionNode, FeasibilityAssessmentNode, PythonAnalyzeNode, SemanticConsistencyNode).
    • Medium: Nodes with 2-3 dependencies (e.g., SqlGenerateNode, PlannerNode, PythonGenerateNode, QueryEnhanceNode, SchemaRecallNode, TableRelationNode, ReportGeneratorNode).
    • High: Nodes with approximately 5 dependencies requiring DB mocking (e.g., SqlExecuteNode).
    • Very High: Nodes requiring multiple external services (e.g., EvidenceRecallNode, PythonExecuteNode).
    | Complexity Level | Nodes | Strategy |
    |----------------|-------|----------|
    | Very Low | PlanExecutorNode, HumanFeedbackNode | Pure logic, no external deps |
    | Low | IntentRecognitionNode, FeasibilityAssessmentNode, PythonAnalyzeNode, SemanticConsistencyNode | Single LLM dependency |
    | Medium | SqlGenerateNode, PlannerNode, PythonGenerateNode, QueryEnhanceNode, SchemaRecallNode, TableRelationNode, ReportGeneratorNode | 2-3 dependencies |
    | High | SqlExecuteNode | 5 dependencies, DB mocking |
    | Very High | EvidenceRecallNode, PythonExecuteNode | Multiple external services |
  6. Manage workflow state with OverAllState

    main

    In DataAgent, OverAllState is the mechanism used to pass data between workflow nodes. When writing tests, you must follow a specific lifecycle for state management to ensure data is correctly accessible and typed.

    1. Register Keys

    CRITICAL: You must register state keys and their associated replacement strategies before attempting to use them. Failure to do this is a common cause of low test coverage.

    2. Update State

    Use updateState to inject data into the workflow state, typically using a map of constant keys to values.

    3. Retrieve State Values

    Use StateUtil to extract values from the state. This utility provides type-specific methods to ensure the data retrieved matches the expected type (e.g., String, Integer, or custom DTOs).

    // 1. Register keys before use (CRITICAL)
    state.registerKeyAndStrategy(SQL_GENERATE_OUTPUT, new ReplaceStrategy());
    
    // 2. Set state values
    state.updateState(Map.of(
        SQL_GENERATE_OUTPUT, "SELECT * FROM users",
        SQL_GENERATE_COUNT, 0
    ));
    
    // 3. Get state values (via StateUtil)
    String sql = StateUtil.getStringValue(state, SQL_GENERATE_OUTPUT);
    SchemaDTO schema = StateUtil.getObjectValue(state, TABLE_RELATION_OUTPUT, SchemaDTO.class);
  7. Understand the DataAgent System Architecture

    main

    DataAgent follows a multi-layered architecture designed to handle complex data analysis tasks through LLM-driven workflows.

    Core Layers:

    • Clients: Includes the data-agent-frontend-nuxt UI, an Admin Console, and MCP Clients.
    • Access Layer: Provides communication via REST API and SSE Stream (Server-Sent Events).
    • Management (Spring Boot): The core engine containing controllers (GraphController, AgentController, PromptConfigController, ModelConfigController), services for LLM orchestration (LlmService), vector retrieval (AgentVectorStoreService), and a Python sandbox execution environment (PythonCodeExecutorService).
    • Execution Layer: Uses a Python Sandbox Runtime powered by Docker Engine and SAA SandboxService to safely execute generated code.
    • Data Layer: Manages Business DBs, Metadata (Management DB), Vector Stores, and Knowledge Files.
    • Observability: Integrates with the Langfuse Platform for monitoring and tracing.
    %%{init: {"theme": "base", "flowchart": {"curve": "basis", "nodeSpacing": 35, "rankSpacing": 45}, "themeVariables": {"lineColor": "#475569", "primaryTextColor": "#1F2937"}}}
    %%
    flowchart LR
      subgraph Clients[Clients]
        UserUI[data-agent-frontend-nuxt UI]
        AdminUI[Admin Console]
        MCPClient[MCP Client]
      end
    
      subgraph Access[Access Layer]
        RestAPI[REST API]
        SSE[SSE Stream]
      end
    
      subgraph Management[data-agent-management Spring Boot]
        GraphCtl[GraphController]
        AgentCtl[AgentController]
        PromptCtl[PromptConfigController]
        ModelCtl[ModelConfigController]
        GraphSvc[GraphServiceImpl]
        Context[MultiTurnContextManager]
        Graph[StateGraph Workflow]
        LlmSvc[LlmService]
        ModelRegistry[AiModelRegistry]
        VectorSvc[AgentVectorStoreService]
        Hybrid[HybridRetrievalStrategy]
        CodeExec[PythonCodeExecutorService]
        McpSvc[McpServerService]
        LangfuseSvc[LangfuseService]
      end
    
      subgraph Observability[Observability]
        Langfuse[Langfuse Platform]
      end
    
      subgraph Data[Data Storage]
        BizDB[(Business DB)]
        MetaDB[(Management DB)]
        VectorDB[(Vector Store)]
        Files[(Knowledge Files)]
      end
    
      subgraph LLMs[LLM Providers]
        ChatLLM[Chat Model]
        EmbeddingLLM[Embedding Model]
      end
    
      subgraph Exec[Python Sandbox Runtime]
        SandboxSvc[SAA SandboxService]
        DockerEngine[Docker Engine]
        TaskSandbox[Task-scoped BaseSandbox]
        PackageIndex[(PyPI / Private Package Index)]
      end
    
      UserUI --> RestAPI
      UserUI --> SSE
      AdminUI --> RestAPI
      MCPClient --> McpSvc
      RestAPI --> AgentCtl
      RestAPI --> PromptCtl
      RestAPI --> ModelCtl
      SSE --> GraphCtl
      GraphCtl --> GraphSvc
      GraphSvc --> Context
      GraphSvc --> Graph
      Graph --> LlmSvc
      GraphSvc --> VectorSvc
      VectorSvc --> Hybrid
      VectorSvc --> VectorDB
      VectorSvc --> Files
      Graph --> BizDB
      GraphSvc --> ModelRegistry
      ModelRegistry --> ChatLLM
      ModelRegistry --> EmbeddingLLM
      Graph --> CodeExec
      CodeExec --> SandboxSvc
      SandboxSvc --> DockerEngine
      DockerEngine --> TaskSandbox
      TaskSandbox --> PackageIndex
      GraphSvc --> LangfuseSvc
      LangfuseSvc --> Langfuse
      AgentCtl --> MetaDB
      PromptCtl --> MetaDB
      ModelCtl --> MetaDB
  8. Apply Backend Design Principles

    main

    The backend architecture follows these core principles to ensure maintainability and testability:

    • Single Responsibility: Separate concerns such as environment resolution, Docker client creation, image preparation, and task execution into distinct components.
    • Dependency Inversion: Orchestration logic should depend on small, stable contracts (e.g., a Docker gateway contract) rather than constructing infrastructure internally.
    • Explicit Side Effects: Constructors should only assign dependencies. They must not connect to services, pull images, or start long-running work.
    • Fail-Fast Contracts: Reject invalid configurations immediately with specific, testable exceptions and messages.
    • Encapsulation: Extract collaborators only when they represent a coherent policy or an external boundary, not just to reduce class size.
    • Compatibility: Maintain existing service interfaces and configuration properties while refactoring implementation details behind new collaborators.
  9. Pattern for implementing Workflow Node tests

    main

    When implementing tests for workflow nodes (e.g., QueryEnhanceNode, PlannerNode), follow this standardized pattern to ensure consistency:

    1. Annotations: Use @ExtendWith(MockitoExtension.class) and @MockitoSettings(strictness = Strictness.LENIENT).
    2. Mocking: Use @Mock to declare all constructor dependencies.
    3. Setup: Initialize the node in a @BeforeEach method using constructor injection.
    4. State Management: Use TestFixtures.createStateWith() to set up the OverAllState.
    5. Service Mocking: Mock service responses using when(...).thenReturn(Flux.just(...)).
    6. Assertion: Call node.apply(state) and assert the returned Map<String, Object> or the next node in the graph.
  10. Understand the Python Sandbox execution lifecycle

    main

    The Python execution follows a strict two-phase, task-level sandbox lifecycle to ensure isolation and security:

    1. Sandbox Creation: A new, independent BaseSandbox is created for every task. It is non-privileged and isolated from other agents or sessions.
    2. Dependency Installation Phase: The backend uses a fixed bootstrap command to install dependencies into a specific target directory (/tmp/dataagent-deps) using pip. This phase is subject to dependency-install-timeout.
    3. Code Execution Phase: The Python code is executed via python -c <code_string>. The PYTHONPATH is set to include the dependency directory. Input data is passed via stdin. This phase is subject to code-timeout.
    4. Cleanup: Once the task completes (successfully or via error), the sandbox is closed and the container is deleted. No state is reused between retries or different tasks.