Files
2026-07-13 13:30:30 +08:00

276 lines
8.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Install jq
echo "Installing jq"
sudo apt-get -y install jq
# Load env variables
source /tmp/env.sh
## Install pgadmin
echo "Installing pgadmin"
# Download certificate
curl -fsS https://www.pgadmin.org/static/packages_pgadmin_org.pub | sudo gpg --dearmor -o /usr/share/keyrings/packages-pgadmin-org.gpg
# Download pgAdmin4
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/packages-pgadmin-org.gpg] https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list && apt update'
# Install for web mode only:
sudo apt -y install pgadmin4-web
# Configure the webserver
echo "Configuring the pgadmin webserver"
export PGADMIN_SETUP_EMAIL=$PGADMIN_USER
export PGADMIN_SETUP_PASSWORD=$PGADMIN_PASSWORD
sudo -E /usr/pgadmin4/bin/setup-web.sh --yes
# Create ragdemos Database
echo "Creating the ragdemos database"
sql=$(
cat <<EOF
CREATE DATABASE ragdemos;
EOF
)
echo $sql | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d postgres
sleep 3
# Install AlloyDB AI extensions
echo "Installing AlloyDB AI extensions"
sql=$(
cat <<EOF
CREATE EXTENSION IF NOT EXISTS google_ml_integration VERSION '1.3' CASCADE;
GRANT EXECUTE ON FUNCTION embedding TO postgres;
EOF
)
echo $sql | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Install pgvector extension
sql=$(
cat <<EOF
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
EOF
)
echo $sql | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Register text-embedding-005 embedding model
sql=$(
cat <<EOF
CALL google_ml.create_model (
model_id => 'text-embedding-005',
model_provider => 'google',
model_qualified_name => 'text-embedding-005',
model_type => 'text_embedding',
model_auth_type => 'alloydb_service_agent_iam'
);
EOF
)
echo $sql | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Register Gemini model
GEMINI_ENDPOINT="https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${REGION}/publishers/google/models/gemini-2.0-flash-001:generateContent"
sql=$(
cat <<EOF
CALL
google_ml.create_model (
model_id => 'gemini',
model_request_url => '${GEMINI_ENDPOINT}',
model_provider => 'google',
model_auth_type => 'alloydb_service_agent_iam'
);
EOF
)
echo $sql | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Create investments table and indexes
echo "Creating tables"
sql=$(
cat <<EOF
CREATE TABLE investments (
id SERIAL PRIMARY KEY,
ticker VARCHAR(255) NOT NULL UNIQUE,
etf BOOLEAN,
market VARCHAR(255),
rating TEXT,
overview TEXT,
overview_embedding VECTOR (768),
analysis TEXT,
analysis_embedding VECTOR (768)
);
DROP INDEX IF EXISTS idx_hnsw_co_investments_overview_embedding;
CREATE INDEX idx_hnsw_co_investments_overview_embedding
ON investments USING hnsw (overview_embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
DROP INDEX IF EXISTS idx_hnsw_co_investments_analysis_embedding;
CREATE INDEX idx_hnsw_co_investments_analysis_embedding
ON investments USING hnsw (analysis_embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Create the user_profiles table
sql=$(
cat <<EOF
CREATE TABLE user_profiles (
id SERIAL PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash CHAR(60) NOT NULL,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
age INT,
risk_profile TEXT,
bio TEXT,
bio_embedding VECTOR(768)
);
DROP INDEX IF EXISTS idx_user_profiles_bio_embedding;
CREATE INDEX idx_user_profiles_bio_embedding
ON user_profiles USING hnsw (bio_embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Create the conversation_history table and indexes
sql=$(
cat <<EOF
CREATE TABLE IF NOT EXISTS conversation_history (
id SERIAL PRIMARY KEY,
user_id INTEGER,
user_prompt TEXT,
user_prompt_embedding VECTOR(768) GENERATED ALWAYS AS (google_ml.embedding('text-embedding-005', user_prompt)::vector) STORED,
ai_response TEXT,
ai_response_embedding VECTOR(768) GENERATED ALWAYS AS (google_ml.embedding('text-embedding-005', ai_response)::vector) STORED,
datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
DROP INDEX IF EXISTS idx_hnsw_co_conversation_history_user_prompt_embedding;
CREATE INDEX idx_hnsw_co_conversation_history_user_prompt_embedding
ON conversation_history USING hnsw (user_prompt_embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
DROP INDEX IF EXISTS idx_hnsw_co_conversation_history_ai_response_embedding;
CREATE INDEX idx_hnsw_co_conversation_history_ai_response_embedding
ON conversation_history USING hnsw (ai_response_embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Create the langchain_vector_store table and index
sql=$(
cat <<EOF
DROP TABLE IF EXISTS public.langchain_vector_store;
CREATE TABLE IF NOT EXISTS public.langchain_vector_store
(
langchain_id uuid NOT NULL,
content text COLLATE pg_catalog."default" NOT NULL,
embedding vector(768) NOT NULL,
source character varying COLLATE pg_catalog."default",
page integer,
ticker character varying COLLATE pg_catalog."default",
page_size integer,
doc_ai_shard_count integer,
doc_ai_shard_index integer,
doc_ai_chunk_size integer,
doc_ai_chunk_uri character varying COLLATE pg_catalog."default",
page_chunk integer,
chunk_size integer,
langchain_metadata json,
CONSTRAINT langchain_vector_store_pkey PRIMARY KEY (langchain_id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.langchain_vector_store
OWNER to postgres;
DROP INDEX IF EXISTS public.idx_hnsw_co_langchain_vector_store_embedding;
CREATE INDEX IF NOT EXISTS idx_hnsw_co_langchain_vector_store_embedding
ON public.langchain_vector_store USING hnsw
(embedding vector_cosine_ops)
TABLESPACE pg_default;
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Download test data
echo "Downloading data"
cd || echo "Could not cd into user profile root"
mkdir -p /tmp/demo-data
cd /tmp/demo-data || echo "Could not cd into user profile root"
gcloud storage cp \
"gs://pr-public-demo-data/genwealth-demo/investments-005" \
"gs://pr-public-demo-data/genwealth-demo/user_profiles-005" \
"gs://pr-public-demo-data/genwealth-demo/llm-gemini.sql" .
# Load the investments table
echo "Loading the investments table"
sql=$(
cat <<EOF
\copy investments FROM '/tmp/demo-data/investments-005' WITH (FORMAT csv, DELIMITER '|', QUOTE "'", ESCAPE "'")
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Load the user_profiles table
echo "Loading the user_profiles table"
sql=$(
cat <<EOF
\copy user_profiles FROM '/tmp/demo-data/user_profiles-005' WITH (FORMAT csv, DELIMITER '|', QUOTE "'", ESCAPE "'")
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
# Create the llm() function
echo "Creating the llm() function"
PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos <llm-gemini.sql
# Create embeddings triggers for investments table
echo "Creating embeddings triggers"
sql=$(
cat <<EOF
CREATE OR REPLACE FUNCTION update_overview_embedding() RETURNS trigger AS \$\$
BEGIN
NEW.overview_embedding := google_ml.embedding('text-embedding-005', NEW.overview)::vector;
RETURN NEW;
END;
\$\$ LANGUAGE plpgsql;
CREATE OR REPLACE TRIGGER overview_update_trigger
BEFORE INSERT OR UPDATE OF overview ON investments
FOR EACH ROW
EXECUTE PROCEDURE update_overview_embedding();
-- Analysis overview and function
CREATE OR REPLACE FUNCTION update_analysis_embedding() RETURNS trigger AS \$\$
BEGIN
NEW.analysis_embedding := google_ml.embedding('text-embedding-005', NEW.analysis)::vector;
RETURN NEW;
END;
\$\$ LANGUAGE plpgsql;
CREATE OR REPLACE TRIGGER analysis_update_trigger
BEFORE INSERT OR UPDATE OF analysis ON investments
FOR EACH ROW
EXECUTE PROCEDURE update_analysis_embedding();
EOF
)
echo "$sql" | PGPASSWORD=${ALLOYDB_PASSWORD} psql -h "${ALLOYDB_IP}" -U postgres -d ragdemos
echo "Access the pgadmin interface using the URL below:"
echo "http://$(curl -s ifconfig.me)/pgadmin4"
echo "Connect to AlloyDB using the following IP:"
echo "$ALLOYDB_IP"