Skip to content

Latest commit

 

History

History
244 lines (195 loc) · 5.75 KB

File metadata and controls

244 lines (195 loc) · 5.75 KB

AI Agent project

Description

This project is a full-stack demonstration of AI chatbot application with NestJS backend and React (Vite + Axios) as frontend. On top with the integration with Langgraph.js, Langchain.js, and Azure OpenAI as assistant

System supports

  • UUID-based chat sessions
  • Persistent chat history in JSON format
  • RESTful API with Swagger documentation
  • CLI-based interaction
  • Basic browser-based interface
  • search agent with Tavily
  • database with PostgreSQL server
  • CRUD operation on database
  • vector embedding
  • similarity search using vector & cosine similarity

Architecture

src
├── ai
│   ├── agent.state.ts
│   ├── ai.controller.spec.ts
│   ├── ai.controller.ts
│   ├── ai.graph.ts
│   ├── ai.module.ts
│   ├── ai.service.spec.ts
│   ├── ai.service.ts
│   ├── ask.dto.ts
│   ├── nodes
│   │   └── agent.node.ts
│   └── utils
│       └── tool.logger.ts
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── chat
│   ├── chat.controller.ts
│   ├── chat.module.ts
│   ├── chat.repository.ts
│   ├── chat.service.ts
│   └── chat.types.ts
├── cli.ts
├── data
│   └── chats.json
├── database
│   ├── database.controller.spec.ts
│   ├── database.controller.ts
│   ├── database.module.ts
│   ├── database.service.spec.ts
│   ├── database.service.ts
│   ├── database.types.ts
│   ├── dto
│   │   ├── create-company.dto.ts
│   │   ├── create-person.dto.ts
│   │   ├── create-worksfor.dto.ts
│   │   ├── update-company.dto.ts
│   │   ├── update-person.dto.ts
│   │   └── update-works-for.dto.ts
│   ├── models
│   │   ├── company.model.ts
│   │   ├── person.model.ts
│   │   └── works-for.model.ts
│   └── sequelize.provider.ts
├── llm
│   └── llm.module.ts
├── main.ts
├── seed.ts
└── tools
    ├── database
    │   ├── database.tool.schema.ts
    │   └── database.tool.ts
    ├── search
    │   ├── candidate-search.tool.ts
    │   ├── safe-tavily.tool.ts
    │   └── search-qa.util.ts
    ├── tools.module.ts
    ├── tools.service.spec.ts
    └── tools.service.ts

Backend Design

ai/

Graph Structure:
  • State: { messages: BaseMessage[] } using MessagesAnnotation
  • Nodes: agent and tools
  • Use addConditionalEdges to detect tool calls

tools/

  • SafeTavilySearchTool (in search/safe-tavily-tool.ts): perform web search, QA by score and freshness
  • DatabaseManagerTool (in database/database.tool.ts): Database CRUD operation
  • candidate-search.tool.ts (in tools/search/candidate-search.tool.ts): more complex search, web search for more info about the role/skills of candidate -> perform RAG -> answer
  • schema: zod discriminated union

chat/

  • Chat session creation (no delete feature yet)
  • Chat history retrieval
  • JSON storage at data/chats.json
  • main functionalities in chat.repository.ts

database/

  • sequelize provider: postgreSQL

  • 3 entities (Found in models/)

    • person: ['id', 'full_name', 'email']
    • company: ['id', 'company_name']
    • works_for: ['person_id', 'company_id', 'duration', 'position', 'responsibility']
  • supported methods

    • select
    • join
    • insert
    • update
    • delete

llm/

  • for llm modules for both chatbot and embedding

Alt Text

API

As per Swagger

Swagger Page

CLI (depreciated)

Entry Point

src/cli.ts

Development & Testing

start backend

npm run start:dev

go to chat

CLI Mode

npm run start:cli

seed

  • Used for adding data to database
npm run seed
  • use Axios to send requests to http://localhost:3000/api/ai/ask (foun in frontend/src/api/chat.api.js)
  • generate a uniquue sessionID per load
  • configuration: main.ts updated to enable CORS for port 5173

database server configuration

docker-compose.yaml

services:
  postgres:
    image: pgvector/pgvector:pg16
    container_name: ai-postgres
    restart: unless-stopped

    environment:
      POSTGRES_DB: ai_system
      POSTGRES_USER: ai_user
      POSTGRES_PASSWORD: ai_password

    ports:
      - "5432:5432"

    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres:/postgres
    
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 5s
      timeout: 5s
      retries: 5
    
volumes:
  postgres_data:

schema.sql

CREATE EXTENSION IF NOT EXISTS vector;
DROP TABLE IF EXISTS works_for;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS company;
CREATE TABLE person (
    id SERIAL PRIMARY KEY,
    full_name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE
);

CREATE TABLE company (
    id SERIAL PRIMARY KEY,
    company_name TEXT NOT NULL
);

CREATE TABLE works_for (
    person_id INT NOT NULL,
    company_id INT NOT NULL,
    duration INTERVAL,
    position TEXT,
    responsibility TEXT,


    PRIMARY KEY (person_id, company_id),

    CONSTRAINT fk_person
      FOREIGN KEY (person_id)
      REFERENCES person(id)
      ON DELETE CASCADE,

    CONSTRAINT fk_company
      FOREIGN KEY (company_id)
      REFERENCES company(id)
      ON DELETE CASCADE
);
ALTER TABLE works_for 
ADD COLUMN embedding vector(1536);