Getting Started with OpenAI Codex

A strong way to use Codex for this is to make AGENTS.md define the architecture and engineering rules, then give Codex small issue-style tasks such as “build authentication” or “build the chat shell.”

OpenAI recommends exactly this pattern: AGENTS.md supplies persistent repository context, while individual Codex prompts describe concrete changes. OpenAI also recommends keeping AGENTS.md relatively concise and pointing to deeper documentation as the project grows.

For a boilderplate project, start with this stack:

Next.js / React / TypeScript
        │
        ├── Tailwind CSS + shadcn/ui
        │
        ├── Auth.js
        │    ├── Email magic link
        │    ├── Google OAuth
        │    └── Microsoft Entra ID OAuth
        │
        ├── PostgreSQL
        │    └── Prisma ORM
        │
        └── Chat API
             ├── OpenAI-compatible endpoint
             └── later: OpenAI / vLLM / other models

Next.js continues to recommend the App Router for full-stack applications, and its authentication documentation uses NextAuth/Auth.js-style authentication and protected routes.

1. Start with an empty repository

For example:

mkdir chatapp
cd chatapp

git init

touch AGENTS.md

Your initial repository can be almost empty:

chatapp/
├── AGENTS.md
├── README.md
└── .gitignore

Then open that directory with Codex.

The important point is that you don't need to manually create the application first. Give Codex the architecture through AGENTS.md, then tell it to scaffold the repository.


2. Example AGENTS.md

Here is the kind of AGENTS.md I would use.

# AGENTS.md

## Project

This repository contains a ChatGPT-style AI chat web application.

The application must provide:

- Chat as the default authenticated page.
- Email magic-link authentication.
- Google OAuth authentication.
- Microsoft Entra ID OAuth authentication.
- Persistent users and sessions.
- Persistent chat conversations.
- Responsive desktop/mobile UI.
- Dark and light mode.
- A clean ChatGPT-inspired interface without copying OpenAI branding.

---

## Technology Stack

Use:

- Next.js latest stable version
- App Router
- TypeScript
- React
- Tailwind CSS
- shadcn/ui where appropriate
- Auth.js for authentication
- PostgreSQL
- Prisma ORM
- Zod for input validation
- pnpm as package manager

Do not introduce another framework without a clear requirement.

---

## Application Routes

The primary routes are:

/                    -> redirect based on authentication
/chat                -> default authenticated page
/chat/[id]           -> existing conversation
/login               -> authentication page
/settings            -> user settings
/api/auth/*           -> Auth.js
/api/chat             -> chat API

Unauthenticated users attempting to access protected pages
must be redirected to /login.

Authenticated users visiting / should be redirected to /chat.

---

## Authentication

Use Auth.js.

Support these authentication methods:

1. Email magic link
2. Google OAuth
3. Microsoft Entra ID OAuth

Do not implement password authentication.

Authentication secrets and OAuth credentials must only come
from environment variables.

Never commit secrets.

Required environment variables should be documented in:

.env.example

Authentication configuration should support:

AUTH_SECRET

DATABASE_URL

AUTH_GOOGLE_ID
AUTH_GOOGLE_SECRET

AUTH_MICROSOFT_ENTRA_ID_ID
AUTH_MICROSOFT_ENTRA_ID_SECRET
AUTH_MICROSOFT_ENTRA_ID_ISSUER

EMAIL_SERVER_HOST
EMAIL_SERVER_PORT
EMAIL_SERVER_USER
EMAIL_SERVER_PASSWORD
EMAIL_FROM

Exact variable names may be adjusted to match the current
Auth.js provider API, but document any changes.

---

## Database

Use PostgreSQL with Prisma.

Initial data model:

User
Account
Session
VerificationToken
Conversation
Message

Conversation fields should include:

- id
- userId
- title
- createdAt
- updatedAt

Message fields should include:

- id
- conversationId
- role
- content
- createdAt

A conversation belongs to exactly one user.

Never allow one user to access another user's conversations.

---

## Chat UI

The default authenticated application should resemble the
interaction pattern of ChatGPT.

Layout:

+------------------------------------------------------+
| Sidebar             | Chat                          |
|                     |                               |
| + New Chat          |          messages             |
|                     |                               |
| Recent chats        |                               |
|                     |                               |
|                     |                               |
| User                 |                              |
| Settings             |                              |
|---------------------|-------------------------------|
|                     | Ask anything...        Send  |
+------------------------------------------------------+

Sidebar:

- New Chat
- Conversation history
- Settings
- User/account menu
- Sign out

Main chat area:

- conversation messages
- streaming assistant responses
- multiline composer
- send button
- loading state
- error state

Do not copy ChatGPT logos, product names, icons, or proprietary
visual assets.

---

## Chat Backend

Create a provider abstraction rather than tightly coupling
the UI to one AI provider.

Use an interface similar to:

interface ChatProvider {
  stream(messages: ChatMessage[]): Promise<ReadableStream>
}

Initial implementation may use an OpenAI-compatible API.

Provider configuration should come from environment variables:

AI_BASE_URL
AI_API_KEY
AI_MODEL

This design must make it possible to point the application at:

- OpenAI
- vLLM
- another OpenAI-compatible endpoint

without changing UI code.

---

## Security

Security is a first-class requirement.

Always:

- validate server inputs with Zod
- enforce authentication server-side
- enforce conversation ownership server-side
- use secure HTTP-only session cookies
- never expose API keys to browser JavaScript
- never log authentication tokens
- never log magic-link tokens
- never store OAuth access tokens unless required
- use parameterized database queries through Prisma
- return generic authentication errors
- sanitize user-controlled rendering where necessary

Do not rely only on client-side authorization.

---

## Project Structure

Prefer:

src/
├── app/
│   ├── (auth)/
│   │   └── login/
│   ├── (app)/
│   │   ├── chat/
│   │   └── settings/
│   └── api/
│
├── components/
│   ├── auth/
│   ├── chat/
│   ├── layout/
│   └── ui/
│
├── lib/
│   ├── auth/
│   ├── ai/
│   ├── db/
│   └── validation/
│
└── types/

prisma/
└── schema.prisma

docs/
├── architecture.md
└── authentication.md

---

## Coding Standards

- TypeScript strict mode.
- Avoid `any`.
- Prefer Server Components unless client state is required.
- Keep client components small.
- Keep authentication/database logic on the server.
- Prefer reusable components.
- Avoid files larger than approximately 300 lines.
- Use descriptive names.
- Do not duplicate business logic.

---

## Development Commands

Use:

pnpm install
pnpm dev
pnpm lint
pnpm typecheck
pnpm test
pnpm build

Before declaring a task complete:

1. Run lint.
2. Run typecheck.
3. Run tests if applicable.
4. Run production build.
5. Fix errors introduced by the change.

---

## Definition of Done

A feature is complete only when:

- implementation works
- authorization has been considered
- error states are handled
- loading states are handled
- TypeScript passes
- lint passes
- production build passes
- documentation is updated where necessary

Do not merely generate placeholder components unless the task
specifically requests placeholders.

This is where AGENTS.md becomes powerful. Instead of repeatedly telling Codex:

Use TypeScript.
Use PostgreSQL.
Don't expose secrets.
Use Auth.js.
Protect conversations.
Run lint and build.

Codex gets those instructions automatically as it operates in the repository. Codex also applies instructions according to directory scope, with deeper AGENTS.md files taking precedence when appropriate. OpenAI


3. First Codex prompt: create the boilerplate

Now your Codex prompt becomes surprisingly short.

I would give Codex:

Read AGENTS.md.

Create the initial project boilerplate described there.

Start by scaffolding a production-ready Next.js application using
pnpm, TypeScript, App Router, Tailwind and the directory structure
defined in AGENTS.md.

Implement the basic layouts and routes, but do not implement the
AI backend yet.

The authenticated application's default page should be /chat.

Create:

- login page
- application layout
- chat page
- chat sidebar
- new-chat button
- empty conversation state
- message composer
- settings placeholder
- .env.example
- Prisma configuration
- basic README

Run lint, typecheck, and build when complete.

Show me a summary of files created and any decisions you made.

Notice the prompt resembles a GitHub issue rather than a vague request such as:

Build me something like ChatGPT.

OpenAI specifically recommends issue/PR-style prompts containing concrete scope, files, components, and acceptance requirements.

Codex might create something like:

ai-chat/
│
├── AGENTS.md
├── README.md
├── .env.example
├── package.json
├── next.config.ts
├── tsconfig.json
│
├── prisma/
│   └── schema.prisma
│
└── src/
    ├── app/
    │   ├── layout.tsx
    │   ├── page.tsx
    │   │
    │   ├── (auth)/
    │   │   └── login/
    │   │       └── page.tsx
    │   │
    │   └── (app)/
    │       ├── layout.tsx
    │       ├── chat/
    │       │   ├── page.tsx
    │       │   └── [id]/
    │       │       └── page.tsx
    │       │
    │       └── settings/
    │           └── page.tsx
    │
    ├── components/
    │   ├── chat/
    │   │   ├── chat-layout.tsx
    │   │   ├── chat-message.tsx
    │   │   ├── chat-composer.tsx
    │   │   └── conversation-list.tsx
    │   │
    │   ├── layout/
    │   │   └── sidebar.tsx
    │   │
    │   └── ui/
    │
    └── lib/
        ├── auth/
        ├── ai/
        └── db/

4. Second Codex task: authentication

Don't ask Codex to build everything simultaneously.

Next prompt:

Read AGENTS.md and inspect the existing project.

Implement authentication.

Requirements:

- Auth.js
- PostgreSQL-backed Auth.js adapter
- Prisma
- email magic-link authentication
- Google OAuth
- Microsoft Entra ID OAuth
- custom /login page

There must be no password authentication.

Protect:

/chat
/chat/*
/settings

Behavior:

unauthenticated:
/ -> /login
/chat -> /login

authenticated:
/ -> /chat
/login -> /chat

Add all required variables to .env.example.

Never expose OAuth secrets or email credentials to client code.

Add documentation to docs/authentication.md explaining how to
configure Google, Microsoft, and email authentication.

Run database generation, lint, typecheck, tests where applicable,
and production build.

Auth.js provides OAuth provider support and custom sign-in functionality; the current Next.js authentication guidance also shows using server-side auth enforcement rather than relying exclusively on client-side checks.

Your login page could end up looking roughly like:

              ChatApp
   Your private AI assistant


   ┌─────────────────────────────┐
   │ you@company.com             │
   └─────────────────────────────┘

   ┌─────────────────────────────┐
   │     Continue with email     │
   └─────────────────────────────┘

             or

   ┌─────────────────────────────┐
   │ G   Continue with Google    │
   └─────────────────────────────┘

   ┌─────────────────────────────┐
   │ ▣   Continue with Microsoft │
   └─────────────────────────────┘

For email:

you@example.com
       │
       ▼
Auth.js generates token
       │
       ▼
verification token stored
in PostgreSQL
       │
       ▼
email sent
       │
       ▼
user clicks magic link
       │
       ▼
token validated
       │
       ▼
session created
       │
       ▼
/chat

5. Third Codex task: database ownership

This is one task I would deliberately separate from the UI.

Implement persistent conversations and messages.

Follow AGENTS.md.

Create the Prisma models required for:

User
Conversation
Message

Requirements:

- Conversation belongs to User.
- Message belongs to Conversation.
- Users can only read/write their own conversations.
- API/service functions must require authenticated user identity.
- Never accept userId from the browser as authorization.
- Determine userId from the authenticated server session.

Create service functions:

createConversation()
listConversations()
getConversation()
deleteConversation()
createMessage()
listMessages()

Add appropriate indexes.

Generate and validate the Prisma schema.

Add tests specifically checking that user A cannot access
user B's conversation.

That sentence:

Never accept userId from the browser as authorization.

is particularly important.

You want:

Browser
   │
   │ conversationId
   ▼
Server
   │
   ├── auth()
   │      ↓
   │   user.id
   │
   └── query:
       conversation.id = conversationId
       AND
       conversation.userId = user.id

rather than:

POST /conversation

{
   "userId": "123",       ← NEVER TRUST THIS
   "conversationId": "456"
}

6. Fourth task: ChatGPT-style chat

Now Codex has authentication and persistence to build on.

Implement the chat experience described in AGENTS.md.

The layout should be inspired by modern conversational AI
applications without copying OpenAI branding.

Desktop:

┌───────────────────┬────────────────────────────────┐
│ + New chat        │                                │
│                   │                                │
│ Today             │                                │
│ Architecture help │         Messages               │
│ SOC 2 questions   │                                │
│ vLLM tuning       │                                │
│                   │                                │
│                   │                                │
│                   │                                │
│ Isaac             │                                │
│ Settings          ├────────────────────────────────┤
│ Sign out          │ Ask anything...          ↑     │
└───────────────────┴────────────────────────────────┘

Requirements:

- collapsible sidebar
- new conversation
- conversation history
- current conversation highlighting
- multiline composer
- Enter sends
- Shift+Enter creates newline
- responsive mobile navigation
- loading state
- streaming message state
- empty conversation state
- dark mode
- accessible keyboard navigation

Do not implement fake AI responses.

Connect UI only to the application chat service abstraction.

Run lint, typecheck and build.

7. Then add the AI provider abstraction

This is especially useful if you want to use your own vLLM endpoint later.

Have Codex implement:

                  Chat UI
                     │
                     ▼
              POST /api/chat
                     │
                     ▼
               ChatService
                     │
                     ▼
              ChatProvider
                  interface
                     │
          ┌──────────┼───────────┐
          ▼          ▼           ▼
       OpenAI      vLLM       future

Prompt:

Implement the AI provider layer described in AGENTS.md.

Create a provider-neutral ChatProvider interface.

Implement an OpenAI-compatible provider using:

AI_BASE_URL
AI_API_KEY
AI_MODEL

The UI must not know whether the backend is OpenAI, vLLM,
or another compatible service.

Implement streaming responses.

POST /api/chat must:

1. authenticate the user
2. validate the request
3. verify conversation ownership
4. save the user message
5. invoke ChatProvider
6. stream the response
7. persist the assistant response

Do not expose AI_API_KEY to client JavaScript.

This is a design I would strongly favor for your boilerplate because it means you can later do something like:

AI_BASE_URL=https://your-vllm.example.com/v1
AI_API_KEY=xxxxxxxx
AI_MODEL=google/gemma-4-12b-it

or:

AI_BASE_URL=https://api.openai.com/v1
AI_API_KEY=xxxxxxxx
AI_MODEL=...

without rewriting the application.


8. Use nested AGENTS.md files as the project grows

This is one of the more useful features.

For example:

project/
│
├── AGENTS.md
│
├── src/
│   └── app/
│
└── src/lib/auth/
    └── AGENTS.md

Root:

AGENTS.md

contains general engineering rules.

Then:

src/lib/auth/AGENTS.md

could say:

# Authentication Agent Instructions

These instructions apply to src/lib/auth/**.

Authentication code is security-sensitive.

Requirements:

- Never log access tokens.
- Never expose provider secrets.
- Authentication must be performed server-side.
- Session authorization must use the authenticated server session.
- OAuth account linking must require matching verified identities.
- Do not automatically trust arbitrary email claims.
- Magic links must expire.
- Magic-link tokens must be single use.
- Authentication errors exposed to users must not reveal whether
  an account exists.

Changes to authentication logic must include tests.

Before completing authentication-related work run:

pnpm test
pnpm lint
pnpm typecheck
pnpm build

Codex uses instructions according to the file's directory scope, and deeper instructions override broader ones when they conflict. OpenAI

So now:

                  AGENTS.md
                      │
            project-wide rules
                      │
        ┌─────────────┴─────────────┐
        ▼                           ▼
 src/lib/auth                 src/lib/ai
 AGENTS.md                    AGENTS.md
        │                           │
 auth-specific                  AI-specific
 security rules                 provider rules

9. Keep architecture documentation outside AGENTS.md

I wouldn't eventually turn AGENTS.md into a 1,000-line specification.

A better mature repository looks like:

AGENTS.md

docs/
├── architecture.md
├── authentication.md
├── database.md
├── chat-api.md
├── security.md
└── deployment.md

And AGENTS.md says:

## Architecture

Read `docs/architecture.md` before making architecture-level changes.

## Authentication

Read `docs/authentication.md` before modifying authentication.

## Security

Security requirements are documented in `docs/security.md`.

This aligns with OpenAI's own reported approach: use AGENTS.md more as a concise map into the repository's deeper system of record rather than turning it into an enormous manual. OpenAI


10. The development workflow becomes simple

Instead of one enormous request:

Codex, build ChatGPT.

I would use Codex like this:

AGENTS.md
     │
     │ persistent architecture
     ▼
┌─────────────────────────────┐
│ Task 1                      │
│ Scaffold application       │
└──────────────┬──────────────┘
               ▼
┌─────────────────────────────┐
│ Task 2                      │
│ Authentication             │
└──────────────┬──────────────┘
               ▼
┌─────────────────────────────┐
│ Task 3                      │
│ Conversation persistence   │
└──────────────┬──────────────┘
               ▼
┌─────────────────────────────┐
│ Task 4                      │
│ Chat UI                    │
└──────────────┬──────────────┘
               ▼
┌─────────────────────────────┐
│ Task 5                      │
│ Streaming AI API           │
└──────────────┬──────────────┘
               ▼
┌─────────────────────────────┐
│ Task 6                      │
│ Tests/security review      │
└──────────────┬──────────────┘
               ▼
         Production baseline

The main advantage is that AGENTS.md turns Codex from a code generator into an engineer operating under your project's rules. The prompts tell it what to change; AGENTS.md tells it how this repository should be engineered.

For this particular boilerplate, make Chat → Auth → persistence → provider-neutral AI backend the core architecture. That gives you a clean starting point for an internal AI platform and also lets the same frontend point at OpenAI-compatible vLLM endpoints later without coupling the application to one model provider.

Read more

SOP Benchmark vLLM Models Using LiveBench

1. Purpose This SOP describes how to use LiveBench to evaluate model quality through a production-style vLLM OpenAI-compatible API. Environment: ComponentConfigurationInference EnginevLLMAPIOpenAI-compatibleEndpointhttps://dev-va-vllm.eveon.comAuthenticationAPI Key / Bearer TokenBenchmarkLiveBenchInfrastructureAWS ALB → EC2 → Docker → vLLM LiveBench is primarily used to evaluate model quality, including reasoning, coding, mathematics, data analysis, language, and instruction following.

By admin