This is a submission for the Agentic Postgres Challenge with Tiger Data
Problem that I discovered
Freelancers often struggle to find jobs that truly match their skills, while clients spend too much time sorting through proposals that don’t fit their project needs. Traditional freelancing platforms rely on keyword matching, which often misses the context or intent behind a job or service.
The solution for it
A smarter freelancing platform that automatically matches freelancers’ services with client job postings using Agentic Postgres. The system analyzes job descriptions and service listings semantically, understanding what the client needs and which freelancers can deliver the best results.
What I Built
My application is a modern freelancing marketplace with two main roles:
- Freelancers: Create detailed service listings describing their skills, pricing, and deliverables.
- Clients: Post jobs with requirements and budgets.
Agentic Postgres powers the intelligent recommendation layer that suggests the most relevant freelancers to each job — helping clients find ideal candidates faster and improving visibility for freelancers.
Inspiration:
I’ve often seen clients overwhelmed with irrelevant bids and freelancers missing good opportunities. I wanted to create a fair, intelligent matching system that benefits both sides.
How I Used Agentic Postgres
I leveraged several Agentic Postgres features to build a powerful and intelligent recommendation system:
- 🧠 pg_text search: Used for semantic matching between job descriptions and freelancer service listings. This allows the system to recommend services that mean the same thing, not just share the same keywords.
- ⚡ Fast Forks: Enabled isolated testing and prototyping of different matching algorithms without duplicating data manually.
- 🔍 Tiger CLI: Simplified schema management and quick querying during development.
- 💾 Fluid Storage: Used to manage vector embeddings for freelancer service descriptions and job texts, improving search and recommendation speed.
Below is a simplified version of how I implemented semantic matching between jobs and freelancer services using Agentic Postgres:
-- Enable the Agentic Postgres extensions
CREATE EXTENSION IF NOT EXISTS pg_text;
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS tiger;
-- 1️⃣ Create tables for freelancers and jobs
CREATE TABLE freelancers (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
service_title TEXT,
service_description TEXT,
service_embedding vector(768) -- store embedding for semantic search
);
CREATE TABLE jobs (
id SERIAL PRIMARY KEY,
client_name TEXT NOT NULL,
job_title TEXT,
job_description TEXT,
job_embedding vector(768) -- embedding for matching
);
-- 2️⃣ Generate embeddings using pg_text (powered by built-in LLM models)
-- These embeddings capture the semantic meaning of text
UPDATE freelancers
SET service_embedding = pg_text.embed(service_description);
UPDATE jobs
SET job_embedding = pg_text.embed(job_description);
-- 3️⃣ Create an index for fast vector search (Fluid Storage optimization)
CREATE INDEX ON freelancers USING ivfflat (service_embedding vector_cosine_ops);
-- 4️⃣ Recommend freelancers for a given job
-- This query finds the top 5 freelancers whose services semantically match the job
SELECT
f.id,
f.name,
f.service_title,
1 - (f.service_embedding <=> j.job_embedding) AS similarity_score
FROM
freelancers f, jobs j
WHERE
j.id = 1 -- target job
ORDER BY
f.service_embedding <=> j.job_embedding -- cosine distance
LIMIT 5;
-- 5️⃣ (Optional) Store accepted matches for analytics
CREATE TABLE job_matches (
job_id INT REFERENCES jobs(id),
freelancer_id INT REFERENCES freelancers(id),
match_score FLOAT
);
INSERT INTO job_matches (job_id, freelancer_id, match_score)
SELECT j.id, f.id, 1 - (f.service_embedding <=> j.job_embedding)
FROM freelancers f, jobs j
WHERE j.id = 1
ORDER BY f.service_embedding <=> j.job_embedding
LIMIT 1;
🔍 Explanation of What’s Happening
-
pg_text.embed()automatically converts text(like job descriptions)into embeddings using built-in models. -
vector(768)stores the embedding efficiently in Postgres. -
ivfflat index (with vector_cosine_ops)makes vector similarity search super fast. - The query ranks freelancers by semantic similarity, not just keywords — so “web app developer” matches “React frontend engineer,” even if the words differ.
- Finally, the match results can be inserted into a
job_matchestable to record accepted pairings.
This combination allowed me to build a fast, agentic recommendation engine directly inside Postgres — no external vector database required.
Overall Experience
Building with Agentic Postgres was a smooth and surprisingly fun experience. I was impressed by how seamlessly I could integrate AI-powered text search and recommendation logic directly into the database.
What worked well:
- Semantic matching was fast and accurate.
- The Tiger CLI made experimentation effortless.
- Easy to scale and test different models using fast forks.
Challenges:
- Fine-tuning embeddings for different categories of jobs required experimentation.
- Understanding how to optimize queries for vector search took some learning.
Learnings:
Agentic Postgres makes it possible to bring intelligence closer to the data layer, reducing the need for complex backend logic. It’s perfect for building AI-driven, real-time recommendation systems like this freelancing platform.
Top comments (2)
Comment your thoughts
Some comments may only be visible to logged-in visitors. Sign in to view all comments.