genai-lab
README.md
# GenAI Lab
**GenAI Lab** is a TypeScript playground for building controlled GenAI workflows with:
- Retrieval-Augmented Generation (RAG) over a local knowledge base
- LangGraph-based agent planning and routing
- MCP (Model Context Protocol) tools/resources/prompts
- bounded, safe fallback behavior
It is intentionally compact so the mechanics stay inspectable end-to-end.
---
## Neat project description
GenAI Lab demonstrates a practical pattern for safe AI agents: it separates **decision (LLM-planned routing)** from **execution (typed nodes for retrieval, drafting, answering, and finalization)**, and exposes the same core capabilities through a direct CLI and an MCP server interface.
---
## What the project includes
- `agent` flow (LangGraph)
- plans a response path based on a user request
- retrieves notes when needed
- drafts a message or answers a question from retrieved context
- retries retrieval once when first pass yields insufficient context
- returns deterministic fallback responses when appropriate
- RAG utilities
- local semantic search over notes using OpenAI embeddings
- source-grounded answers with `[note_x]` citations
- MCP surface
- `search_notes` tool
- `answer_from_notes` tool
- `notes://all` resource
- `rag_answer_prompt` prompt template
---
## Repository layout
```text
lib/
agent/
agent-state.ts # LangGraph state schema
mini-agent.ts # LangGraph graph + nodes + routing
embedding.ts # Embedding helpers
knowledge-base.ts # In-memory note dataset
rag-types.ts # Shared RAG types
retrieve-context.ts # Retrieval filtering/threshold flow
rag-answer.ts # Standalone RAG answer generation
semantic-search.ts # Embedding + cosine similarity search
vector-utils.ts # Cosine similarity implementation
mcp/
server.ts # MCP server + tools/resources/prompts
client-test.ts # Script to test server tools/resources/prompts
llm-client-test.ts # Script showing LLM tool selection via MCP
scripts/
agent.ts # Run the LangGraph mini agent
rag.ts # Run standalone RAG answer flow
semantic-search.ts # Run semantic search directly
```
---
## Setup
Requirements:
- Node.js 18+
- `pnpm`
```bash
pnpm install
```
Create `.env.local` at the repository root:
```bash
OPENAI_API_KEY=your_openai_api_key
```
Both completion and embedding calls use OpenAI:
- `gpt-4.1-mini` for planning/answering/drafting
- `text-embedding-3-small` for semantic search
---
## Usage
### Run the mini agent
```bash
pnpm agent "Can you explain why retrieval should happen before generation?"
```
Output includes the full final state and `finalResponse`.
### Run standalone RAG
```bash
pnpm rag "Why do long chats become more expensive?"
```
### Run semantic search
```bash
pnpm semantic-search "backend tool execution"
```
### Start MCP server
```bash
pnpm mcp:server
```
Runs over stdio and exposes tools/resources/prompts defined in `mcp/server.ts`.
### MCP integration checks
```bash
pnpm mcp:test # raw tool/resource/prompt client checks
pnpm mcp:llm # LLM-driven MCP tool-calling demo
```
---
## How the agent flow works
1. **Planner (`planner`)**: maps request intent into an execution plan (`retrieve_notes`, `answer_question`, `draft_message`, `final_response`).
2. **Retrieve (`retrieveNotes`)**: runs similarity retrieval when required.
3. **Draft/Answer (`draftMessage` / `answerQuestion`)**:
- drafts a Slack-style message
- or answers using only retrieved notes, with citations
4. **Retry policy**:
- if first retrieval is empty and this is the first attempt, retry once with a broader query and lower threshold
5. **Finalize (`finalize`)**: returns drafted output, RAG answer, retrieved context, or a bounded fallback.
The state machine is intentionally explicit and inspectable:
```text
START -> planner
├─> retrieveNotes -> answerQuestion -> finalize
├─> retrieveNotes -> draftMessage -> finalize
├─> draftMessage -> finalize
└─> finalize
```
---
## Design principles implemented
- **Controlled output quality**: tool use and response style are constrained by explicit system prompts.
- **No side-effect leakage**: the planner only decides plan, all actions are backend nodes.
- **Source grounding**: answers can cite only known sources (`[note_#]`).
- **Bounded behavior**: retries are limited and unsupported requests take a safe fallback path.
---
## Notes on MCP and agent parity
The LangGraph flow and MCP tools use the same underlying retrieval/RAG primitives:
- semantic search logic lives in `lib/semantic-search.ts`
- answer generation logic lives in `lib/rag-answer.ts`
- note store is shared in `lib/knowledge-base.ts`
This allows you to compare:
- in-repo agent orchestration (`pnpm agent`)
- direct function style RAG (`pnpm rag`)
- tool-based orchestration (`pnpm mcp:llm`)
---
## Future improvements
- Persist notes in a real vector database
- Add chunking and richer document metadata
- Add confidence thresholds + eval snapshots
- Add contract tests for planner routing and retrieval fallback
---
## Quality checklist
- `pnpm typecheck` validates strict TypeScript compilation.
- `pnpm format` formats all files with Prettier.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues