This guide explains how to build an AI Agent using CrewAI for orchestrating SQL queries and GibsonAI for handling data storage and CRUD operations via its Data API.
What You’ll Build
- A CrewAI Agent that uses the GibsonAI Data API to read and write data.
- You will define tables in GibsonAI, and CrewAI will use its API to query or insert records.
- The example provided demonstrates storing sales contact information in GibsonAI.
Key Concept
- GibsonAI exposes a REST Data API for all created tables.
- CrewAI can query and perform CRUD operations directly via this API, making it a powerful backend for AI agents.
- The ability to execute SQL queries via GibsonAI’s
/query
endpoint.
GitHub Repo Link: Sales Contact Finder (CrewAI + GibsonAI)
Prerequisites
Before you begin, ensure you have:
- A GibsonAI Account – Sign up at https://app.gibsonai.com.
- A GibsonAI API Key – Create a project in GibsonAI and copy the API key from the Connect tab.
- Python 3.9+ installed.
- OpenAI API Key – Get one here.
- Serper.dev API Key (if using web scraping/search features).
Generate Your Database Schema in GibsonAI
Use the following prompt in GibsonAI to create the schema:
I want to create a sales contact aggregator agent. Generate a “sales_contact” table with fields (company_id, name, title, linkedin_url, phone, email). Also create a “sales_company” table with fields (name). All string fields, except name, are nullable.
Click Deploy and copy the API Key.
Implement CrewAI Tool for SQL Operations
CrewAI will communicate with GibsonAI’s Data API for CRUD operations. Below is an example ContactStorageTool:
import json import os import requests from dotenv import load_dotenv from pydantic import Field from crewai.tools import BaseTool load_dotenv() # Load environment variables from .env class ContactStorageTool(BaseTool): name: str = "ContactStorageTool" description: str = """ Saves contact information in a GibsonAI database using the hosted API. Expected payload format: {"company_name": "Company Name", "contacts": [{"name": "Name", "title": "Title", "linkedin_url": "LinkedIn URL", "phone": "Phone", "email": "Email"}]} """ api_base_url: str = Field(description="The base URL of the GibsonAI API") api_key: str = Field(description="The API key associated with your GibsonAI project") def __init__(self): self.api_base_url = "https://api.gibsonai.com/v1/-" self.api_key = os.getenv("GIBSONAI_API_KEY") if not self.api_key: raise ValueError("Missing GIBSONAI_API_KEY environment variable") super().__init__() def _run(self, contact_info: str) -> str: try: contact_data = json.loads(contact_info) if isinstance(contact_info, str) else contact_info company_name = contact_data["company_name"] contacts = contact_data["contacts"] # Insert company company_payload = {"name": company_name} response = requests.post( f"{self.api_base_url}/sales-company", json=company_payload, headers={"X-Gibson-API-Key": self.api_key}, ) response.raise_for_status() company_id = response.json()["id"] print(f"Posted company: {response.status_code}") # Insert contacts for contact in contacts: contact_payload = { "company_id": company_id, "name": contact["name"], "title": contact["title"], "linkedin_url": contact["linkedin_url"], "phone": contact["phone"], "email": contact["email"], } response = requests.post( f"{self.api_base_url}/sales-contact", json=contact_payload, headers={"X-Gibson-API-Key": self.api_key}, ) print(f"Posted contact {contact['name']}: {response.status_code}") except Exception as e: return f"Failed to post contact: {str(e)}"
Check Your Data
Go to the GibsonAI Dashboard to see:
- Sales Company and Sales Contact tables.
- The data stored by the CrewAI agent.
Need help?
Join our Discord Server to ask questions or see what others are doing with GibsonAI.