# Context Arithmetic Source: https://getalchemystai.com/docs/advanced/context-arithmetic Understanding the foundational principles on which Alchemyst works ## Introduction **Context arithmetic** is the set of rules by which Alchemyst **selects, combines, filters, and ranks context** at query time. It answers a deceptively simple question: > *Given a large universe of documents, which pieces of information should the model see right now—and why?* Unlike traditional retrieval systems that rely on static queries or hard-coded joins, context arithmetic is **dynamic**. The result set is not fixed; it is *computed* based on scope, intent, constraints, and relevance. Think of it less like a database query, and more like **set algebra over meaning**. *** ### The Mental Model: Context as Sets Every document you ingest belongs to one or more **sets**. These sets are defined implicitly by: * `groupName` * metadata fields * semantic similarity * recency and relevance signals At query time, Alchemyst performs a series of **set operations** to determine what survives into the final context window. Conceptually: ``` Final Context = (Semantic Matches) ∩ (groupName Scope) ∩ (Metadata Filters) − (Deduplicated / Superseded Content) ``` This is context arithmetic. *** ### Primitive Operations At a high level, Alchemyst applies four core operations. #### 1. **Intersection (AND)** Used to **narrow scope**. When you specify multiple `groupName` values, *all* of them must match. ```javascript theme={null} search({ groupName: ["engineering", "backend", "auth"] }) ``` This is equivalent to: ``` engineering ∩ backend ∩ auth ``` Only documents that belong to **all three sets** survive. This is why `groupName` is composable—and why flat or overloaded tags break down quickly. *** #### 2. **Union (OR)** Used implicitly when: * searching semantically * retrieving top-K results * expanding related context For example, a query like: > “How does authentication work?” may retrieve documents from: * design docs * code * past PRs * resolved incidents These are **unioned**, then ranked. ``` (Auth Docs ∪ Auth Code ∪ Auth Tickets ∪ Auth PRs) ``` Union increases recall; intersection increases precision. Good context arithmetic balances both. *** #### 3. **Subtraction (EXCLUSION)** Used to **remove noise and conflicts**. Common examples: * Older versions of the same document * Superseded policies * Duplicate or near-duplicate chunks * Out-of-scope access groups For example: ``` All Auth Docs − Deprecated Docs − Draft Versions − Private/Internal Scope ``` This is why deduplication, versioning, and delete-then-add semantics matter—they directly affect arithmetic correctness. *** #### 4. **Ranking (WEIGHTING)** Once the candidate set is computed, Alchemyst ranks what remains. Ranking signals typically include: * semantic similarity * recency * metadata signals (priority, freshness) * historical usefulness * proximity to the query intent Only the **top-ranked** results are passed to the model. This is where cost, latency, and answer quality converge. *** ### Why This Matters Understanding context arithmetic explains *why* the patterns in this guide exist. * Why hierarchical `groupName` works * Why over-segmentation hurts retrieval * Why metadata bloat slows everything down * Why bulk ingestion and deduplication are not optional * Why document size matters more than raw token count If your context structure aligns with arithmetic rules, retrieval feels “magical.” If it doesn’t, no amount of prompt engineering will save you. *** ### A Simple Example Assume your system contains **50,000 documents**. A user asks: > “How do we handle JWT refresh tokens in API v2?” The effective context computation might look like: ``` ( SemanticMatches("JWT refresh token") ) ∩ groupName(["engineering", "backend", "auth"]) ∩ metadata({ version: "v2" }) − deprecatedDocs − supersededVersions → rank → top 5 ``` The model never sees: * frontend docs * marketing material * outdated auth specs * irrelevant code paths Not because you filtered manually—but because the **arithmetic worked**. *** ### Context Arithmetic vs Prompt Stuffing | Prompt Stuffing | Context Arithmetic | | --------------- | ------------------ | | Static | Dynamic | | Manual | Computed | | Token-heavy | Precision-first | | Fragile | Composable | | Hard to scale | Designed for scale | Prompt stuffing assumes *more tokens = better answers*. Context arithmetic assumes: > *Only the right tokens matter.* *** ### Design Principle > **Structure your context so that correct answers fall out naturally from arithmetic—not from clever prompts.** If you internalize this section, every pattern below will feel less like a rulebook and more like common sense. # Overview Source: https://getalchemystai.com/docs/advanced/overview Unlock the full potential of the Alchemyst Platform At **Alchemyst AI**, we provide AI applications with the context they need to become **smarter**, more **accurate**, and more **useful**. This page explains the proposed scope and outline for the Context Processor, gives a concise top-level view of how the system works, highlights technical insights and their implications, and shows practical examples and use-cases. ## Introduction **Alchemyst** automatically converts your data into retrievable **context** that enhances model reasoning, context and memory. The overall platform works as follows: 1. **Ingest:** Bring data from databases, files, user interactions, and external APIs. 2. **Enrich & Index:** Normalize and enrich data, then index it for fast retrieval by your agents or LLM prompts. 3. **Serve Context:** Provide contextual snippets and memories to models at inference time. 4. **Orchestrate:** Chain tools and services to create deterministic workflows and agent behaviors. 5. **Persist & Evolve:** Store user - or application-level memory that can be updated and audited over time. ## Key Features * **Composable Context**: Manage context data with user and organization-level access control, ensuring that your AI agents can compose and maintain context and intent. * **Granular Access Controls**: Segregate your data by granular access control levels - enabling you to restrict or allow data and control overall data flow for AI agents or applications across your organization. * **Context Traces**: Trace which data points across your entire organizational data is used for your AI agent, at a query level. * **Universal Support**: Connect directly to Claude or OpenAI with MCPs, and get started with context-rich responses in minutes. ## When to use Alchemyst * When context needs to be reusable. * When context is too big to fit inside an LLM's [**effective context window**](https://arxiv.org/abs/2509.21361) * When latencies for GenAI powered applications matter * When tractability and economic feasibility is of paramount importance ## When NOT to use Alchemyst Alchemyst provides a context layer that fares well for most of the use cases one might encounter while using agentic AI. However, there are a few exceptions: * In scenarios where you have a lot of structured data with IDs/numbers and very sparse information explaining what they are. For example, inventory tables with just IDs. Use a traditional database in those scenarios alongside the context layer, and store the document(s) containing the business logic that connects those IDs in the context layer. * Foreign Keys in traditional database tables. One quick hack is to denormalize the data before adding it to the context layer. * Information with low semantic density (although then it becomes more a question of business data strategies). ## Quick tips * You should have a basic understanding of Context Arithmetic. You can find a comprehensive overview [**here**](/docs/advanced/context-arithmetic) * Understand how much data and metadata do you actually need to store for your use case. Metadata bloat is real. * Understand what the best case of `similarity_threshold` and `minimum_similarity_threshold` is for your use case. * Reduce noise in both data input and search query as much as possible. For data, that can mean extra spaces, ad-hoc symbols, emojis, etc. For search, removing noisy tokens is even more important. A good rule of thumb is to implement up context search as tool/function calls. * Bundle bulk requests as much as possible. Adding context is considered as a bulk operation, so sending 10000 documents over 10 bulk requests is advisable over 10000 separate calls. * Alchemyst implements deduplication by default over data by context name (implemented as `metadata.fileName`), so ensure that for changes in the same context source (or doc), they are either treated as an AI conversation, or the older version is first deleted and then the new version is added. Otherwise you'll end up with `409: Conflict` status code. * Compose context as much as possible, over multiple segregations over namespaces. ### How to set up composable context Use `groupName` in the `metadata` tag. The field `metadata.groupName` is an array of strings that works via subset matching. To explain in easier terms, let's say that we have 3 data points `A`, `B`, `C`. `A` has `metadata.groupName` as `["group_main", "group1"]`, `B` has `["group_main", "group2"]` and `C` has `["group_main", "group1"]`. When you search with `groupName`, the filter values you provide must `ALL` be present in a document's `groupName` array for that document to match. **Examples:** * **Search with `["group_main"]`**: * Matches: A ✓, B ✓, C ✓ * Reason: All three documents contain `"group_main"` in their arrays * **Search with `["group_main", "group1"]`**: * Matches: A ✓, C ✓ * Does not match: B ✗ * Reason: A and C both contain both `"group_main"` AND `"group1"`, but B only has `"group_main"` * **Search with `["group1"]`**: * Matches: A ✓, C ✓ * Does not match: B ✗ * Reason: Only A and C contain `"group1"` * **Search with `["group_main", "group3"]`**: * Matches: None * Reason: No document contains both `"group_main"` AND `"group3"` **In summary:** Think of the search filter as defining a "scope" - documents must fall within that scope (contain all the specified tags) to be returned. See [**Understanding Context Arithmetic**](/docs/advanced/context-arithmetic) for the intuition behind this. After that, head over to [**Advanced Usage**](/docs/advanced/advanced-usage-patterns) for patterns to maximize your benefits by leveraging this system. ## Conclusion **Alchemyst** simplifies the process of giving AI models the right **context** so they can reason **more accurately** using your own data. By transforming raw information into structured, retrievable context, it bridges the gap between static knowledge and dynamic intelligence. Whether you're enhancing customer support, powering developer tools, or building compliance systems, we can act as the **Organizational Context Layer** that provides a reliable foundation for **context-aware applications**. # Architecting Context-aware systems Source: https://getalchemystai.com/docs/advanced/realworld-use-cases Use cases that leverage context arithmetic for building robust context aware AI systems. ## Customer Support Knowledge Base ### Objective * Upload product documentation, FAQs, and support tickets * Get instant, accurate answers with source citations * Reduce response time and improve consistency ### Possible Design Outline ```mermaid theme={null} sequenceDiagram participant CS as Customer Support Agent participant AI as AI Assistant participant AC as Alchemyst Context participant DS as Data Sources Note over DS: Product Docs, FAQs, Tickets DS->>AC: Ingest & Index Documents AC->>AC: Enrich with metadata
(product, category, priority) CS->>AI: Customer Query:
"How do I reset my password?" AI->>AC: Search Context
groupName: ["support", "auth"] AC->>AC: Filter & Rank Relevant Docs AC->>AI: Return Top 3 Context Snippets
with Source Citations AI->>AI: Generate Response with Context AI->>CS: Answer + Sources:
1. Password Reset Guide (Doc #123)
2. Authentication FAQ (Doc #456)
3. Similar Ticket Resolution (Ticket #789) CS->>CS: Verify & Send to Customer CS->>AC: Log Interaction
(for future context) Note over AC: Context evolves with
new interactions ``` ### Data Organization Structure ```mermaid theme={null} graph TB subgraph "Knowledge Base Structure" A[All Support Content
groupName: support] A --> B[Product Documentation
groupName: support, product] A --> C[FAQs
groupName: support, faq] A --> D[Support Tickets
groupName: support, tickets] B --> B1[Authentication
groupName: support, product, auth] B --> B2[Features
groupName: support, product, features] B --> B3[Troubleshooting
groupName: support, product, troubleshoot] C --> C1[Billing FAQ
groupName: support, faq, billing] C --> C2[Technical FAQ
groupName: support, faq, technical] D --> D1[Resolved Tickets
groupName: support, tickets, resolved] D --> D2[Open Tickets
groupName: support, tickets, open] end style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#fff4e1 style D fill:#fff4e1 ``` ### Benefits * **Faster Resolution**: Reduce average response time by 60% with instant context retrieval * **Consistency**: All agents have access to the same up-to-date knowledge base * **Traceability**: Track which documents were used to answer each query * **Continuous Improvement**: Learn from past interactions to improve future responses * **Scalability**: Handle increasing support volume without proportional staff increase
## Engineering Code Assistant ### Objective * Index code repositories, design docs, and API specifications * Provide contextual code examples and explanations * Accelerate developer onboarding and productivity ### Possible Design Outline ```mermaid theme={null} sequenceDiagram participant Dev as Developer participant IDE as IDE/CLI Tool participant AI as AI Code Assistant participant AC as Alchemyst Context participant Repo as Code Repository Note over Repo: Codebase, Design Docs,
API Specs, PRs Repo->>AC: Sync & Index Repository AC->>AC: Parse & Enrich:
- Function signatures
- Dependencies
- Documentation
- Code patterns Dev->>IDE: Write code or ask question:
"How do I implement auth middleware?" IDE->>AI: Developer Query + Current Context
(file path, language, imports) AI->>AC: Search Context
groupName: ["codebase", "auth", "middleware"] AC->>AC: Retrieve Relevant:
- Similar implementations
- Design docs
- API specs
- Past PRs AC->>AI: Return Context:
1. auth.middleware.ts (line 45-78)
2. Auth Design Doc (section 3.2)
3. PR #234: "Add JWT middleware"
4. API Security Spec (v2.1) AI->>AI: Generate Response:
- Code example
- Explanation
- Best practices
- Related patterns AI->>IDE: Code Suggestion + Documentation IDE->>Dev: Display inline with citations Dev->>Dev: Accept/Modify suggestion Dev->>AC: Log usage pattern
(improve future suggestions) Note over AC: Context evolves with
codebase changes ``` ### Repository Structure & Indexing ```mermaid theme={null} graph TB subgraph "Code Repository Organization" A[Full Codebase
groupName: codebase, repo_main] A --> B[Source Code
groupName: codebase, src] A --> C[Documentation
groupName: codebase, docs] A --> D[Tests
groupName: codebase, tests] A --> E[Configuration
groupName: codebase, config] B --> B1[Backend Services
groupName: codebase, src, backend] B --> B2[Frontend Components
groupName: codebase, src, frontend] B --> B3[Shared Libraries
groupName: codebase, src, shared] B1 --> B1A[Authentication
groupName: codebase, src, backend, auth] B1 --> B1B[API Endpoints
groupName: codebase, src, backend, api] B1 --> B1C[Database Models
groupName: codebase, src, backend, db] C --> C1[API Specs
groupName: codebase, docs, api] C --> C2[Design Docs
groupName: codebase, docs, design] C --> C3[Architecture
groupName: codebase, docs, architecture] D --> D1[Unit Tests
groupName: codebase, tests, unit] D --> D2[Integration Tests
groupName: codebase, tests, integration] end style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#fff4e1 style D fill:#fff4e1 style E fill:#fff4e1 style B1 fill:#f0e1ff style C1 fill:#d4edda ``` ### Context Enrichment Pipeline ```mermaid theme={null} flowchart LR A[Raw Code File] --> B[Parse AST] B --> C{Extract Metadata} C --> D[Functions & Classes] C --> E[Dependencies] C --> F[Documentation] C --> G[Type Signatures] D --> H[Enrichment Layer] E --> H F --> H G --> H H --> I[Add Semantic Tags] H --> J[Link Related Files] H --> K[Extract Patterns] H --> L[Generate Embeddings] I --> M[Indexed Context] J --> M K --> M L --> M M --> N[Vector Store] M --> O[Metadata Store] N --> P[Context Retrieval Engine] O --> P style A fill:#e1f5ff style H fill:#fff4e1 style M fill:#f0e1ff style P fill:#d4edda ``` ### Developer Interaction Patterns ```mermaid theme={null} stateDiagram-v2 [*] --> Exploration: New feature/codebase [*] --> Implementation: Active coding [*] --> Debugging: Issue encountered [*] --> Review: Code review Exploration --> QueryDocs: "How does X work?" Exploration --> FindExamples: "Show similar patterns" Implementation --> GetSnippets: "Generate boilerplate" Implementation --> CheckAPIs: "Verify API usage" Implementation --> FindPatterns: "Best practice for Y?" Debugging --> SearchIssues: "Similar bugs?" Debugging --> CheckTests: "Related test cases?" Debugging --> TraceFlow: "Call hierarchy?" Review --> ComparePatterns: "Is this idiomatic?" Review --> CheckStandards: "Meets style guide?" QueryDocs --> ContextRetrieved FindExamples --> ContextRetrieved GetSnippets --> ContextRetrieved CheckAPIs --> ContextRetrieved FindPatterns --> ContextRetrieved SearchIssues --> ContextRetrieved CheckTests --> ContextRetrieved TraceFlow --> ContextRetrieved ComparePatterns --> ContextRetrieved CheckStandards --> ContextRetrieved ContextRetrieved --> AIResponse: Process & generate AIResponse --> DeveloperAction: Present solution DeveloperAction --> [*]: Task completed DeveloperAction --> Implementation: Continue coding DeveloperAction --> Debugging: Need more info ``` ### Example: Authentication Middleware Query ```mermaid theme={null} graph TD A["Developer Query: How do I add JWT auth to my Express routes?"] --> B[Context Search] B --> C1[Code: auth.middleware.ts
Relevance: 95%] B --> C2[Doc: Auth Architecture
Relevance: 88%] B --> C3[Code: routes.config.ts
Relevance: 82%] B --> C4[PR: JWT Implementation
Relevance: 78%] B --> C5[Test: auth.test.ts
Relevance: 75%] C1 --> D[AI Synthesis] C2 --> D C3 --> D C4 --> D C5 --> D D --> E[Generated Response] E --> F[Code Example:
app.use'/api', authMiddleware] E --> G[Explanation:
How JWT validation works] E --> H[Best Practices:
Token refresh, error handling] E --> I[Related Resources:
Links to docs & tests] F --> J[Developer Reviews] G --> J H --> J I --> J J --> K{Helpful?} K -->|Yes| L[Implement Solution] K -->|Partial| M[Request Refinement] K -->|No| N[Try Different Approach] L --> O[Log Success Pattern] M --> B N --> B style A fill:#e1f5ff style D fill:#fff4e1 style E fill:#d4edda style O fill:#f0e1ff ``` ### Benefits * **Faster Onboarding**: New developers become productive 3x faster with contextual code guidance * **Consistency**: Ensure team follows established patterns and best practices across the codebase * **Knowledge Preservation**: Capture institutional knowledge from design docs, PRs, and code comments * **Reduced Context Switching**: Get answers without leaving the IDE or reading through multiple files * **Living Documentation**: Code examples stay up-to-date as the repository evolves * **Smart Code Reuse**: Discover existing solutions before writing duplicate code * **Cross-Team Learning**: Share patterns and practices across different teams and projects ### Key Features for Engineering Teams * **IDE Integration**: Works seamlessly with VS Code, IntelliJ, and terminal workflows * **Language Agnostic**: Supports Python, JavaScript/TypeScript, Java, Go, Rust, and more * **Real-time Sync**: Repository changes automatically update the context index * **Privacy Controls**: Keep sensitive code within team boundaries using `groupName` filters * **Audit Trails**: Track which code snippets and docs are referenced for compliance * **Custom Queries**: Define team-specific search patterns and code templates
## Content Summarization Agent ### Objective * Process long-form content across multiple documents * Generate executive summaries with source attributions * Maintain consistent messaging across teams ### Possible Design Outline ```mermaid theme={null} sequenceDiagram participant User as Content Manager participant Agent as Summarization Agent participant AC as Alchemyst Context participant Sources as Content Sources Note over Sources: Reports, Articles,
Meeting Notes, Emails Sources->>AC: Ingest Documents AC->>AC: Extract & Structure:
- Key points
- Entities
- Themes
- Citations User->>Agent: Request Summary:
"Summarize Q4 marketing
performance across all channels" Agent->>AC: Query Context
groupName: ["marketing", "q4", "performance"] AC->>AC: Retrieve Relevant:
- Campaign reports (5 docs)
- Analytics dashboards (3 docs)
- Meeting notes (8 docs)
- Email threads (12 docs) AC->>Agent: Return Ranked Documents
with metadata & excerpts Agent->>Agent: Process Content:
1. Identify key themes
2. Extract metrics
3. Detect trends
4. Consolidate insights Agent->>Agent: Generate Summary:
- Executive overview
- Key findings (5-7 points)
- Supporting data
- Source attributions Agent->>User: Deliver Summary with:
- Main insights
- Visual highlights
- Full source list
- Confidence scores User->>User: Review & Refine User->>Agent: "Add details about email campaign ROI" Agent->>AC: Targeted search:
groupName: ["marketing", "q4", "email", "roi"] AC->>Agent: Return specific sections Agent->>User: Updated summary with
expanded email ROI section User->>AC: Save Final Summary
as reference document Note over AC: Summary becomes
searchable context ``` ### Processing Pipeline ```mermaid theme={null} flowchart TD A[Start: Summarization Request] --> B[Parse Request Intent] B --> C{Scope Identification} C -->|Single Topic| D[Focused Search] C -->|Multiple Topics| E[Multi-faceted Search] C -->|Time-based| F[Temporal Search] C -->|Comparative| G[Cross-sectional Search] D --> H[Retrieve Documents] E --> H F --> H G --> H H --> I{Document Count?} I -->|1-5 docs| J[Detailed Extraction] I -->|6-20 docs| K[Balanced Extraction] I -->|21+ docs| L[High-level Extraction] J --> M[Content Analysis] K --> M L --> M M --> N[Identify Themes] M --> O[Extract Key Points] M --> P[Detect Patterns] M --> Q[Flag Contradictions] N --> R[Synthesis Engine] O --> R P --> R Q --> R R --> S{Summary Type?} S -->|Executive| T[High-level: 3-5 paragraphs] S -->|Detailed| U[In-depth: 2-3 pages] S -->|Bullet Points| V[Structured: Key takeaways] S -->|Narrative| W[Story-form: Chronological] T --> X[Add Source Citations] U --> X V --> X W --> X X --> Y[Generate Confidence Scores] Y --> Z[Quality Check] Z --> AA{Meets Standards?} AA -->|Yes| AB[Deliver Summary] AA -->|No| AC[Flag for Review] AB --> AD[Log & Learn] AC --> AD AD --> AE[End] style A fill:#d4edda style H fill:#e1f5ff style R fill:#fff4e1 style X fill:#f0e1ff style AB fill:#d4edda style AE fill:#d4edda ``` ### Content Organization Structure ```mermaid theme={null} graph TB subgraph "Content Repository" A[All Content
groupName: content] A --> B[By Department
groupName: content, dept_X] A --> C[By Content Type
groupName: content, type_X] A --> D[By Time Period
groupName: content, period_X] A --> E[By Project
groupName: content, project_X] B --> B1[Marketing
groupName: content, marketing] B --> B2[Sales
groupName: content, sales] B --> B3[Product
groupName: content, product] B1 --> B1A[Q4 2024
groupName: content, marketing, q4_2024] B1 --> B1B[Campaigns
groupName: content, marketing, campaigns] B1 --> B1C[Analytics
groupName: content, marketing, analytics] C --> C1[Reports
groupName: content, reports] C --> C2[Meeting Notes
groupName: content, meetings] C --> C3[Emails
groupName: content, emails] C --> C4[Presentations
groupName: content, presentations] D --> D1[Q3 2024
groupName: content, q3_2024] D --> D2[Q4 2024
groupName: content, q4_2024] D --> D3[Annual
groupName: content, annual_2024] E --> E1[Product Launch
groupName: content, product_launch_alpha] E --> E2[Rebranding
groupName: content, rebrand_2024] end style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#fff4e1 style D fill:#fff4e1 style E fill:#fff4e1 style B1 fill:#f0e1ff style C1 fill:#d4edda ``` ### Multi-Document Synthesis Strategy ```mermaid theme={null} flowchart LR A[Document Set
28 documents] --> B{Clustering} B --> C1[Theme 1: Performance
12 documents] B --> C2[Theme 2: Budget
8 documents] B --> C3[Theme 3: Strategy
6 documents] B --> C4[Theme 4: Challenges
9 documents] C1 --> D1[Extract Key Metrics] C2 --> D2[Consolidate Financials] C3 --> D3[Identify Initiatives] C4 --> D4[List Issues & Solutions] D1 --> E[Synthesis Layer] D2 --> E D3 --> E D4 --> E E --> F[Cross-reference] E --> G[Validate Consistency] E --> H[Resolve Conflicts] E --> I[Rank by Importance] F --> J[Unified Summary] G --> J H --> J I --> J J --> K[Executive Overview] J --> L[Key Findings] J --> M[Supporting Details] J --> N[Source Map] style A fill:#e1f5ff style E fill:#fff4e1 style J fill:#f0e1ff style K fill:#d4edda ``` ### Summary Output Structure ```mermaid theme={null} graph TD A[Generated Summary] --> B[Executive Overview
2-3 sentences] A --> C[Key Findings Section] A --> D[Supporting Evidence] A --> E[Metadata & Attribution] C --> C1[Finding 1
Source: Doc A, Para 3] C --> C2[Finding 2
Source: Doc B, Slide 7] C --> C3[Finding 3
Source: Doc C, Meeting notes] C --> C4[Finding 4
Source: Docs D, E, F] D --> D1[Charts & Metrics] D --> D2[Quote Excerpts] D --> D3[Timeline of Events] D --> D4[Comparative Analysis] E --> E1[Source Documents: 28] E --> E2[Confidence Score: 87%] E --> E3[Date Range: Oct-Dec 2024] E --> E4[Generated: Dec 29, 2025] E --> E5[Version: 1.2] style A fill:#e1f5ff style B fill:#d4edda style C fill:#fff4e1 style D fill:#f0e1ff style E fill:#ffe1e1 ``` ### Agent State Machine ```mermaid theme={null} stateDiagram-v2 [*] --> Idle Idle --> ReceiveRequest: User submits query ReceiveRequest --> AnalyzeIntent: Parse request AnalyzeIntent --> QueryContext: Identify search criteria QueryContext --> RetrieveDocuments: Execute search RetrieveDocuments --> ValidateResults: Check document count ValidateResults --> ProcessContent: Sufficient results ValidateResults --> RefineQuery: Insufficient results RefineQuery --> QueryContext: Broaden search ProcessContent --> ExtractContent: Parse documents ExtractContent --> IdentifyThemes: Analyze patterns IdentifyThemes --> ConsolidateInsights: Group related info ConsolidateInsights --> GenerateSummary: Create output GenerateSummary --> QualityCheck: Validate summary QualityCheck --> DeliverSummary: Passes checks QualityCheck --> FlagIssues: Fails checks FlagIssues --> HumanReview: Request manual review HumanReview --> GenerateSummary: Revise DeliverSummary --> AwaitFeedback: Present to user AwaitFeedback --> Idle: Task complete AwaitFeedback --> RefineRequest: User requests changes RefineRequest --> ProcessContent: Adjust focus ``` ### Example: Quarterly Performance Summary ```mermaid theme={null} graph TD A["User Request:
'Summarize Q4 2024
marketing performance'"] --> B[Context Search] B --> C1[Campaign Reports
5 documents
Relevance: 98%] B --> C2[Analytics Dashboards
3 documents
Relevance: 95%] B --> C3[Meeting Notes
8 documents
Relevance: 88%] B --> C4[Email Threads
12 documents
Relevance: 75%] B --> C5[Budget Reports
2 documents
Relevance: 82%] C1 --> D[Theme Analysis] C2 --> D C3 --> D C4 --> D C5 --> D D --> E1[Theme: ROI Performance
Sources: C1, C2, C5] D --> E2[Theme: Channel Mix
Sources: C1, C2] D --> E3[Theme: Team Feedback
Sources: C3, C4] D --> E4[Theme: Budget Variance
Sources: C5, C1] E1 --> F[Synthesis Engine] E2 --> F E3 --> F E4 --> F F --> G[Generated Summary] G --> H1["Executive Overview:
'Q4 exceeded targets by 23%
with strong digital performance'"] G --> H2["Key Finding 1:
Email campaigns ROI: 340%
Source: Campaign Report Q4"] G --> H3["Key Finding 2:
Social media spend up 15%
Source: Budget Report, Analytics"] G --> H4["Key Finding 3:
Team recommends doubling
video content budget
Source: 3 meeting notes"] H1 --> I[Deliver to User] H2 --> I H3 --> I H4 --> I I --> J[User Actions] J --> K[Share with executives] J --> L[Export to presentation] J --> M[Request detailed breakdown] J --> N[Save as template] style A fill:#e1f5ff style D fill:#fff4e1 style F fill:#f0e1ff style G fill:#d4edda ``` ### Consistency & Version Control ```mermaid theme={null} flowchart TD A[Summary Version 1.0] --> B{Detect Content Update} B -->|New Document Added| C[Incremental Analysis] B -->|Existing Doc Modified| D[Delta Processing] B -->|No Changes| E[Maintain Current] C --> F[Identify Impact] D --> F F --> G{Significance?} G -->|Major| H[Regenerate Summary
Version 1.1] G -->|Minor| I[Add Footnote
Version 1.0.1] G -->|Negligible| E H --> J[Track Changes] I --> J E --> J J --> K[Version History] K --> L[Version 1.0: Dec 1
Source docs: 20] K --> M[Version 1.0.1: Dec 15
Added: Budget update] K --> N[Version 1.1: Dec 29
Major revision: New data] L --> O[Audit Trail] M --> O N --> O O --> P[Maintain Consistency
Across Teams] style A fill:#e1f5ff style F fill:#fff4e1 style H fill:#f0e1ff style K fill:#d4edda ``` ### Benefits * **Time Savings**: Reduce summary creation time from hours to minutes * **Comprehensive Coverage**: Never miss key information across multiple documents * **Source Transparency**: Full attribution ensures credibility and traceability * **Consistency**: Maintain unified messaging across departments and stakeholders * **Version Control**: Track how summaries evolve as new information arrives * **Scalability**: Process hundreds of documents simultaneously * **Multi-format Output**: Generate executive briefs, detailed reports, or bullet points * **Living Summaries**: Automatically update as source documents change ### Key Features for Content Teams * **Smart Deduplication**: Identify and consolidate redundant information * **Conflict Detection**: Flag contradictory statements across documents * **Confidence Scoring**: Indicate reliability based on source quality and consensus * **Custom Templates**: Define organization-specific summary formats * **Multi-language Support**: Summarize content across different languages * **Sentiment Analysis**: Capture tone and emotional context * **Trend Identification**: Highlight patterns across time periods * **Collaborative Refinement**: Allow teams to iterate on summaries together ### Use Case Scenarios * **Executive Briefings**: Distill 50+ documents into 2-page executive summaries * **Meeting Preparation**: Synthesize pre-read materials for strategic sessions * **Project Retrospectives**: Consolidate learnings from project documentation * **Market Research**: Aggregate insights from multiple research reports * **Competitive Analysis**: Summarize intelligence across competitor activities * **Quarterly Reviews**: Compile performance data across all departments * **Crisis Communication**: Rapidly synthesize information during incidents
# Errors & Platform Limits Source: https://getalchemystai.com/docs/advanced/troubleshooting Understanding common issues you might face, while building with Alchemyst ## Quick Diagnosis * Can't upload? [see Upload Errors](#common-errors-add) * Search not working? [go to Search Errors](#common-errors-search) * Slow performance? [look at Performance Issues](#performance-issues) * Wrong results? [Check Retrieval Quality](#retrieval-quality-issues) ## API Errors ### Common errors (Add) | Status Code | Error Type | Common Cause | Recommended Fix | | :---------- | :---------------- | :-------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | | **400** | `BadRequest` | Invalid JSON or missing required fields (e.g., `source`). | Validate your payload against the [schema](/docs/api-reference/endpoint/api/v1/context/add/post). Ensure `documents` array is not empty. | | **401** | `Unauthorized` | Invalid or missing `ALCHEMYST_AI_API_KEY`. | Check your `.env` file. Ensure you aren't using a Test key in Prod. | | **403** | `Forbidden` | Accessing a `scope` (e.g., `user_123`) you don't have permission for. | Verify the `api_key` or `user_id` matches the authenticated session. Make sure the key is still valid. | | **409** | `Conflict` | Document with the same `fileName` already exists. | Follow [Pattern 2: Document Updates](/docs/advanced/usage-patterns#pattern-2%3A-handling-document-updates) to update or replace existing documents safely. | | **413** | `PayloadTooLarge` | Document exceeds the 50MB limit or batch size > 100. | Split your `documents` array into chunks of 50 and retry. | | **429** | `RateLimit` | Exceeded 1000 requests/minute. | Implement exponential backoff (default in SDK). Contact support for higher limits. | | **422** | `Unprocessable` | The file type provided in `metadata` matches `source` but content is unparseable. | Ensure `fileType` matches the actual binary content (e.g., don’t send PDF bytes as `text/plain`). | ### Common errors (Search) | Status Code | Error Type | Common Cause | Recommended Fix | | :---------- | :-------------- | :-------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | | **400** | `BadRequest` | Missing or malformed search parameters. | Ensure `query` is provided and properly formatted.Validate your payload against the [schema](/docs/api-reference/endpoint/api/v1/context/search) | | **401** | `Unauthorized` | Invalid or missing `ALCHEMYST_AI_API_KEY`. | Confirm the request includes a valid API key. | | **403** | `Forbidden` | Searching a `scope` you don't have access to. | Make sure the key is still valid. Ensure the search `scope` is accessible to the current user or org. | | **429** | `RateLimit` | Too many search requests. | Add throttling or cache repeated searches. | | **422** | `Unprocessable` | Documents were not indexed correctly. | Verify documents were successfully ingested before searching. | ## Application-Level Issues ### Performance issues #### Slow Ingestion **Diagnosis:** ```javascript theme={null} // Sequential adds: ~30 seconds for 1000 docs for (let i = 0; i < 1000; i++) { await alchemyst.add(documents[i]); } // Async add: ~3 seconds for 1000 docs (10x faster!) // documents is an array of content const documents = []; documents.push({ content: "files content", metadata: { // optional file_name: "file_name", file_type: "pdf/txt/json", group_name: ["group1", "group2"], }, }); await alchemyst.add(documents); ``` **Common Causes:** * Document size > 50MB (max file size - 50MB) * Large number of documents uploaded sequentially * Token limit reached **Solutions :** 1. Make sure the doc size is less then 50MB 2. Upload documents via bulkAdd (faster) 3. Check if you have sufficent tokens 4. For bulk operations read [here](/docs/advanced/usage-patterns#pattern-4%3A-bulk-operations-at-scale) *** #### Slow Searches (> 1 second) **Quick Checks:** ```javascript theme={null} // Measure your query time const start = Date.now(); const result = await alchemyst.v1.context.search({ groupName: ["a", "b", "c", "d", "e", "f", "g"] // 7 filters! }); console.log(`Search took ${Date.now() - start}ms`); ``` **Common Causes:** * 7+ groupName tags (exponential overhead) * No minimum\_similarity\_threshold set * 10K+ documents in scope **Solutions:** 1. Reduce to 3-5 groupName tags max 2. Set minimum\_similarity\_threshold: 0.5 3. Use namespaces to shard data *** ### Retrieval Quality Issues #### No Results Returned **Quick Checks:** ```javascript theme={null} // 1. Verify documents exist const docs = await alchemyst.v1.context.view(); console.log(`Total docs: ${docs.length}`); // 2. Try broader search const result = await alchemyst.v1.context.search({ query: "your query", similarity_threshold: 0.5, // Lower threshold groupName: ["broad_tag"] // Fewer filters }); ``` **Common Causes:** * High minimum\_similarity\_threshold set * groupnames don't intersect * Query is not relevant or very specific **Solutions :** 1. Verify documents exist : [platform](https://platform.getalchemystai.com/context) 2. Reduce similarity\_threshold from 0.6-0.7 to 0.5-0.6 3. Remove overly specific groupNames 4. Try with a general query, make sure it's not too specific *** ### Common Scenarios #### Scenario: Queries Return Too Many Fragments * **Problem:** Search returns 50+ small chunks * **Cause:** Over-segmentation (see [Anti-Pattern 1](/docs/advanced/usage-patterns#anti-pattern-1%3A-over-segmentation)) * **Solution:** Combine related content into cohesive documents #### Scenario : Metadata Bloat Symptoms * **Problem:** Storing too much or redundant information in metadata * **Cause:** Metadata bloating (see [Anti-Pattern 2](/docs/advanced/usage-patterns#anti-pattern-2%3A-metadata-bloat)) * **Solution:** Limit metadata to only what you query/filter by, pass all the other things in the content itself. ## Debugging Tools * Context traces [API](/docs/api-reference/endpoint/api/v1/context/traces/get) or [Platform](https://platform.getalchemystai.com/traces) * Verbose SDK [logging](/docs/integrations/sdk/python-sdk#logging) * Health check endpoints ### Platform Limits | Feature | Limit / Specification | | :----------------------- | :------------------------------------------------------------ | | **Max File Size** | 50 MB per document | | **Max Batch Size** | 100 documents per `add()` request | | **Supported File Types** | `.pdf`, `.txt`, `.docx`, `.md`, `.json`, `.csv` | | **Token Limit** | 8,192 tokens per document chunk | | **Metadata Fields** | Max 20 keys per document; Values must be `string` or `number` | | **Indexing Speed** | \~120 records/sec (Text), \~5 sec/page (OCR PDF) | ## Still Stuck? * Check our [Discord](https://docs.getalchemystai.com/join-discord?utm_source=docs\&utm_medium=referral\&utm_campaign=discord_join) for community help # Usage Patterns Primer Source: https://getalchemystai.com/docs/advanced/usage-patterns Advanced usage patterns to let you take full advantage of context arithmetic ## Prerequisites * Understanding of [**Context Arithmetic**](/docs/advanced/context-arithmetic) * Data to contextualize * Familiarity with the Alchemyst SDKs and APIs. ## Introduction Context Arithmetic is a very simple but powerful tool. Leveraging that system, we can derive context spaces, merge them, segregate them, or even apply access controls on top of them - all while maintaining the tractability and other benefits that Alchemyst offers. In an agentic environment where non-determinism exists not as a byproduct, but as a foundational principle, it offers verifiability across large systems. This gives enterprise teams control over their data usage and governance patterns and scopes. In this section we explore patterns that you can leverage to build robust context-aware AI systems using context arithmetic. ## Pattern 1: Hierarchical groupName Design ### The Problem Flat groupName structures become unmanageable at scale. You end up with searches that are either too broad (returning 1000+ documents) or too narrow (returning nothing). ### The Solution: Think in Layers Design your groupName hierarchy like a file system - broad categories at the top, specific tags as you go deeper. ```javascript theme={null} // ❌ Flat structure - Hard to query effectively { "groupName": ["marketing_q4_2024_campaign_email_newsletter_product_launch"] } // ✅ Hierarchical structure - Composable and flexible { "groupName": ["marketing", "q4_2024", "campaign", "email"] } ``` ### Three-Layer Strategy **Layer 1: Organization/Domain** (Required for all documents) * `"engineering"`, `"marketing"`, `"sales"`, `"support"` * Purpose: Top-level access control **Layer 2: Category/Time** (Recommended) * `"q4_2024"`, `"product_alpha"`, `"codebase"`, `"customer_tickets"` * Purpose: Logical grouping and temporal filtering **Layer 3: Specifics** (Optional, use sparingly) * `"auth"`, `"api"`, `"campaign"`, `"billing"` * Purpose: Fine-grained filtering #### Example: Engineering Team ```javascript theme={null} // Base document - accessible to all engineering { "groupName": ["engineering"], "content": "Company-wide coding standards..." } // Backend auth code - specific team access { "groupName": ["engineering", "backend", "auth"], "content": "JWT middleware implementation..." } // Frontend component - specific project { "groupName": ["engineering", "frontend", "project_redesign"], "content": "Button component with new design system..." } ``` ### Query Patterns ```javascript theme={null} // Broad: All engineering docs (might return 10,000+ docs) search({ groupName: ["engineering"] }) // Focused: Backend authentication (returns ~50 docs) search({ groupName: ["engineering", "backend", "auth"] }) // Specific: Auth docs in current project (returns ~10 docs) search({ groupName: ["engineering", "backend", "auth"], metadata: { project: "api_v2" } }) ``` ### 💡 Pro Tip: The 3-5-10 Rule * Maximum 3 groupName layers for 90% of queries * Maximum 5 tags in any single groupName array * Maximum 10 unique tag combinations per user query pattern ## ⚠️ Common Mistake: Over-nesting ```javascript theme={null} // ❌ Too deep - queries become fragile ["engineering", "backend", "api", "v2", "endpoints", "user", "auth", "login"] // ✅ Better - use metadata for the specifics groupName: ["engineering", "backend", "api"] metadata: { version: "v2", category: "auth", endpoint: "login" } ``` *** ## Pattern 2: Handling Document Updates ### The Deduplication Gotcha Alchemyst uses `metadata.fileName` as the deduplication key. This means: 1. Same fileName = Alchemyst treats it as an update attempt 2. Update attempts without delete = **409 Conflict error** 3. This is **by design** to prevent accidental duplicates ### Three Update Strategies #### Strategy A: Delete-Then-Add (Recommended for true updates) ```javascript theme={null} // Document has changed - replace it entirely async function updateDocument(fileName, newContent) { // Step 1: Find and delete old version const existing = await alchemyst.search({ metadata: { fileName: fileName } }); if (existing.results.length > 0) { await alchemyst.delete(existing.results[0].id); } // Step 2: Add new version await alchemyst.add({ content: newContent, metadata: { fileName: fileName } }); } // Use case: Documentation that gets edited // "user-guide.pdf" updated from v1 to v2 ``` #### Strategy B: Versioned FileNames (Keep history) ```javascript theme={null} // Track document evolution over time await alchemyst.add({ content: quarterlyReport, metadata: { fileName: "q4-report-v1.pdf", version: "1.0", status: "draft" } }); await alchemyst.add({ content: quarterlyReportFinal, metadata: { fileName: "q4-report-v2.pdf", // Different fileName! version: "2.0", status: "final", supersedes: "q4-report-v1.pdf" } }); // Use case: Legal documents, contracts, specs where history matters ``` #### Strategy C: Conversational Updates (Incremental context) ```javascript theme={null} // For chat-like interactions where context accumulates await alchemyst.addToConversation({ conversationId: "support-ticket-1234", content: "Customer reported login issue...", metadata: { timestamp: "2024-12-29T10:00:00Z", speaker: "customer" } }); await alchemyst.addToConversation({ conversationId: "support-ticket-1234", content: "Resolved by resetting password...", metadata: { timestamp: "2024-12-29T10:15:00Z", speaker: "agent" } }); // Use case: Support tickets, chat logs, ongoing projects ``` ### Decision Tree: Which Strategy? ``` Is the new content completely replacing the old? ├─ YES → Use Strategy A (Delete-Then-Add) │ ├─ NO → Does history matter? ├─ YES → Use Strategy B (Versioned FileNames) │ └─ NO → Is this part of a conversation/thread? ├─ YES → Use Strategy C (Conversational) └─ NO → Use Strategy B with cleanup job ``` ### 🔧 Advanced: Batch Updates ```javascript theme={null} // ❌ Don't do this - 100 sequential operations for (const doc of documents) { await alchemyst.delete(doc.id); await alchemyst.add(doc.updated); } // Time: ~30-60 seconds // ✅ Do this - bulk operations const deleteIds = documents.map(d => d.id); await alchemyst.bulkDelete(deleteIds); await alchemyst.bulkAdd( documents.map(d => d.updated) ); // Time: ~3-5 seconds ``` #### ⚠️ Warning: The Race Condition ```javascript theme={null} // ❌ Dangerous - race condition in concurrent environments async function updateDoc(fileName, content) { await alchemyst.delete({ fileName }); // ⚠️ Might not be done yet await alchemyst.add({ fileName, content }); // ⚠️ Might conflict } // ✅ Safe - wait for confirmation async function updateDocSafe(fileName, content) { const deleteResponse = await alchemyst.delete({ fileName }); if (!deleteResponse.success) { throw new Error("Delete failed"); } // Small delay to ensure propagation (100-200ms) await new Promise(resolve => setTimeout(resolve, 150)); return await alchemyst.add({ fileName, content }); } ``` *** ## Pattern 3: Composable Context Strategies ### The Dilemma Should you store one big document or many small ones? This affects retrieval quality, performance, and maintenance. ### Rule of Thumb: Split by Access Pattern #### When to COMBINE contexts: **Scenario 1: Tightly Coupled Information** ```javascript theme={null} // ✅ Good - store together { groupName: ["product", "api_spec"], content: ` Authentication Endpoint POST /api/auth/login Request Body: - email: string (required) - password: string (required) Response: - token: JWT string - expiresIn: number (seconds) Error Codes: - 401: Invalid credentials - 429: Rate limited ` } // ❌ Bad - unnecessarily fragmented // Document 1: "POST /api/auth/login" // Document 2: "Request body fields" // Document 3: "Response format" // Document 4: "Error codes" // Problem: User query "how to login" needs all 4 docs ``` **Scenario 2: Always Retrieved Together** ```javascript theme={null} // If users always need A, B, and C together, combine them // Example: Product onboarding guide (overview + setup + first steps) ``` ### When to SPLIT contexts: **Scenario 1: Different Access Patterns** ```javascript theme={null} // ✅ Good - separate by access control // Public documentation { groupName: ["docs", "public"], content: "How to use our API..." } // Internal implementation notes { groupName: ["docs", "internal"], content: "Rate limiting implementation details..." } ``` **Scenario 2: Different Update Frequencies** ```javascript theme={null} // ✅ Good - separate by volatility // Static content (rarely changes) { fileName: "company-history.md", content: "Founded in 2020..." } // Dynamic content (changes daily) { fileName: "daily-metrics-2024-12-29.json", content: "Today's sales: $45,231..." } ``` **Scenario 3: Size Optimization** ```javascript theme={null} // One 50,000-word document: // ❌ Slow to retrieve // ❌ Wastes tokens on irrelevant sections // ❌ Hard to rank relevance // Split into 10 logical sections: // ✅ Fast retrieval // ✅ Only relevant sections retrieved // ✅ Better semantic ranking ``` ### The Goldilocks Size: 500-2000 words per document ```javascript theme={null} // ❌ Too small (100 words) // Problem: Loses context, requires many docs for complete answer { content: "JWT tokens expire after 24 hours" } // ❌ Too large (10,000 words) // Problem: Retrieves too much irrelevant content { content: "Entire authentication system documentation..." } // ✅ Just right (800 words) // Problem: Single cohesive topic with enough context { content: ` JWT Token Management Overview: Our JWT implementation uses... Token Lifecycle: 1. Generation: POST /auth/login 2. Validation: Automatic on each request 3. Refresh: POST /auth/refresh 4. Expiration: 24 hours default [Full details with examples...] ` } ``` ### 💡 Pro Tip: The Chapter Pattern Structure large content like a book: ```javascript theme={null} // Parent metadata for navigation const bookMetadata = { book: "employee-handbook", totalChapters: 12 }; // Chapter 1: Welcome await alchemyst.add({ groupName: ["hr", "handbook"], metadata: { ...bookMetadata, chapter: 1, title: "Welcome" }, content: "Chapter 1: Welcome to the company..." }); // Chapter 2: Benefits await alchemyst.add({ groupName: ["hr", "handbook"], metadata: { ...bookMetadata, chapter: 2, title: "Benefits" }, content: "Chapter 2: Health insurance options..." }); // Query: Get specific chapter or search across all // "Tell me about health insurance" // → Retrieves Chapter 2 specifically ``` ### Advanced: Cross-References ```javascript theme={null} // Document with references to related content { groupName: ["engineering", "backend", "auth"], metadata: { relatedDocs: ["api-security-guide", "user-model-schema"], prerequisites: ["basic-auth-concepts"] }, content: "Advanced authentication patterns..." } // Your application can fetch related docs for deeper context ``` *** ## Pattern 4: Bulk Operations at Scale ### The Performance Cliff ```javascript theme={null} // Sequential adds: ~30 seconds for 1000 docs for (let i = 0; i < 1000; i++) { await alchemyst.add(documents[i]); } // Async add: ~3 seconds for 1000 docs (10x faster!) // documents is an array of content const documents = []; documents.push({ content: "files content", metadata: { // optional file_name: "file_name", file_type: "pdf/txt/json", group_name: ["group1", "group2"], }, }); await alchemyst.add(documents); ``` ### Optimal Batch Sizes Based on production usage patterns: | Documents | Batches | Time | Recommendation | | --------- | ----------- | ------ | ----------------------------- | | 100 | 1 batch | \~0.5s | ✅ Single call | | 1,000 | 1 batch | \~3s | ✅ Single call | | 10,000 | 10 batches | \~35s | ✅ Optimal | | 10,000 | 100 batches | \~90s | ⚠️ Too fragmented | | 100,000 | 100 batches | \~6min | ✅ Good with progress tracking | ### The 1000-Document Sweet Spot ```javascript theme={null} // Process 10,000 documents efficiently async function bulkIngest(documents) { const BATCH_SIZE = 1000; const batches = []; // Split into batches of 1000 for (let i = 0; i < documents.length; i += BATCH_SIZE) { batches.push(documents.slice(i, i + BATCH_SIZE)); } // Process batches with progress tracking const results = []; for (let i = 0; i < batches.length; i++) { console.log(`Processing batch ${i + 1}/${batches.length}`); const result = await alchemyst.bulkAdd(batches[i]); results.push(result); // Optional: Small delay between batches to avoid rate limits if (i < batches.length - 1) { await new Promise(resolve => setTimeout(resolve, 100)); } } return results; } ``` ### 🚀 Advanced: Parallel Processing with Limits ```javascript theme={null} // Process multiple batches in parallel (but not too many!) async function parallelBulkIngest(documents) { const BATCH_SIZE = 1000; const MAX_CONCURRENT = 3; // Don't overwhelm the API const batches = []; for (let i = 0; i < documents.length; i += BATCH_SIZE) { batches.push(documents.slice(i, i + BATCH_SIZE)); } // Process 3 batches at a time const results = []; for (let i = 0; i < batches.length; i += MAX_CONCURRENT) { const chunk = batches.slice(i, i + MAX_CONCURRENT); const chunkResults = await Promise.all( chunk.map(batch => alchemyst.bulkAdd(batch)) ); results.push(...chunkResults); console.log(`Completed ${Math.min(i + MAX_CONCURRENT, batches.length)}/${batches.length} batches`); } return results; } ``` ### Error Handling in Bulk Operations ```javascript theme={null} async function robustBulkIngest(documents) { const BATCH_SIZE = 1000; const MAX_RETRIES = 3; const batches = chunkArray(documents, BATCH_SIZE); const results = []; const failures = []; for (let i = 0; i < batches.length; i++) { let attempt = 0; let success = false; while (attempt < MAX_RETRIES && !success) { try { const result = await alchemyst.bulkAdd(batches[i]); results.push(result); success = true; } catch (error) { attempt++; console.warn(`Batch ${i} failed (attempt ${attempt}/${MAX_RETRIES}):`, error.message); if (attempt < MAX_RETRIES) { // Exponential backoff: 1s, 2s, 4s await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt - 1)) ); } else { // Final failure - log and continue failures.push({ batchIndex: i, error: error.message }); } } } } if (failures.length > 0) { console.error(`${failures.length} batches failed after retries:`, failures); } return { results, failures }; } ``` ### 💡 Pro Tip: Progress Tracking for Large Ingests ```javascript theme={null} // For 100K+ documents, give users feedback async function ingestWithProgress(documents, onProgress) { const BATCH_SIZE = 1000; const batches = chunkArray(documents, BATCH_SIZE); let completed = 0; for (const batch of batches) { await alchemyst.bulkAdd(batch); completed += batch.length; onProgress({ completed, total: documents.length, percentage: (completed / documents.length * 100).toFixed(1) }); } } // Usage in UI await ingestWithProgress(allDocs, (progress) => { console.log(`Progress: ${progress.percentage}% (${progress.completed}/${progress.total})`); // Update progress bar, etc. }); ``` *** ## Anti-Pattern 1: Over-segmentation ### The Problem Creating too many small, fragmented contexts that should be combined. ### Real Example: Support Ticket System ```javascript theme={null} // ❌ Anti-pattern: One document per field // Ticket #1234 split into 6 documents: { groupName: ["support", "ticket_1234", "subject"], content: "Cannot login to dashboard" } { groupName: ["support", "ticket_1234", "description"], content: "User reports error message..." } { groupName: ["support", "ticket_1234", "priority"], content: "High" } { groupName: ["support", "ticket_1234", "agent"], content: "John Doe" } { groupName: ["support", "ticket_1234", "resolution"], content: "Password reset required" } { groupName: ["support", "ticket_1234", "timestamp"], content: "2024-12-29T10:00:00Z" } // Problems: // 1. Query "login issues" retrieves 6 fragments // 2. LLM needs to reassemble the ticket // 3. Costs 6x the storage and retrieval // 4. Loses contextual relationships ``` ```javascript theme={null} // ✅ Correct: One cohesive document { groupName: ["support", "tickets", "resolved"], metadata: { ticketId: "1234", priority: "high", agent: "John Doe", resolvedAt: "2024-12-29T10:15:00Z" }, content: ` Ticket #1234: Cannot login to dashboard Description: User reports error message "Invalid credentials" when attempting to log in with correct password. Account verified as active. Resolution: Issue caused by expired password (90-day policy). Password reset link sent to user. User confirmed successful login after reset. Root Cause: Password expiration notification system failed to send warning emails. ` } // Benefits: // 1. Single retrieval gets complete context // 2. LLM can understand full story // 3. 6x cost reduction // 4. Preserves semantic relationships ``` ### The Acid Test: Query Simulation Ask yourself: "What will my users search for?" ```javascript theme={null} // User query: "How do we handle login issues?" // With over-segmentation: // → Retrieves 47 fragments across 8 tickets // → LLM confused by incomplete pieces // → Answer: Generic, not helpful // With proper documents: // → Retrieves 3-4 complete ticket resolutions // → LLM sees full context and patterns // → Answer: "Based on tickets #1234, #1456, we typically..." ``` ### 💡 Rule: The Paragraph Test If your document content is less than a paragraph (\< 100 words), you're probably over-segmenting. **Exception:** Structured data with high retrieval value ```javascript theme={null} // This is OK even though it's short { groupName: ["company", "contacts"], metadata: { department: "engineering", role: "cto" }, content: "Jane Smith - CTO - jane@company.com - ext. 1234" } ``` *** ## Anti-Pattern 2: Metadata Bloat ### The Problem Storing too much or redundant information in metadata, slowing down queries and wasting storage. ### Real Example: Product Catalog ```javascript theme={null} // ❌ Metadata bloat { groupName: ["products", "electronics"], metadata: { productId: "PROD-12345", productName: "Wireless Mouse", productDescription: "Ergonomic wireless mouse with 6 buttons", productCategory: "Electronics", productSubcategory: "Computer Accessories", productSubSubcategory: "Input Devices", productBrand: "TechCorp", productBrandId: "BRAND-789", productBrandCountry: "USA", productPrice: 29.99, productPriceCurrency: "USD", productPriceFormatted: "$29.99", productStock: 150, productStockStatus: "in_stock", productStockWarehouse: "warehouse_3", productWeight: "0.2kg", productDimensions: "12x8x4cm", productColor: "black", productColorHex: "#000000", productRating: 4.5, productReviewCount: 234, productSKU: "MOUSE-WL-BK-001", productUPC: "123456789012", productManufacturer: "TechCorp Electronics Ltd", productOriginCountry: "China", productWarranty: "2 years", productReleaseDate: "2024-01-15", productLastUpdated: "2024-12-29T10:00:00Z", productCreatedAt: "2024-01-01T00:00:00Z", productCreatedBy: "admin@company.com", productUpdatedBy: "inventory@company.com", productTags: ["wireless", "ergonomic", "6-button", "usb-receiver"], productIsActive: true, productIsFeatured: false, productIsDiscounted: false // ... 15 more fields }, content: "TechCorp Wireless Mouse - Ergonomic design with 6 programmable buttons..." } // Problems: // 1. 90% of metadata never used in queries // 2. Duplicates info already in content // 3. Slows down indexing and retrieval // 4. Harder to maintain consistency ``` ```javascript theme={null} // ✅ Lean metadata - only what you query/filter by { groupName: ["products", "electronics", "accessories"], metadata: { productId: "PROD-12345", category: "input_devices", price: 29.99, inStock: true, brand: "TechCorp" }, content: ` TechCorp Wireless Mouse (SKU: MOUSE-WL-BK-001) Ergonomic wireless mouse with 6 programmable buttons Price: $29.99 | Rating: 4.5/5 (234 reviews) Color: Black | Weight: 0.2kg | Dimensions: 12x8x4cm Features: - 2.4GHz wireless with USB receiver - Ergonomic design for all-day comfort - 6 programmable buttons - 2-year warranty Stock: 150 units available at Warehouse 3 Origin: Made in China | Released: January 2024 ` } // Benefits: // 1. 80% less metadata storage // 2. Faster queries (fewer fields to scan) // 3. Easier to maintain // 4. Full info still retrievable from content ``` ### Decision Framework: Metadata vs Content **Store in METADATA if:** * ✅ You filter or sort by it (`price`, `inStock`, `category`) * ✅ You need exact matching (`productId`, `sku`) * ✅ It's used for access control (`department`, `classification`) * ✅ It changes frequently and independently (`stock`, `price`) **Store in CONTENT if:** * ✅ It's descriptive text (`description`, `features`) * ✅ It's rarely filtered (`dimensions`, `weight`) * ✅ It's only needed when document is retrieved (`warranty`, `origin`) * ✅ It's part of the semantic meaning (`reviews`, `specifications`) ### 💡 Pro Tip: The 5-Field Rule Start with maximum 5 metadata fields. Add more ONLY when you have a specific query pattern that requires it. ```javascript theme={null} // Starter template - covers 90% of use cases { groupName: ["domain", "category"], metadata: { id: "unique-identifier", // For updates/deletes status: "active", // For filtering lastModified: "2024-12-29", // For freshness owner: "team-name", // For access control priority: "high" // For ranking (optional) }, content: "..." // Everything else goes here } ``` ### ⚠️ Common Mistake: Duplicating Content in Metadata ```javascript theme={null} // ❌ Don't do this { metadata: { title: "Q4 Sales Report", // Duplicated summary: "Sales increased by 23%..." // Duplicated }, content: ` Q4 Sales Report Summary: Sales increased by 23%... ` } // ✅ Do this { metadata: { documentType: "sales_report", quarter: "q4_2024" }, content: ` Q4 Sales Report Summary: Sales increased by 23%... ` } ``` ### Real Impact: Before & After **Before optimization (metadata bloat):** * Storage: 2.3GB for 10,000 products * Query time: 450ms average * Index time: 12 minutes * Maintenance: 3 fields out of sync per 100 updates **After optimization (lean metadata):** * Storage: 0.8GB for 10,000 products (65% reduction) * Query time: 180ms average (60% faster) * Index time: 4 minutes (67% faster) * Maintenance: Consistency issues eliminated *** ## Quick Reference: Pattern Selection ``` Choose Pattern 1 (Hierarchical groupName) when: → You have multiple teams/departments → Access control matters → Your data has natural categories Choose Pattern 2 (Document Updates) when: → Delete-then-add: Content genuinely changes → Versioning: History matters (legal, compliance) → Conversational: Building context over time Choose Pattern 3 (Composable Context) when: → Combine: Info always retrieved together → Split: Different access patterns or update frequencies → Target 500-2000 words per document Choose Pattern 4 (Bulk Operations) when: → Ingesting 1000+ documents → Batch size: 1000 documents per call → Use retries and progress tracking Avoid Anti-Pattern 1 (Over-segmentation) by: → Keeping related info together → Passing the "paragraph test" → Simulating real user queries Avoid Anti-Pattern 2 (Metadata Bloat) by: → Starting with 5 fields max → Only storing what you filter/sort by → Keeping descriptions in content ``` # User Profiling for AI Applications Source: https://getalchemystai.com/docs/advanced/user-profiling Build AI systems that understand and adapt to individual users through intelligent memory and profiling. ## User Profiling with Alchemyst AI This guide shows you how to **build sophisticated user profiling** for AI consumer applications using Alchemyst AI's memory layer. ## What you'll build By the end of this guide, you will: * Store user preferences and behavioral patterns * Retrieve user context across sessions * Build personalized AI experiences * Manage user data with privacy controls ## Prerequisites You'll need: * An Alchemyst AI account - [**sign up**](https://platform.getalchemystai.com/auth?utm_source=docs\&utm_campaign=quickstart_memory\&utm_medium=quickstart_memory_article\&utm_content=quickstart_memory_prerequisites_cta) * Your `ALCHEMYST_AI_API_KEY` * Node.js 18+ *** ## Why Personalization Matters in Consumer AI Consumer AI applications face a fundamental challenge: **treating every user the same**. Without memory, each interaction starts from zero—users must repeatedly explain their context, preferences, and goals. This creates friction and undermines the promise of intelligent assistance. **AI memory transforms this experience** by enabling applications to build comprehensive user profiles that persist across sessions, devices, and time. The result is an AI that genuinely *knows* its users. ### The Personalization Gap Traditional AI applications suffer from: * **Context amnesia**: Forgetting previous conversations entirely * **Preference blindness**: Unable to remember what users like or dislike * **Repetitive interactions**: Asking the same clarifying questions repeatedly * **Generic responses**: One-size-fits-all answers that ignore individual needs ### How Memory Bridges This Gap AI memory creates a **living user profile** that evolves with every interaction: | User Signal | What Memory Captures | Personalization Outcome | | -------------------- | ----------------------------------- | ---------------------------------------- | | Past questions | Topics of interest, knowledge gaps | Tailored explanations at the right level | | Response feedback | Preferred answer length/format | Responses that match communication style | | Repeated behaviors | Workflow patterns, common tasks | Proactive suggestions and shortcuts | | Explicit preferences | Stated likes, dislikes, constraints | Filtered recommendations | | Temporal patterns | Active hours, usage frequency | Contextually-timed engagement | *** ## How Memory Powers User Profiling Alchemyst automatically builds rich user profiles through conversation history, enabling your AI to: **Understand User Preferences**: Track topics of interest, communication style, preferred level of detail, and recurring questions to tailor responses. For example, if a user consistently asks for code examples in Python, future responses automatically prioritize Python snippets. **Maintain Context Across Sessions**: Users can pick up conversations days or weeks later without repeating themselves, creating a seamless experience. Memory retains the thread of ongoing projects, unresolved questions, and evolving goals. **Personalize Recommendations**: Leverage past interactions to suggest relevant content, features, or actions that align with user interests. A user who frequently asks about data visualization will receive proactive suggestions about charting libraries or dashboard tools. **Adapt Communication Style**: Learn whether users prefer technical explanations, casual tone, brief answers, or detailed responses. Memory captures implicit signals—like users skipping long explanations or asking for more detail—to calibrate future interactions. **Track User Journey**: Understand feature adoption, pain points, and engagement patterns to improve product experience. Identify when users struggle with specific concepts and proactively offer help. ### Building Compound Personalization The true power of AI memory lies in **compound personalization**—where multiple profile dimensions combine to create deeply relevant experiences: # Asynchronously queue context data to add to the context processor Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/add-async/post POST /api/v1/context/add-async This endpoint accepts context data and queues it for asynchronous processing by the context processor. It returns a success or error response depending on the queuing result. # List all ongoing context add jobs for the authenticated user Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/add-async/status/get GET /api/v1/context/add-async/status Returns all jobs (active, waiting, delayed, failed, completed) belonging to the authenticated user. # Cancel a context add job Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/add-async/{id}/cancel/delete DELETE /api/v1/context/add-async/{id}/cancel Attempts to cancel a context add job by job id. - If the job is already completed or failed, returns 404. - If the job is currently running ("active"), returns 409 and cannot be cancelled. - Only jobs in "waiting" or "delayed" state can be cancelled. # Get status of a context add job Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/add-async/{id}/status/get GET /api/v1/context/add-async/{id}/status Returns the status and result of a context add job by job id. # Add context data to the context processor Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/add/post POST /api/v1/context/add This endpoint accepts context data and sends it to a context processor for further handling. It returns a success or error response depending on the result from the context processor. # Delete context data from the context processor Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/delete/post POST /api/v1/context/delete This endpoint deletes context data based on the provided parameters. It returns a success or error response depending on the result from the context processor. # Add memory context data Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/memory/add/post POST /api/v1/context/memory/add This endpoint adds memory (chat history) as context. # Delete memory context data Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/memory/delete/post POST /api/v1/context/memory/delete Deletes memory context data based on provided parameters. # Update memory context data Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/memory/update/post POST /api/v1/context/memory/update This endpoint updates memory context data. # Search for context data in the context processor Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/search/post POST /api/v1/context/search This endpoint sends a search request to the context processor to retrieve relevant context data based on the provided query. # Retrieves a list of traces for the authenticated user Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/traces/get GET /api/v1/context/traces Returns paginated traces for the authenticated user within their organization. # Delete a specific data trace Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/traces/{traceId}/delete/delete DELETE /api/v1/context/traces/{traceId}/delete Deletes a data trace for the authenticated user with the specified trace ID. # Retrieve user contexts by documents Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/view/docs/get GET /api/v1/context/view/docs Fetches documents view for authenticated user with optional organization context. # Retrieve user context Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/context/view/get GET /api/v1/context/view Gets the context information for the authenticated user. # View organization context Source: https://getalchemystai.com/docs/api-reference/endpoint/api/v1/org/context/view/post POST /api/v1/org/context/view # Introduction Source: https://getalchemystai.com/docs/api-reference/introduction API documentation and reference ## Welcome **[OpenAPI Specification](https://platform-backend.getalchemystai.com/api/openapi.json)** for the **Alchemyst Platform APIs**. View the OpenAPI specification file ## Authentication To obtain your **API key**, follow these steps: 1. Go to the **[Alchemyst Platform](https://platform.getalchemystai.com)** and sign up using your **Google account**. 2. After logging in, navigate to the **Get Started** section to generate your API key. 3. You can also view and manage your API keys anytime from the **Settings** page. Use the following authentication schema when making API requests: ```json theme={null} "security": [ { "bearerAuth": [] } ] ``` # Overview Source: https://getalchemystai.com/docs/changelog/index Latest platform updates and improvements. Follow along with updates across Alchemyst's context and memory platform. Stay up to date with the latest changes and improvements to Alchemyst. *** ## What's New This Month ( January ) **January 2026** brought major improvements to integrations and developer documentation: ### For Developers * **Vercel AI SDK Integration** - Native middleware support with examples for personalized chat, streaming, and bulk operations * **Enhanced Documentation** - Streamlined MongoDB/PostgreSQL guides and expanded user profiling patterns * **API Consistency** - Updated `conversationId` → `sessionId` across all integrations *** ## Recent Highlights (Oct - Dec 2025) ### For Developers * **Official SDKs** - TypeScript and Python SDKs for seamless integration with any AI stack * **10x Faster Retrieval** - Reduced latency by \~71% (from \~4s to \~1.14s) through optimized processors * **Namespaces** - Group and scope data under logical boundaries for multi-tenant workflows ### For Users * **Complete UI Revamp** - Redesigned platform with Playground as a full experimentation environment * **Magic Keys** - Share context without duplication, with read-only access control * **Visual Context Graph** - Dual-view visualization with direct editing capabilities ### Performance * **37% Faster Uploads** - Improved ingestion speed for large documents * **70%+ Speed Boost** - Dramatic improvements for short conversations * **Async Ingestion** - Non-blocking uploads backed by job queues for better throughput *** ## What's Next * **More Integrations** - Expanding support for additional AI frameworks and tools * **Business Adapters** - Pre-built connectors for enterprise platforms with streamlined setup *** Looking for detailed release notes? Check the [Platform Changelog](/docs/changelog/platform) for complete release history. # Platform Source: https://getalchemystai.com/docs/changelog/platform/index Latest features, improvements, and infrastructure updates to the Alchemyst platform. Track the evolution of Alchemyst's context and memory platform. From performance optimizations to new integrations, see what's new and how we're making AI context more powerful and accessible. *** ### 31 January 2026 **Data Sources Documentation** **What's new:** * Cleaner, more focused database integration guides **What changed:** * Streamlined **MongoDB and PostgreSQL documentation** by removing redundant examples * Improved overall readability and structure across all data source integration guides * Made documentation more beginner-friendly with simplified explanations *** ### 17 January 2026 **Third-party Integrations: Vercel AI SDK** **What's new:** * **Vercel AI SDK integration** with full middleware support * Comprehensive examples for real-world use cases (user preferences, personalized chat, streaming, bulk operations) **What changed:** * Renamed **conversationId** → **sessionId** across all integrations for better API consistency * Added batching support and performance optimization guides for large-scale operations *** ### 15 January 2026 **Advanced Usage Documentation** **What's new:** * Enhanced **user profiling documentation** with advanced patterns * New code examples for user-specific context management **What changed:** * Restructured advanced features section for easier navigation * Expanded best practices with production-ready examples * Improved documentation discoverability *** ## Recent Platform Updates ### 18 December 2025 **Platform Revamp** **What's new:** * Completely redesigned UI and Playground experience * Playground now supports direct data uploads and experimentation * Magic keys integration in the Playground interface **What changed:** * Streamlined navigation and workflows across the entire platform * Playground evolved from a simple chat interface to a full experimentation environment * Faster iteration cycles without leaving the Playground *** ### 12 December 2025 **Ingestion Performance & Reliability** **What's new:** * Asynchronous ingestion routes with job queue backing * Non-blocking upload capabilities **What changed:** * Upload operations no longer block other processes * Dramatically improved throughput under heavy load * More stable system performance during peak usage *** ### 3 December 2025 **Context Sharing** **What's new:** * **Magic keys** for sharing context without duplication * Read-only sharing capabilities **What changed:** * No need to re-ingest data when sharing with team members * Recipients automatically get read-only access via magic key * Simplified collaboration workflows *** ### 27 November 2025 **Context Visualization** **What's new:** * Dual-view context graph visualization * Interactive graph editing capabilities * Group-name based clustering **What changed:** * Added **Document view** to explore context by source documents * Added **Node view** to inspect individual context relationships * Can now edit and delete nodes directly from the graph * Changes reflect instantly across all connected context *** ### 8 November 2025 **Namespaces** **What's new:** * **Namespaces** for logical data boundaries * Multi-tenant and multi-project support **What changed:** * Data can now be organized under named namespaces * More precise context retrieval through namespace scoping * Better isolation for enterprise and team workflows *** ### 21 October 2025 **Context Retrieval** **What's new:** * Completely overhauled context processor **What changed:** * **\~71% faster** ranked retrieval (from \~7s to \~2s for 10k data points) * **\~57% faster** fast-mode retrieval (from \~400ms to \~170ms at p50) * More efficient retrieval algorithms under the hood *** ### 6 October 2025 **SDK Release** **What's new:** * Official **TypeScript SDK** * Official **Python SDK** **What changed:** * Unified API for context ingestion, retrieval, and memory management * Drop-in integration support for popular agent frameworks * Developer-friendly API design optimized for quick adoption *** ## The Journey So Far From October 2025 through early 2026, Alchemyst evolved from foundational data infrastructure into a **production-ready context and memory layer** for modern AI applications. Key achievements: * **10x faster retrieval** through optimized processors and caching * **Expanded integration ecosystem** with native SDK support and framework integrations * **Enhanced developer experience** with intuitive UI, comprehensive docs, and powerful debugging tools * **Enterprise-ready features** including namespaces, magic keys, and robust async ingestion We're just getting started. More updates coming soon. # How to get featured in Awesome‑SaaS Source: https://getalchemystai.com/docs/contribution/awesome-saas-repo How community contributors can prepare and get their projects listed in the Awesome‑SaaS collection. ## What are AI agents? AI agents are modular programs that combine models, tools, and memory to perform higher‑level tasks. In this repository, an **agent** is a self‑contained folder under `agents/` that bundles code, configuration, and documentation so builders can run, extend, or deploy a specific AI workflow — for example: newsletter generation, document summarization, or ticket triage. Agents can be delivered as CLI tools, serverless API routes, bots, or full SaaS templates that integrate with the Alchemyst AI Platform. ## Quick Guide This guide explains how to prepare and submit your AI agent so it can be featured in the Awesome-SaaS collection. * Eligibility requirements to appear in the Awesome‑SaaS listing. * Required files and metadata so the automated generator can discover your project. * How to open a focused PR and what to include in the description for a smooth review. * Contributor-focused troubleshooting steps if your project does not appear. ## Repository Overview * **Root docs:** `README.md`, `index.md`, `CONTRIBUTING.md`. * **Agents:** each agent lives in `agents/` and should include a `README.md` and a dependency manifest (`package.json`, `requirements.txt`, etc.). * **Generators:** `list.js` and `leaderboard.js` produce the public listing and contributor leaderboard. * **Community leaderboard:** see `leaderboard/README.md` for maintainer notes. ## How to prepare your project (step‑by‑step) Follow these steps to make your project eligible for the Awesome-SaaS listing and easy for maintainers and other builders to evaluate. 1. **Make the repository public** * Ensure the repository is **public on GitHub** so the listing script can discover it. 2. **Add the repository topic** * Add the exact topic `alchemyst-awesome-saas` to your repo 3. **Provide a clear `README.md` that includes**: * One‑line description. * Quick install & run steps. * Example usage and a short **Why this helps builders** paragraph. * Required environment variables and a sample `.env.example`. * License information. 4. **Keep the agent self-contained** Put all runtime files and manifests inside `agents//`, including: * Dependency manifests (e.g., `package.json`, `requirements.txt`). * Config samples (e.g., `.env.example`). * A minimal runnable demo or reproducible example so reviewers can confirm it runs locally. 5. **Add helpful extras** (optional but recommended) * Screenshots or a short demo GIF. * CI (GitHub Actions) with basic smoke tests. * README badges (build, license, version). * Additional topic tags describing the agent's domain. ## Recommended folder layout This is where all community-contributed AI agents live. Each sub-folder here contains an agent built using the Alchemyst AI Platform, whether it's a CLI agent, SaaS prototype, or something experimental with Memory AI. ``` agents/ ├── email-agent/ │ ├── README.md │ ├── main.py │ ├── requirements.txt │ └── ... ├── chatbot-agent/ │ ├── README.md │ ├── app.js │ └── ... └── ... ``` ## PR & Contribution checklist * Create a feature branch (e.g. `feature/docs-community` or `feature/community-`). * Keep PRs focused: one doc or feature per PR. * Confirm `alchemyst-awesome-saas` is added to your repository topics. * Add links to your project in the PR description and request the `hacktoberfest-accepted` label if you want the PR to count for Hacktoberfest. ## Examples * [B2b-newsletter-writer](https://docs.getalchemystai.com/example-projects/community/b2b-newsletter-writer) - The **B2B Newsletter AI Agent** is a SaaS prototype that automatically generates audience-focused newsletters for businesses using the Alchemyst AI Platform * [Discord-bot](https://docs.getalchemystai.com/example-projects/community/discord-bot) - A simple Discord bot powered by [Alchemyst AI SDK](https://docs.getalchemystai.com/integrations/sdk/typescript-sdk) and OpenAI. The bot stores conversation context and provides smart answers to users' questions in direct messages. ## Troubleshooting * Keep your agent self-contained (all dependencies in its own folder). * Include a clear `README.md` with: * What the agent does * Setup steps * Example usage * Stay aligned with the repo's theme (AI Agents, AI SaaS, Agentic AI, Memory AI). * Avoid broken, incomplete, or irrelevant code. ## Need Help? If you get stuck or want to share feedback: * Browse the **Guides** and **API docs** on this site. * Search the documentation for targeted answers. * Join our [Discord server](https://dub.sh/context-community) for real-time help. # Contributing Source: https://getalchemystai.com/docs/contribution/contributing Guide for contributing to our documentation ## Introduction Welcome to our documentation contribution guide! We're excited that you're interested in helping improve our documentation. This guide will walk you through everything you need to know to make your first contribution. ## Prerequisites Before you begin, ensure you have the following: **Required Tools & Accounts**: * Node.js version 19 or higher * npm or yarn * Git installed on your machine * A GitHub account * A docs repository with a `docs.json` file * Code editor (we recommend VS Code) ## How to Contribute Follow these steps to make your first contribution: 1. Fork the repository by clicking the 'Fork' button on GitHub 2. Clone your fork locally: ```bash theme={null} git clone https://github.com/YOUR-USERNAME/docs.git cd docs ``` Install the Mintlify CLI: ```bash theme={null} npm i -g mint ``` Navigate to your developer-docs directory, and start the development server: ```bash theme={null} cd developer-docs mint dev ``` A local preview will be available at `http://localhost:3000`. Make your changes and test them locally. Stage and commit your changes: ```bash theme={null} git add . git commit -m "Description of your changes" ``` 1. Push your changes to your fork 2. Go to the original repository and create a Pull Request 3. Follow the PR template and provide a clear description of your changes ### MDX Quick Tips * Check how MDX works. You can see examples in `/essentials` ### Structure & Navigation * Place new pages in the most relevant directory (e.g., `ai-context/`, `integrations/`). * For API docs, follow `api-reference/endpoint/api/v1/...` folder conventions. * Update `docs.json` to surface new sections/pages in the sidebar navigation. ### Quality Checks * **Run**: `mint dev` and verify the page renders, links work, and images load * **Lint/content sanity**: check for broken links, heading hierarchy, and typos * **Keep line length readable**; wrap long lines and avoid trailing spaces ### Commit and PR * Commit style: `docs(scope): short summary` (e.g., `docs(ai-context): add diagram`) * When adding files, update the Directory map in this README (`developer-docs/README.md`). * Push your branch and open a PR to `main` * In the PR description: **include screenshots** of visual changes and a brief summary * Request review from a maintainer; address feedback promptly Please follow [Conventional Commits](https://www.conventionalcommits.org/) format: * `fix: ...` → for bug fixes * `docs: ...` → for documentation changes * `feat: ...` → for new features * `chore: ...` → for maintenance tasks ## Custom ports By default, Mintlify uses `port 3000`. You can customize the port Mintlify runs on by using the `--port` flag. For example, to run Mintlify on `port 3333`, use this command: ```bash theme={null} mint dev --port 3333 ``` If you attempt to run Mintlify on a port that's already in use, it will use the next available port: ``` Port 3000 is already in use. Trying 3001 instead. ``` ## Mintlify versions Please note that each CLI release is associated with a specific version of Mintlify. If your local preview does not align with the production version, please update the CLI: ```bash theme={null} npm update -g mint ``` ## Validating links The CLI can assist with validating links in your documentation. To identify any broken links, use the following command: ```bash theme={null} mint broken-links ``` ## Deployment If the deployment is successful, you should see the following: Screenshot of a deployment confirmation message that says All checks have passed. ## Code formatting We suggest using extensions on your IDE to recognize and format MDX. If you're a VSCode user, consider the [MDX VSCode extension](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) for syntax highlighting, and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) for code formatting. ## Troubleshooting This may be due to an outdated version of Node.js. Try the following: 1. Remove the currently-installed version of the CLI: `npm remove -g mint` 2. Upgrade to Node v19 or higher. 3. Reinstall the CLI: `npm i -g mint` Solution: Go to the root of your device and delete the `~/.mintlify` folder. Then run `mint dev` again. Curious about what changed in the latest CLI version? Check out the [CLI changelog](https://www.npmjs.com/package/mintlify?activeTab=versions). ## Review Process Here's what happens after you submit your PR: 1. **Initial Check**: Automated checks will run to ensure your changes meet our basic requirements 2. **Review**: A maintainer will review your PR within 1-2 business days 3. **Feedback**: You may receive feedback requesting changes 4. **Merge**: merged into the `main` branch.\ Once deployed, you can view your changes at [docs.getalchemystai.com](https://docs.getalchemystai.com/).\ If issues arise, submit a follow-up PR with focused fixes. Screenshot showing a successfully merged Pull Request. ## Where to Ask for Help Need help? We're here to support you: * **Discord Community**: Join our [Discord server](https://discord.gg/H2StAaSeJ8) for real-time help * **GitHub Issues**: Search existing [issues](https://github.com/Alchemyst-ai/docs/issues) or create a new one Remember, no question is too small. We're happy to help you contribute! # B2b newsletter writer Source: https://getalchemystai.com/docs/example-projects/community/b2b-newsletter-writer # B2B Newsletter AI Agent ## Overview The **B2B Newsletter AI Agent** is a SaaS prototype that automatically generates audience-focused newsletters for businesses using the Alchemyst AI Platform. It leverages AI to create high-quality, personalized content that can be used for marketing, customer engagement, or internal communication. This agent provides a simple interface where users can input key details about their audience, product, or service, and receive a professional newsletter draft in return. *** ## Features * Generate fully structured B2B newsletters in minutes. * Customize content for specific audiences or industries. * Supports multiple newsletter formats (HTML, plain text). * Ready-to-use SaaS template for deployment. *** ## Setup Instructions ### Prerequisites * Python 3.10+ or Node.js 18+ (depending on your implementation) * Alchemyst AI SDK installed and configured * Access to Alchemyst API key ### Installation 1. Clone the repository: ```bash theme={null} git clone https://github.com/aniketsingh1023/B2B-Newsletter-SaaS.git cd B2B-Newsletter-SaaS/agents/b2b-newsletter-agent ``` Install dependencies: For Python version: ``` pip install -r requirements.txt ``` For Node.js version: ``` npm install ``` Set your Alchemyst API key and also Gemini API Key as an environment variable: ``` ALCHEMYST_AI_API_KEY=your_api_key GEMINI_API_KEY=your_api_key ``` # Company research Source: https://getalchemystai.com/docs/example-projects/community/company_research # Company Research AI Agent A powerful, real-time company research application built with Python, Streamlit, and AlchemystAI's Chat Streaming API. This tool provides comprehensive business intelligence analysis for any company with streaming updates and downloadable reports. ## 🚀 Features * **Comprehensive Reports**: Detailed company analysis covering: * Executive summary and business overview * Financial landscape and funding history * Competitive analysis and market positioning * Demographic insights and target audience * Technology stack and operations * Market opportunities and risk assessment * **Downloadable Reports**: Export research findings as text files * **User-friendly Interface**: Clean, modern Streamlit web interface ## 🛠️ Tech Stack * **Python** - Backend logic and API integration * **AlchemystAI Chat API** - AI-powered research engine * **AlchemystAI SDK** - AI-powered research engine * **Streamlit** - Web application framework * **Requests** - HTTP client for API communication ## 📋 Prerequisites * Python 3.8+ * AlchemystAI API Key * Gemini API Key ## ⚡ Quick Start 1. **Clone the repository** ```bash theme={null} git clone cd company_research ``` 2. **Install the dependencies** ```bash theme={null} pip install -r requirements.txt ``` 3. **Setting the API Keys in .env** ```bash theme={null} ALCHEMYST_API_KEY = "Your Alchemyst API key" GEMINI_API_KEY = "Your Gemini API Key" ``` 4. **Run app.py** ```bash theme={null} streamlit run app.py ``` # Discord bot Source: https://getalchemystai.com/docs/example-projects/community/discord-bot # Discord AI Chat Bot A simple Discord bot powered by [Alchemyst AI SDK](https://docs.getalchemystai.com/integrations/sdk/typescript-sdk) and OpenAI. The bot stores conversation context and provides smart answers to users’ questions in direct messages. *** ## Features * Responds to **Direct Messages (DMs)** only. * Stores conversation context using Alchemyst AI. * Generates intelligent responses with OpenAI models. * Easily extendable for new features and commands. *** ## Prerequisites * Node.js v20+ * Discord Bot Token ([create one here](https://discord.com/developers/applications)) * Alchemyst AI API Key * OpenAI API Key *** # Prompt evaluator Source: https://getalchemystai.com/docs/example-projects/community/prompt-evaluator # AI Prompt Evaluator This project is an AI-powered prompt evaluation tool built with [Next.js](https://nextjs.org). It analyzes user prompts and provides structured feedback to help improve clarity, groundedness, tonality, and overall effectiveness. The evaluation is performed using Google's Gemini LLM and context management via AlchemystAI. ## Features * Enter a prompt and receive an instant evaluation. * Visualize prompt quality across multiple criteria (relevance, intent match, groundedness, fluency, conciseness, reference alignment, tonality). * Get actionable suggestions and an improved version of your prompt. * Interactive charts and UI components for clear feedback. ## How It Works 1. Enter your prompt in the input box. 2. Click **Evaluate**. 3. The backend sends your prompt to a Gemini LLM, using context from previous evaluations via AlchemystAI. 4. The LLM returns a JSON evaluation, which is visualized and displayed in the UI. ## Running Locally ### Prerequisites * Node.js (v18+ recommended) * npm, yarn, pnpm, or bun ### Environment Variables Create a `.env.local` file in the root directory and add: ``` GOOGLE_API_KEY=your-google-generative-ai-key ALCHEMYST_API_KEY=your-alchemystai-sdk-key ``` ### Install Dependencies ```bash theme={null} npm install # or yarn install # or pnpm install ``` ### Start the Development Server ```bash theme={null} npm run dev # or yarn dev # or pnpm dev # or bun dev ``` Open [http://localhost:3000](http://localhost:3000) in your browser. ## Dependencies * [Next.js](https://nextjs.org) * [React](https://react.dev) * [@google/generative-ai](https://www.npmjs.com/package/@google/generative-ai) * [@alchemystai/sdk](https://www.npmjs.com/package/@alchemystai/sdk) * [@tanstack/react-query](https://tanstack.com/query/latest) * [d3](https://d3js.org) (for charts) * [Tailwind CSS](https://tailwindcss.com) (for styling) * [Lucide React](https://lucide.dev) (icons) * [uuid](https://www.npmjs.com/package/uuid) * [axios](https://axios-http.com) ## Project Structure * `app/` - Next.js app directory (main pages and layout) * `components/` - UI components * `lib/` - API utilities and context management * `src/` - Types and config * `.env.local` - Environment variables (not committed) ## # Introduction Source: https://getalchemystai.com/docs/example-projects/introduction # CLI Agent Source: https://getalchemystai.com/docs/example-projects/team/cli-chatbot Build a Context-Aware CLI tool that answers questions using stored context from Alchemyst and Gemini. ## What it does * Accepts questions from the terminal * Searches Alchemyst for relevant stored context * Injects that context into the prompt * Generates grounded responses using an LLM This pattern is ideal for **developer tools, internal assistants, and debugging workflows**. ### Repo link The full source code for this CLI agent is also available in our public repository. It includes this **Node.js implementation** as well as a **Python version** of the same context-aware agent. If you prefer Python, you can use that implementation directly or adapt it to your workflow. View the repository: * [python](https://github.com/Alchemyst-ai/awesome-saas/tree/main/agents/alchemystai-python-SDK) * [typescript](https://github.com/Alchemyst-ai/awesome-saas/tree/main/agents/alchemystai-ts-SDK) ## Prerequisites You'll need: * Node.js 18+ * An Alchemyst AI API key * A Google Gemini API key ## 1. Set your environment variables ```bash theme={null} export ALCHEMYST_AI_API_KEY=your_key_here export GEMINI_API_KEY=your_key_here ``` ### How it works The flow is simple: * **Accept a user question** from the CLI * **Search Alchemyst** for relevant context * **Inject retrieved context** into the LLM prompt * **Generate and display** the response If no relevant context is found, the agent falls back to general model knowledge. ## 2.Install dependencies ```bash theme={null} npm install @alchemystai/sdk @google/generative-ai dotenv ``` ## 3.Add the code ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; import * as readline from 'readline'; import 'dotenv/config'; import { GoogleGenerativeAI } from "@google/generative-ai"; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY || '', }); const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY || ''); const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash" }); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); const askQuestion = (prompt: string): Promise => { return new Promise((resolve) => { rl.question(prompt, (answer) => resolve(answer)); }); }; async function runCLI() { console.log('Alchemyst AI CLI Tool'); console.log('Type your questions and get AI-powered answers with context!'); console.log('Type "exit", "quit", or "bye" to stop.\n'); if (!process.env.ALCHEMYST_AI_API_KEY || !process.env.GEMINI_API_KEY) { console.error('Missing required environment variables.'); process.exit(1); } while (true) { const userQuestion = await askQuestion('Ask me anything: '); if (['exit', 'quit', 'bye', 'stop'].includes(userQuestion.toLowerCase().trim())) { console.log('Goodbye!'); break; } if (!userQuestion.trim()) { console.log(' Please enter a question.\n'); continue; } console.log('Searching for relevant context...'); const { contexts } = await client.v1.context.search({ query: userQuestion, similarity_threshold: 0.8, minimum_similarity_threshold: 0.5, scope: 'internal', }); let promptText = userQuestion; if (contexts && contexts.length > 0) { const formattedContexts = contexts .map((c, i) => `Context ${i + 1}: ${c.content}`) .join('\n\n'); promptText = ` Based on the following context, answer the question. If the context is insufficient, say so clearly. Contexts: ${formattedContexts} Question: ${userQuestion} `; } console.log('Generating response...'); const result = await model.generateContent(promptText); console.log(result.response.text()); console.log('\n' + '─'.repeat(50) + '\n'); } rl.close(); } runCLI(); ``` ## 4. Run the code ```bash theme={null} node index.js ``` ## Build Beyond the CLI You've built a foundational context-aware agent, but this is just the beginning. The Alchemyst AI platform is designed to be the "brain" of your larger systems. From here, you can extend this pattern to: **Persistent Memory**: Enable long-term recall by saving user preferences in dedicated namespaces. **Knowledge Ingestion**: Connect your agent to PDFs, GitHub repos, or Slack history for deep domain expertise. **Serverless Agents**: Wrap this logic in a FastAPI or Next.js route to power a web-based AI microservice. # SyllabAI Source: https://getalchemystai.com/docs/example-projects/team/syllabai Upload your syllabus and get personalized study assistance and Q&A ## Overview **SyllabAI** is a starter project built with **Next.js** that helps students and instructors turn a course syllabus into an interactive study assistant. Upload a syllabus (PDF/DOCX/TXT), the platform extracts and indexes the content, and you can immediately ask questions or request summaries. ```mermaid theme={null} sequenceDiagram participant U as User participant FE as Frontend participant BE as Backend participant IDX as Index/Store U->>FE: Upload syllabus (PDF/DOCX/TXT) FE->>BE: POST /upload (file) BE->>BE: Extract text BE->>IDX: POST /context/add (document) U->>FE: Ask question in chat FE->>BE: POST /chat/generate (chat_history) BE->>IDX: Retrieve context BE->>FE: Return generated answer FE->>U: Show answer ``` *** ## Get Started ```bash theme={null} git clone https://github.com/Alchemyst-ai/SyllabAI.git cd SyllabAI npm install # or: pnpm install cp .env.example .env npm run dev # app starts at http://localhost:3000 (default) ``` > ⚡ After setup, upload a small test syllabus at `/upload` and visit `/chat` to interact. *** ## How It Works ? 1. **Prepare your syllabus** – Export or collect your syllabus in PDF, DOCX or TXT. 2. **Upload** – Use the Upload page to send the file to the backend extraction endpoint. 3. **Extract & Index** – Backend extracts text and adds it to a document store (or index) via `/context/add`. 4. **Ask** – Use the Chat UI to ask questions; the backend generates responses grounded in the indexed syllabus. ```mermaid theme={null} flowchart LR FE["Frontend (Next.js)"] UP["/upload"] CA["/context/add"] CG["/chat/generate"] EX["Extraction Service"] VS["Vector Store / DB"] MODEL["LLM / Generation"] FE --> UP UP --> EX EX --> CA CA --> VS FE --> CG CG --> VS CG --> MODEL MODEL --> CG ``` *** ## Environment Variables Copy `.env.example` → `.env` and set at minimum: ```bash theme={null} NEXT_PUBLIC_BACKEND_URL=https://your-backend.example.com NEXT_PUBLIC_API_KEY=your_api_key_here # Optional: configure timeouts, storage endpoints, and dev ports ``` > ⚠️ Keep keys and secrets out of version control. *** ## Code Structure ``` Root Directory ├── app/ # Next.js app (pages & routes) │ ├── page.tsx # Landing │ ├── upload/page.tsx # Upload UI and client-side flow │ └── chat/page.tsx # Chat UI and message handling ├── components/ # Reusable UI components │ ├── file-upload.tsx │ ├── chat-message.tsx │ └── document-viewer.tsx ├── lib/ # Utility helpers ├── public/ # Static assets ├── styles/ # Tailwind / CSS ├── package.json # Scripts & dependencies └── README.md # Project README ``` ```mermaid theme={null} graph TD A[app/] --> A1[page.tsx] A --> A2[upload/page.tsx] A --> A3[chat/page.tsx] B[components/] --> B1[file-upload.tsx] B --> B2[chat-message.tsx] B --> B3[document-viewer.tsx] ``` *** ## Architecture & Flow SyllabAI is organized into four main modules: **Frontend**, **Backend (integration)**, **Storage / Indexing**, and **Configuration**. ### 1. Frontend Handles uploads, interactions, and rendering. **Key files**: * `app/upload/page.tsx` — file upload, validation, and `/upload` call * `app/chat/page.tsx` — chat UI, fetch document, send `chat_history` * `components/*` — UI primitives (file upload, message, viewer) ### 2. Backend (integration) The frontend relies on a backend to perform extract, index, and generate operations. The backend can be any service that implements the expected endpoints and authorization. **Expected endpoints**: * `POST /upload` — Accepts multipart/form-data (file), returns `{ text }`. * `POST /context/add` — Accepts documents payload to index/store content. * `POST /chat/generate` — Accepts a `chat_history` and returns a generated response object. ### 3. Storage / Indexing Indexing can be as simple as storing raw documents in a database or more advanced using vector embeddings and a vector store for retrieval-augmented generation. ### 4. Configuration Environment variables and API keys configure the backend endpoints, auth, and optional storage settings. ```mermaid theme={null} flowchart LR U[User] --> FE[Frontend] FE --> API[Backend Endpoints] API --> IDX[Index / Vector Store] IDX --> GEN[Generation / Retrieval] GEN --> FE ``` *** ## Core Features * Upload PDF / DOCX / TXT syllabus files * Extract and index content for retrieval * Chat UI that answers questions grounded in the syllabus * Modular frontend that can work with different backends ```mermaid theme={null} flowchart LR Upload[Upload Page] --> Viewer[Document Viewer] Viewer --> Chat[Chat UI] Chat --> Backend[Backend / Retrieval] ``` *** ## API Endpoints ### Documents * POST `/upload` — Upload a file (FormData) and receive extracted text `{ "text": "..." }`. * POST `/context/add` — Add documents for indexing: `{ documents: [{ content, fileName, fileType, fileSize, name }], source, context_type }`. ### Chat * POST `/chat/generate` — Generate an assistant response from `chat_history` and options. The UI expects response content at `result.response.kwargs.content`. *** ## Example HTTP requests Here are concrete examples you can use when testing or building a compatible backend. 1. Upload (curl) ```bash theme={null} curl -X POST "$NEXT_PUBLIC_BACKEND_URL/upload" \ -H "Authorization: Bearer $NEXT_PUBLIC_API_KEY" \ -F "file=@/path/to/syllabus.pdf" ``` Expected (mock) response: ```json theme={null} { "text": "This is mock extracted text from syllabus.pdf" } ``` 2. Context add (curl) ```bash theme={null} curl -X POST "$NEXT_PUBLIC_BACKEND_URL/context/add" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $NEXT_PUBLIC_API_KEY" \ -d '{ "documents": [{ "content": "", "fileName": "syllabus.pdf", "name": "Intro to CS" }], "source": "user-upload", "context_type": "resource" }' ``` Expected response: ```json theme={null} { "success": true, "documentId": "doc_12345" } ``` 3. Chat generate (curl) ```bash theme={null} curl -X POST "$NEXT_PUBLIC_BACKEND_URL/chat/generate" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $NEXT_PUBLIC_API_KEY" \ -d '{ "chat_history": [{ "type": "human", "id": "1", "lc_kwargs": { "content": "What are the grading policies?" } }] }' ``` Expected (mock) response shape (frontend expects assistant content at result.response.kwargs.content): ```json theme={null} { "result": { "response": { "kwargs": { "content": "The grading policy is: Assignments 40%, Midterm 30%, Final 30%." } } } } ``` *** *** ## Troubleshooting * 400/401 errors: verify `NEXT_PUBLIC_BACKEND_URL` and `NEXT_PUBLIC_API_KEY`. * Empty chat responses: ensure the document was added via `/context/add` and the backend returns embeddings or indexed content. * Upload parsing errors: check backend logs for file parser issues (unsupported PDF structure or encoding). *** ## How to run & deploy ### Run locally ```bash theme={null} npm install npm run dev # development server npm run build npm run start # production ``` ### Testing * Upload a short syllabus (\~1–3 pages) and ask a few questions in the chat UI. * Optionally add unit/integration tests for upload and chat API integrations. *** ## Security & Best Practices * Keep API keys secret and use server-side auth where possible. * Validate and sanitize uploads server-side to prevent malicious files. * Rate-limit generation endpoints and monitor usage. *** ## Benefits 1. Fast to set up and test — a minimal frontend that integrates with any compatible backend. 2. Focused UX for syllabus-driven learning. 3. Easily extensible — swap or enhance the backend for improved retrieval and generation. *** Star and look at the code # Zendocs Source: https://getalchemystai.com/docs/example-projects/team/zendocs Put your SEO on AutoPilot with automated indexing ## Overview **Zendocs** is a starter project built with **Next.js + MongoDB** that helps you put your documentation and SEO on **autopilot**. Instead of manually creating and maintaining docs pages, you upload your documentation, and the **Alchemyst Platform** takes care of indexing, generating SEO-friendly pages, and enabling Q\&A directly from your docs. *** ## Get Started ```bash theme={null} git clone https://github.com/Alchemyst-ai/zendocs.git cd zendocs npm install cp .env.example .env npm run dev # app starts at http://localhost:4163 ``` > ⚡ After setup, upload a small test file. You should see: > > * A successful request at `/api/upload` in DevTools > * A record created in **MongoDB** > * A new SEO-friendly page under `/docs/{id}` *** ## How It Works ? 1. **Prepare your docs** – Gather your internal documentation (text, markdown, or zipped files). 2. **Create a MongoDB instance** – Either self-hosted or on [MongoDB Atlas](https://www.mongodb.com/atlas/database). 3. **Sign up on [Alchemyst Platform](https://getalchemystai.com?utm_source=docs.getalchemystai.com\&utm_campaign=docs\&utm_medium=web)** – Create an account and get an [API KEY](https://platform.getalchemystai.com/settings). 4. **Upload docs to [Context Surgeon](https://platform.getalchemystai.com/context)** – This tool indexes your documents so the AI can use them. 5. **Set environment variables** – Copy `.env.example` → `.env` and fill in: ```bash theme={null} BACKEND_BASE_URL=https://platform-backend.getalchemystai.com NEXT_BACKEND_URL=http://localhost:4163 # or your deployed URL ``` 6. **Run locally** – Start the app and you'll see your docs auto-generated with SEO pages. 7. **Ask questions** – Users can search or ask questions, and get answers powered by your docs. ```mermaid theme={null} flowchart LR U["User: Upload Docs"] --> FE["Upload UI"] FE --> API["API Route /api/upload"] API --> BE["Alchemyst Platform (Context Surgeon)"] BE --> IDX["Indexing & Embeddings"] IDX --> DB["MongoDB Stores Metadata"] IDX --> GEN["SEO Page Generator"] GEN --> PAGES["Docs Pages /docs/[id]"] PAGES --> UI["Docs Viewer + Search"] UI -->|Queries| BE ``` *** ## Environment Variables Set these in `.env`: ```bash theme={null} ALCHEMYST_API_KEY=YOUR_ALCHEMYST_API_KEY BACKEND_BASE_URL=YOUR_BACKEND_BASE_URL MONGODB_URL=YOUR_MONGODB_URL DB_NAME=YOUR_DB_NAME DEBOUNCING_THRESHOLD=YOUR_API_DEBOUNCING_THRESHOLD_IN_MS NEXT_APP_BACKEND_URL=http://localhost:4163 ``` > ⚠️ Remember to keep `.env` out of version control. *** ## Code Structure ``` Root Directory ├── .env.example # Environment variables template ├── .eslintrc.json # ESLint configuration ├── .gitignore # Git ignore rules ├── components.json # UI components configuration ├── next.config.mjs # Next.js configuration ├── package.json # Project dependencies and scripts ├── postcss.config.mjs # PostCSS configuration ├── README.md # Project documentation ├── tailwind.config.ts # Tailwind CSS configuration ├── tsconfig.json # TypeScript configuration │ ├── .azure/ # Azure configuration directory ├── .github/ # GitHub configuration │ └── workflows/ │ └── codacy.yml # Codacy security scan workflow │ ├── collections/ # API collections │ └── apis.http # HTTP API examples │ ├── public/ # Public assets │ ├── robots.txt # SEO robots file │ ├── fonts/ # Font files │ └── logo/ # Logo images │ ├── scripts/ # Utility scripts │ └── insert-test-docs.ts # Script to insert test documents │ └── src/ # Source code ├── app/ # Next.js app directory │ ├── api/ # API routes │ ├── docs/ # Documentation pages │ ├── layout.tsx # Root layout │ ├── page.tsx # Home page │ └── globals.css # Global styles │ ├── components/ # React components │ ├── docs/ # Documentation-specific components │ └── ui/ # Reusable UI components │ ├── lib/ # Library code ├── models/ # Database models ├── types/ # TypeScript type definitions └── utils/ # Utility functions ``` *** ## Architecture & Flow **Zendocs** is divided into four main modules: **Frontend**, **Backend**, **Database**, and **Config**. Below is a detailed breakdown with flowcharts for each module. ### 1. Frontend Handles user interactions, file uploads, and displaying documentation and search results. > **Key Files**: > > * src/pages/upload.tsx – Upload UI > * src/components/DocViewer.tsx – Displays individual docs > * src/components/Search.tsx – Search & Q\&A interface ```mermaid theme={null} flowchart LR U["User"] --> FE["Upload UI (upload.tsx)"] FE --> VIEW["Docs Viewer (DocViewer.tsx)"] VIEW --> SEARCH["Search & Chat UI (Search.tsx)"] SEARCH -->|Queries| FE ``` ### 2. Backend Processes uploaded files, interacts with the Alchemyst AI platform, and generates SEO pages. > **Key Files**: > > * src/pages/api/upload.ts – API route for uploads > * Alchemyst Platform – Indexing & embedding service > * Page Generator – Creates SEO-friendly pages and sitemap ```mermaid theme={null} flowchart LR API["API Route (api/upload.ts)"] --> BE["Alchemyst Platform (Context Surgeon)"] BE --> IDX["Indexing & Embeddings"] IDX --> GEN["SEO Page Generator"] GEN --> PAGES["Docs Pages (docs/[id].tsx)"] ``` ### 3. Database Stores metadata and document information for quick retrieval and search. > **Key Files**: > > * lib/mongodb.ts – MongoDB connection helper > * models/ – MongoDB schemas ```mermaid theme={null} flowchart LR IDX["Indexing & Embeddings"] --> DB["MongoDB (Stores docs metadata)"] ``` ### 4. Configuration Environment variables manage API keys, backend URLs, and thresholds for debouncing requests. > **Key Variables**: ```bash theme={null} ALCHEMYST_API_KEY=YOUR_API_KEY BACKEND_BASE_URL=https://platform-backend.getalchemystai.com MONGODB_URL=YOUR_MONGODB_URL DB_NAME=YOUR_DB_NAME NEXT_APP_BACKEND_URL=http://localhost:4163 DEBOUNCING_THRESHOLD=YOUR_API_DEBOUNCING_THRESHOLD_IN_MS ``` ```mermaid theme={null} flowchart LR ENV["Environment Variables"] -.-> API["API Route"] ENV -.-> FE["Frontend Components"] ``` *** ## Core Features ### 1. Document Generation Generates docs from uploaded content via Alchemyst AI. Stored in MongoDB with metadata for fast retrieval. ->`generateDocs.ts` ### 2. Document Chat Real-time chat for a document's context. Integrates with Alchemyst AI for intelligent responses. -> `src/components/docs/chat-app.tsx` ### 3. Document Search Full-text search with filtering and ranking. ->`src/components/docs/doc-search.tsx` *** ## API Endpoints ### 1. Documents * GET `/api/docs/list` – List all docs * GET `/api/docs/[docSlug]` – Get a specific doc * POST `/api/docs/search` – Search docs * POST `/api/docs/generate `– Generate a new doc ### 2. Chat * GET `/api/docs/[docSlug]/chat/history` – Get chat history * POST `/api/docs/[docSlug]/chat/generate` – Generate chat response *** ## Benefits of using Zendocs 1. **Personalized Documentation** – Users get answers based on your uploaded docs 2. **SEO on Autopilot** – New pages are generated and added to the sitemap automatically 3. **Fast Setup** – Just connect MongoDB, add environment variables, and you're ready *** ## How to Deploy ? ### Run Locally ```bash theme={null} npm install npm run dev # Start dev server npm run build # Production build ``` ### Testing ```bash theme={null} npm run insert-test-docs # Inserts test documents ``` ### Deployment Configured for Next.js hosting platforms. Default `port: 4163`. *** ## SEO & Performance * Automatic sitemap generation * Server-side rendering for better SEO * Optimized image loading * Response caching and metadata optimization *** ## Security * API route protection * MongoDB connection security * Input validation with Zod * XSS prevention & CORS configuration *** Star and look at the code # Get Started with Alchemyst Source: https://getalchemystai.com/docs/getting-started/index Add context or memory to your AI applications ## Choose Your Path Store documents and retrieve relevant information on demand. **Example:** AI answers "What's our refund policy?" from your documentation **Time:** 10 minutes Track user preferences and conversation history automatically. **Example:** Chatbot remembers "I'm vegan" across sessions **Time:** 15 minutes *** ## Start with Context, Add Memory Later 90% of users start with Context because it shows immediate value: 1. Store a document 2. Ask a question 3. Get accurate answers Add Memory when you need your AI to remember users across sessions. *** ## Ready to Build? Store docs • Search context • Build RAG apps Track users • Remember conversations • Personalize responses *** ## Need Help Deciding? Join our [Discord](https://dub.sh/context-community) - we'll help you choose the right approach. # Contextual AI Agent Source: https://getalchemystai.com/docs/getting-started/quickstart Build AI that answers from your documents in 10 minutes ## What You're Building An AI that answers questions using YOUR documents instead of guessing. **Before Alchemyst:** ```typescript theme={null} const answer = await llm.generate("What's our refund policy?"); // "I don't have information about your specific refund policy..." ❌ ``` **After Alchemyst:** ```typescript theme={null} const answer = await llm.generate("What's our refund policy?"); // "We offer a 30-day money back guarantee. Contact support@example.com..." ✅ ``` *** ## Prerequisites * Alchemyst account ([sign up](https://platform.getalchemystai.com/auth?utm_source=docs\&utm_campaign=contextual_ai_quickstart\&utm_medium=quickstart_article\&utm_content=prerequisites_signup_cta)) * Your `ALCHEMYST_AI_API_KEY` * Node.js 18+ or Python 3.9+ **Time to complete:** 10 minutes *** ## Step 1: Install ```bash npm theme={null} npm install @alchemystai/sdk ``` ```bash python theme={null} pip install alchemystai ``` *** ## Step 2: Initialize ```typescript TypeScript theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); ``` ```python Python theme={null} import os from alchemyst_ai import AlchemystAI client = AlchemystAI( api_key=os.environ.get("ALCHEMYST_AI_API_KEY") ) ``` *** ## Step 3: Store a Document ```typescript TypeScript theme={null} const result = await client.v1.context.add({ documents: [{ content: "Our refund policy: We offer a 30-day money back guarantee. Contact support@example.com to request a refund." }], context_type: 'resource', source: 'documentation', scope: 'internal' }); console.log(`✅ Stored ${result.documents?.length || 0} documents`); // Output: ✅ Stored 1 documents ``` ```python Python theme={null} result = client.v1.context.add( documents=[{ "content": "Our refund policy: We offer a 30-day money back guarantee. Contact support@example.com to request a refund." }], context_type="resource", source="documentation", scope="internal" ) print(f"✅ Stored {len(result.get('documents', []))} documents") # Output: ✅ Stored 1 documents ``` **What just happened:** * Your document was chunked into searchable pieces (\~500 word chunks) * Embeddings were generated automatically (vector representations) * Everything is indexed and ready to search **Verify it worked:** 1. Visit [platform.getalchemystai.com/context](https://platform.getalchemystai.com/context?utm_source=docs\&utm_campaign=contextual_ai_quickstart\&utm_medium=quickstart_article\&utm_content=verify_setup_context_link) 2. You should see your document listed 3. Click to view chunks and metadata *** ## Step 4: Search for Context ```typescript TypeScript theme={null} const userQuestion = "What's your refund policy?"; const { contexts } = await client.v1.context.search({ query: userQuestion, similarity_threshold: 0.7, scope: 'internal' }); console.log(`Found ${contexts?.length || 0} relevant chunks`); // Output: Found 1 relevant chunks console.log(contexts[0].content); // Output: "Our refund policy: We offer a 30-day money back guarantee..." ``` ```python Python theme={null} user_question = "What's your refund policy?" result = client.v1.context.search( query=user_question, similarity_threshold=0.7, scope="internal" ) contexts = result.contexts or [] print(f"Found {len(contexts)} relevant chunks") # Output: Found 1 relevant chunks print(contexts[0].content) # Output: "Our refund policy: We offer a 30-day money back guarantee..." ``` ### Understanding similarity\_threshold | Value | Meaning | When to Use | | ----- | ----------------- | ---------------------------------- | | `0.5` | Somewhat relevant | Exploratory searches, broad topics | | `0.7` | Relevant | **Start here** - good balance | | `0.9` | Very relevant | Precise matches, technical queries | **Tip:** Start at 0.7, lower to 0.5 if you get no results, raise to 0.9 if results are too broad. *** ## Step 5: Feed Context to Your LLM ```typescript TypeScript theme={null} import OpenAI from 'openai'; const openai = new OpenAI(); const prompt = contexts?.length ? `Context:\n${contexts.map(c => c.content).join('\n\n')}\n\nQuestion: ${userQuestion}` : userQuestion; const response = await openai.chat.completions.create({ model: "gpt-4", messages: [{ role: "user", content: prompt }] }); console.log(response.choices[0].message.content); // Output: "We offer a 30-day money back guarantee. To request a refund, contact support@example.com." ``` ```python Python theme={null} import openai if contexts: context_text = "\n\n".join([ctx.content for ctx in contexts]) prompt = f"Context:\n{context_text}\n\nQuestion: {user_question}" else: prompt = user_question response = openai.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}] ) print(response.choices[0].message.content) # Output: "We offer a 30-day money back guarantee. To request a refund, contact support@example.com." ``` **Result:** Your AI now answers from YOUR data, not generic training data. *** ## Complete Working Example ```typescript theme={null} import AlchemystAI from '@alchemystai/sdk'; import OpenAI from 'openai'; const alchemyst = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); const openai = new OpenAI(); async function main() { // 1. Store document await alchemyst.v1.context.add({ documents: [{ content: "Our refund policy: We offer a 30-day money back guarantee. Contact support@example.com to request a refund." }], context_type: 'resource', source: 'docs', scope: 'internal' }); console.log("✅ Document stored"); // 2. Search for context const userQuestion = "What's your refund policy?"; const { contexts } = await alchemyst.v1.context.search({ query: userQuestion, similarity_threshold: 0.7, scope: 'internal' }); console.log(`Found ${contexts?.length} relevant chunks`); // 3. Generate answer with context const prompt = contexts?.length ? `Context:\n${contexts.map(c => c.content).join('\n\n')}\n\nQuestion: ${userQuestion}` : userQuestion; const response = await openai.chat.completions.create({ model: "gpt-4", messages: [{ role: "user", content: prompt }] }); console.log("AI Response:", response.choices[0].message.content); } main(); ``` **Expected Output:** ``` ✅ Document stored Found 1 relevant chunks AI Response: We offer a 30-day money back guarantee. To request a refund, contact support@example.com. ``` ```python theme={null} import os from alchemyst_ai import AlchemystAI import openai alchemyst = AlchemystAI(api_key=os.environ.get("ALCHEMYST_AI_API_KEY")) def main(): # 1. Store document alchemyst.v1.context.add( documents=[{ "content": "Our refund policy: We offer a 30-day money back guarantee. Contact support@example.com to request a refund." }], context_type="resource", source="docs", scope="internal" ) print("✅ Document stored") # 2. Search for context user_question = "What's your refund policy?" result = alchemyst.v1.context.search( query=user_question, similarity_threshold=0.7, scope="internal" ) contexts = result.contexts or [] print(f"Found {len(contexts)} relevant chunks") # 3. Generate answer with context if contexts: context_text = "\n\n".join([ctx.content for ctx in contexts]) prompt = f"Context:\n{context_text}\n\nQuestion: {user_question}" else: prompt = user_question response = openai.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}] ) print("AI Response:", response.choices[0].message.content) if __name__ == "__main__": main() ``` **Expected Output:** ``` ✅ Document stored Found 1 relevant chunks AI Response: We offer a 30-day money back guarantee. To request a refund, contact support@example.com. ``` *** ## Next: Add Real Documents Now that you understand the basics, let's add real documents: ```typescript TypeScript theme={null} import fs from 'fs'; const content = fs.readFileSync('./docs/policy.txt', 'utf-8'); await client.v1.context.add({ documents: [{ content: content, metadata: { file_name: "policy.txt", file_type: "text" } }], context_type: 'resource', source: 'documentation', scope: 'internal' }); console.log("✅ File uploaded and indexed"); ``` ```python Python theme={null} with open('./docs/policy.txt', 'r') as f: content = f.read() client.v1.context.add( documents=[{ "content": content, "metadata": { "file_name": "policy.txt", "file_type": "text" } }], context_type="resource", source="documentation", scope="internal" ) print("✅ File uploaded and indexed") ``` ```typescript TypeScript theme={null} const response = await fetch('https://api.example.com/docs'); const apiDocs = await response.json(); const docs = apiDocs.map(doc => ({ content: doc.body, metadata: { file_name: doc.title, doc_id: doc.id } })); await client.v1.context.add({ documents: docs, context_type: 'resource', source: 'api', scope: 'internal' }); console.log(`✅ Indexed ${docs.length} documents from API`); ``` ```python Python theme={null} import requests response = requests.get('https://api.example.com/docs') api_docs = response.json() docs = [{ "content": doc["body"], "metadata": { "file_name": doc["title"], "doc_id": doc["id"] } } for doc in api_docs] client.v1.context.add( documents=docs, context_type="resource", source="api", scope="internal" ) print(f"✅ Indexed {len(docs)} documents from API") ``` ```typescript TypeScript theme={null} const docs = [ { content: "Refund policy: We offer a 30-day money back guarantee...", metadata: { file_name: "refunds.md" } }, { content: "Shipping policy: We ship worldwide within 5-7 business days...", metadata: { file_name: "shipping.md" } }, { content: "Privacy policy: We collect and protect your data...", metadata: { file_name: "privacy.md" } } ]; await client.v1.context.add({ documents: docs, context_type: 'resource', source: 'documentation', scope: 'internal' }); console.log(`✅ Indexed ${docs.length} policy documents`); ``` ```python Python theme={null} docs = [ { "content": "Refund policy: We offer a 30-day money back guarantee...", "metadata": {"file_name": "refunds.md"} }, { "content": "Shipping policy: We ship worldwide within 5-7 business days...", "metadata": {"file_name": "shipping.md"} }, { "content": "Privacy policy: We collect and protect your data...", "metadata": {"file_name": "privacy.md"} } ] client.v1.context.add( documents=docs, context_type="resource", source="documentation", scope="internal" ) print(f"✅ Indexed {len(docs)} policy documents") ``` *** ## Advanced: Organize with Metadata Use `group_name` to filter searches by category: ```typescript TypeScript theme={null} // Store with groups await client.v1.context.add({ documents: [{ content: "Refund policy: We offer a 30-day money back guarantee...", metadata: { file_name: "refund-policy.md", group_name: ["customer-support", "policies"] // ← For storage } }], context_type: 'resource', source: 'documentation', scope: 'internal' }); // Search within specific groups const { contexts } = await client.v1.context.search({ query: "refund policy", scope: 'internal', metadata: { groupName: ['customer-support'] // ← For search (note: camelCase) } }); console.log(`Found ${contexts?.length} results in customer-support`); ``` ```python Python theme={null} # Store with groups client.v1.context.add( documents=[{ "content": "Refund policy: We offer a 30-day money back guarantee...", "metadata": { "file_name": "refund-policy.md", "group_name": ["customer-support", "policies"] # ← For storage } }], context_type="resource", source="documentation", scope="internal" ) # Search within specific groups result = client.v1.context.search( query="refund policy", scope="internal", metadata={ "group_name": ["customer-support"] # ← For search (note: snake_case) } ) print(f"Found {len(result.contexts or [])} results in customer-support") ``` **Naming difference:** Storage uses `group_name` (snake\_case in metadata) but TypeScript search uses `groupName` (camelCase). Python uses `group_name` consistently. Both refer to the same field - this is due to API design conventions. ### Why use groups? | Benefit | Description | | ----------------------- | ------------------------------------------------------- | | **Faster searches** | Smaller search space = lower latency | | **More relevant** | Only search customer-support docs, not engineering docs | | **Better organization** | Hierarchical structure like folders | | **Access control** | Filter by team, project, or user permissions | **Example hierarchy:** ```typescript theme={null} group_name: ["company", "customer-support", "policies"] group_name: ["company", "engineering", "api-docs"] group_name: ["company", "hr", "employee-handbook"] ``` Learn more: [Context Arithmetic](/docs/advanced/context-arithmetic) *** ## Troubleshooting **Error symptoms:** * `contexts?.length` returns 0 * Empty array in search results **Common causes:** 1. `similarity_threshold` is too high 2. Document wasn't stored successfully 3. `scope` mismatch between add and search **Fixes:** **Step 1: Lower the threshold:** ```typescript theme={null} similarity_threshold: 0.5 // Instead of 0.9 ``` **Step 2: Verify documents were stored:** ```typescript theme={null} const stored = await client.v1.context.view(); console.log("Total documents:", stored.length); console.log("Documents:", stored); ``` **Expected output:** ``` Total documents: 1 Documents: [{ id: "doc_123", content: "Our refund policy...", ... }] ``` **Step 3: Check scope matches:** ```typescript theme={null} // Both must use the same scope await client.v1.context.add({ scope: 'internal', ... }); await client.v1.context.search({ scope: 'internal', ... }); // ✅ Match ``` **Error symptoms:** * Getting documents that don't match the query * Too many results to process efficiently **Common causes:** 1. `similarity_threshold` is too low 2. Documents are too broad or generic 3. Not using group filtering **Fixes:** **Step 1: Raise the threshold:** ```typescript theme={null} similarity_threshold: 0.8 // More strict (was 0.5) ``` **Step 2: Use group filtering:** ```typescript theme={null} metadata: { groupName: ['customer-support'] // Narrow to specific category } ``` **Step 3: Add more specific metadata:** ```typescript theme={null} await client.v1.context.add({ documents: [{ content: "...", metadata: { group_name: ["support", "refunds"], // More specific category: "policies", department: "customer-service" } }] }); ``` **Error message:** ```json theme={null} { "error": "Document with file_name 'policy.md' already exists", "code": "CONFLICT", "status": 409 } ``` **Cause:** Trying to add a document with duplicate `file_name` in metadata. **Fixes:** **Step 1: Delete old version first:** ```typescript theme={null} // Delete by file name await client.v1.context.delete({ metadata: { fileName: "policy.md" } }); // Then add new version await client.v1.context.add({ documents: [{ content: "Updated content...", metadata: { file_name: "policy.md" } }] }); ``` **Step 2: Use versioned names:** ```typescript theme={null} file_name: "policy-v2.md" // or "policy-2024-02-01.md" ``` **Step 3: Use unique identifiers:** ```typescript theme={null} file_name: `policy-${Date.now()}.md` // Timestamp // or file_name: `policy-${uuid()}.md` // UUID ``` **Error message:** ```json theme={null} { "error": "Invalid API key", "code": "UNAUTHORIZED", "status": 401 } ``` **Fixes:** **Step 1: Verify API key is set:** ```typescript theme={null} console.log("API Key exists:", !!process.env.ALCHEMYST_AI_API_KEY); // Should output: API Key exists: true ``` **Step 2: Check key format:** ```typescript theme={null} // Should start with "alch_" or similar prefix console.log("Key prefix:", process.env.ALCHEMYST_AI_API_KEY?.substring(0, 5)); ``` **Step 3: Get a new key:** * Visit [platform.getalchemystai.com/settings](https://platform.getalchemystai.com/settings?utm_source=docs\&utm_campaign=contextual_ai_quickstart\&utm_medium=quickstart_article\&utm_content=troubleshooting_api_key_settings) * Generate a new API key * Update your `.env` file **Error message:** ```json theme={null} { "error": "Rate limit exceeded", "code": "RATE_LIMIT", "status": 429, "retry_after": 60 } ``` **Cause:** Too many requests in a short time period. **Fixes:** **Step 1: Add retry logic:** ```typescript theme={null} async function searchWithRetry(query: string, retries = 3) { for (let i = 0; i < retries; i++) { try { return await client.v1.context.search({ query, scope: 'internal' }); } catch (error) { if (error.status === 429 && i < retries - 1) { const waitTime = error.retry_after || 60; console.log(`Rate limited. Waiting ${waitTime}s...`); await new Promise(resolve => setTimeout(resolve, waitTime * 1000)); } else { throw error; } } } } ``` **Step 2: Check your rate limits:** * Free tier: 100 operations/day * Pro tier: 10,000 operations/day **Step 3: Upgrade your plan:** [View pricing](https://platform.getalchemystai.com/settings/billing?utm_source=docs\&utm_campaign=contextual_ai_quickstart\&utm_medium=quickstart_article\&utm_content=troubleshooting_rate_limit_billing) *** ## Best Practices ### Document Organization ```typescript theme={null} // ✅ Good - organized with meaningful metadata await client.v1.context.add({ documents: [{ content: "...", metadata: { file_name: "refund-policy-2024-02.md", group_name: ["customer-support", "policies"], department: "support", last_updated: "2024-02-01" } }] }); // ❌ Bad - minimal metadata, hard to search await client.v1.context.add({ documents: [{ content: "..." }] }); ``` ### Chunk Size Considerations * **Small documents** (under 1000 words): Add as-is * **Medium documents** (1000-5000 words): Let Alchemyst auto-chunk * **Large documents** (over 5000 words): Consider splitting by section ```typescript theme={null} // For large documents, split manually for better control const sections = [ { title: "Introduction", content: "..." }, { title: "Features", content: "..." }, { title: "Pricing", content: "..." } ]; const docs = sections.map(section => ({ content: section.content, metadata: { file_name: "product-docs.md", section: section.title } })); await client.v1.context.add({ documents: docs }); ``` ### Search Optimization ```typescript theme={null} // ✅ Good - specific query with filtering const { contexts } = await client.v1.context.search({ query: "How to request a refund for damaged items", scope: 'internal', similarity_threshold: 0.7, metadata: { groupName: ['customer-support', 'refunds'] } }); // ❌ Bad - too broad, no filtering const { contexts } = await client.v1.context.search({ query: "help", scope: 'internal' }); ``` ### Error Handling ```typescript theme={null} async function safeSearch(query: string) { try { const { contexts } = await client.v1.context.search({ query, scope: 'internal', similarity_threshold: 0.7 }); if (!contexts || contexts.length === 0) { console.log("No results found. Try a broader query."); return null; } return contexts; } catch (error) { console.error("Search failed:", error.message); // Fallback or retry logic here return null; } } ``` *** ## Verify Your Setup After implementing context search, verify everything is working: ### Check Platform UI 1. Visit [platform.getalchemystai.com/context](https://platform.getalchemystai.com/context?utm_source=docs\&utm_campaign=contextual_ai_quickstart\&utm_medium=quickstart_article\&utm_content=verify_setup_ui_check) 2. You should see your stored documents 3. Click to view chunks and embeddings 4. Check document count matches what you uploaded ### Test with Code ```typescript theme={null} // Test the complete flow async function testSetup() { // 1. Store a test document console.log("Step 1: Storing test document..."); await client.v1.context.add({ documents: [{ content: "Test document: The answer is 42", metadata: { file_name: "test.txt" } }], scope: 'internal' }); // 2. Search for it console.log("Step 2: Searching for test document..."); const { contexts } = await client.v1.context.search({ query: "What is the answer?", scope: 'internal', similarity_threshold: 0.5 }); // 3. Verify results const found = contexts?.some(c => c.content.includes("42")); console.log("✅ Test passed:", found); // 4. Cleanup console.log("Step 3: Cleaning up..."); await client.v1.context.delete({ metadata: { fileName: "test.txt" } }); } testSetup(); ``` **Expected Output:** ``` Step 1: Storing test document... Step 2: Searching for test document... ✅ Test passed: true Step 3: Cleaning up... ``` *** ## What's Next? Make your AI remember users across sessions Complete TypeScript SDK reference Complete Python SDK reference REST API documentation ### Learn Advanced Patterns Master advanced filtering and organization Best practices and anti-patterns Customer support, code assistants, and more Community-built projects *** ## Need Help? Get real-time help from our community Browse guides and tutorials Contact our support team Report bugs or request features # Memory enabled Agent Source: https://getalchemystai.com/docs/getting-started/quickstart-memory Build a RAG Agent enabled memory that remembers users across sessions in 15 minutes ## What You're Building An AI that remembers user preferences and past conversations automatically. **Without Memory:** ```typescript theme={null} // Day 1 await llm.generate("I'm vegan and allergic to peanuts"); // Day 2 await llm.generate("Give me a recipe"); // AI: "What dietary restrictions do you have?" ❌ ``` **With Memory:** ```typescript theme={null} // Day 1 await generateWithMemory({ prompt: "I'm vegan", userId: "alice" }); // Day 2 await generateWithMemory({ prompt: "Give me a recipe", userId: "alice" }); // AI: "Here's a vegan recipe: ..." ✅ Remembered automatically ``` *** ## Prerequisites * Alchemyst account ([sign up](https://platform.getalchemystai.com/auth?utm_source=docs\&utm_campaign=memory_agent_quickstart\&utm_medium=quickstart_article\&utm_content=prerequisites_signup_cta)) * Your `ALCHEMYST_AI_API_KEY` * Node.js 18+ or Python 3.9+ **Time to complete:** 15 minutes *** ## Choose Your Approach **Best for:** Next.js, React, Node.js apps Uses Vercel AI SDK wrapper for automatic memory management. ```bash theme={null} npm install ai @alchemystai/aisdk ``` **Best for:** FastAPI, Django, Flask apps Uses direct SDK with manual memory management (more control). ```bash theme={null} pip install alchemystai openai ``` *** ## Quick Start: TypeScript ### Step 1: Set Up Memory ```typescript theme={null} import { generateText } from 'ai'; import { withAlchemyst } from '@alchemystai/aisdk'; // Wrap AI SDK with automatic memory const generateTextWithMemory = withAlchemyst(generateText, { apiKey: process.env.ALCHEMYST_AI_API_KEY, }); ``` **What this does:** 1. Retrieves past conversations for this user 2. Includes them in the prompt automatically 3. Stores the new conversation ### Step 2: Use Memory ```typescript theme={null} // First conversation: User shares preference const response1 = await generateTextWithMemory({ model: "openai:gpt-4", prompt: "I'm vegan and allergic to peanuts", userId: "alice", sessionId: "profile_setup" }); console.log(response1.text); // Output: "Got it! I'll remember you're vegan and have a peanut allergy." // Later: Different session, AI remembers const response2 = await generateTextWithMemory({ model: "openai:gpt-4", prompt: "Give me a dinner recipe", userId: "alice", sessionId: "cooking_monday" }); console.log(response2.text); // Output: "Here's a vegan stir-fry without peanuts: ..." // ✅ Remembered from different conversation! ``` **Memory works across:** * Different sessions (profile\_setup → cooking\_monday) * Different topics (preferences → recipes) * Days or weeks apart ### Complete TypeScript Example ```typescript theme={null} import { generateText } from 'ai'; import { withAlchemyst } from '@alchemystai/aisdk'; const generateTextWithMemory = withAlchemyst(generateText, { apiKey: process.env.ALCHEMYST_AI_API_KEY, }); async function main() { // Day 1: Learn preference const response1 = await generateTextWithMemory({ model: "openai:gpt-4", prompt: "I love science fiction movies", userId: "bob", sessionId: "preferences" }); console.log("AI:", response1.text); // Output: "Great! I'll remember you enjoy sci-fi films." // Day 2: Use preference const response2 = await generateTextWithMemory({ model: "openai:gpt-4", prompt: "Recommend a movie", userId: "bob", sessionId: "movie_night" }); console.log("AI:", response2.text); // Output: "How about Interstellar? You mentioned you love sci-fi." } main(); ``` **Verify it worked:** 1. Visit [platform.getalchemystai.com/context](https://platform.getalchemystai.com/context?utm_source=docs\&utm_campaign=memory_agent_quickstart\&utm_medium=quickstart_article\&utm_content=verify_setup_context_link) 2. You should see stored conversations for user "bob" 3. Click to view memory contents *** ## Quick Start: Python ### Step 1: Simple Example (Recommended) Start with this simplified version to understand the basics: ```python theme={null} import os from alchemyst_ai import AlchemystAI alchemyst = AlchemystAI(api_key=os.environ.get("ALCHEMYST_AI_API_KEY")) # Store a memory alchemyst.v1.context.memory.add({ "user_id": "alice", "session_id": "preferences", "content": "User said: I'm vegan and allergic to peanuts" }) print("✅ Memory stored!") # Later: Retrieve memories result = alchemyst.v1.context.memory.search( user_id="alice", session_id="preferences" ) if result and hasattr(result, 'memories'): for memory in result.memories: print(f"Found: {memory.content}") # Output: Found: User said: I'm vegan and allergic to peanuts ``` **Expected Output:** ``` ✅ Memory stored! Found: User said: I'm vegan and allergic to peanuts ``` ### Step 2: Full Integration with OpenAI Now integrate with OpenAI for complete chat functionality: ```python theme={null} import os from alchemyst_ai import AlchemystAI import openai alchemyst = AlchemystAI(api_key=os.environ.get("ALCHEMYST_AI_API_KEY")) openai_client = openai.OpenAI() def chat_with_memory(prompt: str, user_id: str, session_id: str): """Chat function that remembers past conversations""" # 1. Get past conversations memory = alchemyst.v1.context.memory.search( user_id=user_id, session_id=session_id, limit=10 ) # 2. Build message history messages = [{"role": "system", "content": "You are a helpful assistant."}] # Add past memories to context if memory and hasattr(memory, 'memories'): for mem in memory.memories: if hasattr(mem, 'content'): messages.append({"role": "assistant", "content": mem.content}) # Add current prompt messages.append({"role": "user", "content": prompt}) # 3. Generate response with full context response = openai_client.chat.completions.create( model="gpt-4", messages=messages ) assistant_message = response.choices[0].message.content # 4. Store this conversation for next time alchemyst.v1.context.memory.add({ "user_id": user_id, "session_id": session_id, "content": f"User: {prompt}\nAssistant: {assistant_message}" }) return assistant_message # Test it response = chat_with_memory( prompt="I'm vegan", user_id="alice", session_id="profile" ) print(response) # Output: "Got it! I'll remember you're vegan." response2 = chat_with_memory( prompt="Give me a recipe", user_id="alice", session_id="cooking" ) print(response2) # Output: "Here's a vegan pasta recipe: ..." ``` **Expected Output:** ``` Got it! I'll remember you're vegan. Here's a vegan pasta recipe: ... ``` *** ## Understanding userId and sessionId These two parameters control memory scope: ```typescript theme={null} await generateTextWithMemory({ prompt: "...", userId: "alice", // WHO is talking sessionId: "cooking" // WHAT conversation thread }); ``` ### Real-World Examples | Use Case | userId | sessionId | Why | | ------------------ | -------------- | --------------------------- | ------------------------------------- | | Customer support | `customer_123` | `ticket_456` | Track support history per customer | | Personal assistant | `user_alice` | `daily_planning_2024_02_01` | Separate daily planning sessions | | Team collaboration | `user_bob` | `project_alpha_sprint_3` | Isolate project discussions by sprint | | Multi-user chat | `user_charlie` | `team_standup_2024_w05` | Group conversations by topic and time | **Pro Tip:** Use descriptive sessionIds like `"recipe_planning_2024_02"` instead of `"session_1"` for easier debugging and analytics. **Rule:** Same `userId` + same `sessionId` = same conversation thread *** ## Advanced Features ### Stream Responses with Memory For real-time chat experiences: ```typescript theme={null} import { streamText } from 'ai'; import { withAlchemyst } from '@alchemystai/aisdk'; const streamTextWithMemory = withAlchemyst(streamText, { apiKey: process.env.ALCHEMYST_AI_API_KEY, }); async function streamChat() { const { textStream } = await streamTextWithMemory({ model: "openai:gpt-4", prompt: "Tell me about quantum mechanics", userId: "user_123", sessionId: "physics_101" }); // Process stream chunk by chunk for await (const chunk of textStream) { process.stdout.write(chunk); } } streamChat(); ``` **Expected Output:** ``` Quantum mechanics is the branch of physics... [streams in real-time] ``` ```python theme={null} def chat_with_memory_streaming(prompt: str, user_id: str, session_id: str): """Stream responses while remembering context""" # Get past conversations memory = alchemyst.v1.context.memory.search( user_id=user_id, session_id=session_id, limit=10 ) messages = [{"role": "system", "content": "You are a helpful assistant."}] if memory and hasattr(memory, 'memories'): for mem in memory.memories: if hasattr(mem, 'content'): messages.append({"role": "assistant", "content": mem.content}) messages.append({"role": "user", "content": prompt}) # Stream response stream = openai_client.chat.completions.create( model="gpt-4", messages=messages, stream=True ) full_response = "" for chunk in stream: if chunk.choices[0].delta.content: content = chunk.choices[0].delta.content print(content, end="", flush=True) full_response += content # Store complete conversation alchemyst.v1.context.memory.add({ "user_id": user_id, "session_id": session_id, "content": f"User: {prompt}\nAssistant: {full_response}" }) return full_response # Usage response = chat_with_memory_streaming( prompt="Tell me about quantum mechanics", user_id="user_123", session_id="physics_101" ) ``` **Expected Output:** ``` Quantum mechanics is the branch of physics... [streams in real-time] ``` *** ### Manage Memory Update or delete conversations as needed: ```typescript theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); // Update specific memory await client.v1.context.memory.update({ userId: "alice", sessionId: "profile_setup", messageId: "msg_001", content: "Updated: I'm vegan and gluten-free" }); // Delete a specific conversation await client.v1.context.memory.delete({ userId: "alice", sessionId: "profile_setup" }); // Delete ALL memories for a user (use with caution!) await client.v1.context.memory.delete({ userId: "alice" }); console.log("✅ Memory updated/deleted"); ``` ```python theme={null} # Update specific memory alchemyst.v1.context.memory.update( user_id="alice", session_id="profile_setup", message_id="msg_001", content="Updated: I'm vegan and gluten-free" ) # Delete a specific conversation alchemyst.v1.context.memory.delete( user_id="alice", session_id="profile_setup" ) # Delete ALL memories for a user (use with caution!) alchemyst.v1.context.memory.delete( user_id="alice" ) print("✅ Memory updated/deleted") ``` *** ### Multi-User Conversations Handle group chats where multiple users participate in the same thread: ```typescript theme={null} // User 1 starts discussion await generateTextWithMemory({ model: "openai:gpt-4", prompt: "What are React hooks best practices?", userId: "alice", sessionId: "team_discussion_001" }); // User 2 joins same discussion await generateTextWithMemory({ model: "openai:gpt-4", prompt: "Can you elaborate on useEffect?", userId: "bob", sessionId: "team_discussion_001" // ← Same session = shared context }); // User 1 continues - AI has full thread context await generateTextWithMemory({ model: "openai:gpt-4", prompt: "What about custom hooks?", userId: "alice", sessionId: "team_discussion_001" }); // AI has full thread context regardless of who asks ``` ```python theme={null} # User 1 starts discussion chat_with_memory( prompt="What are React hooks best practices?", user_id="alice", session_id="team_discussion_001" ) # User 2 joins same discussion chat_with_memory( prompt="Can you elaborate on useEffect?", user_id="bob", session_id="team_discussion_001" # ← Same session = shared context ) # User 1 continues - AI has full thread context chat_with_memory( prompt="What about custom hooks?", user_id="alice", session_id="team_discussion_001" ) # AI has full thread context regardless of who asks ``` **Key insight:** Using the same `sessionId` across different `userId` values creates a shared memory space for team conversations. *** ## Configuration Options Customize memory retrieval and storage behavior: ```typescript theme={null} const generateTextWithMemory = withAlchemyst(generateText, { apiKey: process.env.ALCHEMYST_AI_API_KEY, // Memory retrieval settings similarityThreshold: 0.8, // How relevant (0-1) minimumSimilarityThreshold: 0.5, // Absolute minimum cutoff scope: 'internal', // 'internal' | 'external' // Storage settings contextType: 'conversation', source: 'chat-app', // Organization (optional) metadata: { groupName: ['production', 'app-v2'], environment: 'production', version: '2.0' }, }); ``` ```python theme={null} def chat_with_memory( prompt: str, user_id: str, session_id: str, similarity_threshold: float = 0.8, min_similarity_threshold: float = 0.5, scope: str = 'internal' ): memory = alchemyst.v1.context.memory.search( user_id=user_id, session_id=session_id, similarity_threshold=similarity_threshold, minimum_similarity_threshold=min_similarity_threshold, scope=scope, limit=10 ) # ... rest of implementation ``` ### Configuration Reference | Parameter | Value | When to Use | | ------------------------------ | ------------ | ---------------------------------- | | **similarityThreshold** | `0.5` | Broad, exploratory searches | | | `0.7` | **Recommended default** - balanced | | | `0.9` | Precise matches only | | **minimumSimilarityThreshold** | `0.5` | Never return results below this | | **scope** | `'internal'` | Your app's private data | | | `'external'` | Public/shared knowledge | **Recommendation:** Start with `similarityThreshold: 0.7`. Lower to 0.5 if you get no results, raise to 0.9 if results are too broad. *** ## Troubleshooting **Error Message:** ```json theme={null} { "error": "userId and sessionId are required", "code": "MISSING_PARAMETERS" } ``` **Cause:** Both parameters are required for memory operations. **Fix:** Always provide both: ```typescript theme={null} await generateTextWithMemory({ model: "openai:gpt-4", prompt: "Hello", userId: "user_123", // ✅ Required sessionId: "chat_456" // ✅ Required }); ``` **Symptoms:** AI doesn't remember past conversations. **Causes:** 1. Threshold too high 2. Wrong userId/sessionId 3. Memory wasn't stored correctly **Fixes:** **1. Lower threshold:** ```typescript theme={null} similarityThreshold: 0.6 // Instead of 0.9 ``` **2. Verify exact same IDs:** ```typescript theme={null} // IDs must match EXACTLY (case-sensitive) userId: "user_123" // ❌ Not "user_124" or "User_123" sessionId: "chat_456" // ❌ Not "chat_457" or "Chat_456" ``` **3. Test retrieval directly:** ```typescript theme={null} const memories = await client.v1.context.memory.search({ userId: "user_123", sessionId: "chat_456" }); console.log("Found memories:", memories.memories?.length); console.log("Memory content:", memories.memories); ``` **Expected Output:** ``` Found memories: 2 Memory content: [ { content: "User: I'm vegan\nAssistant: Got it!" }, { content: "User: Give me a recipe\nAssistant: Here's a vegan..." } ] ``` **Symptoms:** AI references unrelated past conversations or gets confused. **Causes:** 1. Threshold too low 2. Mixing unrelated conversations in same session **Fixes:** **1. Raise threshold:** ```typescript theme={null} similarityThreshold: 0.85 // More strict ``` **2. Use separate sessions by topic:** ```typescript theme={null} // ✅ Good - separate by topic sessionId: "physics_homework" sessionId: "cooking_recipes" sessionId: "movie_recommendations" // ❌ Bad - everything mixed sessionId: "general_chat" ``` **3. Limit memory retrieval:** ```typescript theme={null} // Only retrieve last 5 memories instead of 10 limit: 5 ``` **Error Message:** ```json theme={null} { "error": "Failed to store memory", "code": "STORAGE_ERROR" } ``` **Common Causes:** 1. Invalid API key 2. Rate limit exceeded 3. Content too large **Fixes:** **1. Verify API key:** ```typescript theme={null} console.log("API Key set:", !!process.env.ALCHEMYST_AI_API_KEY); // Should output: API Key set: true ``` **2. Check rate limits:** * Free tier: 100 operations/day * Pro tier: Unlimited **3. Reduce content size:** ```typescript theme={null} // Keep memory entries under 10KB each const content = longText.slice(0, 10000); // Truncate if needed ``` *** ## Best Practices ### 1. Session Naming Convention ```typescript theme={null} // ✅ Good - descriptive and structured sessionId: "support_ticket_2024_02_001" sessionId: "recipe_planning_vegan_week_5" sessionId: "project_alpha_sprint_3_planning" // ❌ Bad - hard to debug sessionId: "session1" sessionId: "chat" sessionId: "abc123" ``` ### 2. Memory Retention Limits ```typescript theme={null} // ✅ Good - limit memory lookback limit: 10 // Last 10 conversations // ❌ Bad - retrieving everything limit: 1000 // Too much context, slows down LLM ``` ### 3. Privacy-Aware Memory ```typescript theme={null} // Store memories with appropriate scope const generateTextWithMemory = withAlchemyst(generateText, { apiKey: process.env.ALCHEMYST_AI_API_KEY, scope: 'internal', // ✅ Private user data metadata: { dataClassification: 'PII', // Track sensitive data retentionPolicy: '90days' } }); ``` ### 4. Error Handling ```typescript theme={null} // ✅ Good - handle failures gracefully try { const response = await generateTextWithMemory({ model: "openai:gpt-4", prompt: userInput, userId: user.id, sessionId: conversation.id }); return response.text; } catch (error) { console.error("Memory error:", error); // Fallback: Generate without memory return await generateText({ model: "openai:gpt-4", prompt: userInput }); } ``` *** ## Verify Your Setup After implementing memory, verify it's working: ### 1. Check Platform UI 1. Visit [platform.getalchemystai.com/context](https://platform.getalchemystai.com/context?utm_source=docs\&utm_campaign=memory_agent_quickstart\&utm_medium=quickstart_article\&utm_content=verify_setup_ui_check) 2. Filter by your userId 3. You should see stored memories with timestamps 4. Click to view conversation content ### 2. Test with Code ```typescript theme={null} // Store a test memory await client.v1.context.memory.add({ userId: "test_user", sessionId: "test_session", content: "Test memory: The user likes pizza" }); // Retrieve it immediately const result = await client.v1.context.memory.search({ userId: "test_user", sessionId: "test_session" }); console.log("Test passed:", result.memories?.length === 1); // Expected Output: Test passed: true ``` *** ## What's Next? Combine memory with document search for powerful RAG Deep dive into AI SDK integration Complete API reference for TypeScript Complete API reference for Python ### Learn Advanced Patterns Build rich user profiles from memory Customer support, personal assistants, chatbots Complete REST API documentation Community-built memory applications *** ## Need Help? Get real-time help from our community Browse guides and API references Contact our support team Report bugs or request features # Introduction - Alchemyst AI Docs Source: https://getalchemystai.com/docs/index The universal context layer for your AI stack. Choose a path to start building.

Alchemyst

AI

Getting started with the ONLY AI-native context layer - scalable, powerful and flexible, with you in control.

Give conversational memory to your AI tools instantly. **No coding required.** Build context-aware agents with your favourite tech stack in minutes.

Developer Resources

Integrate context into the tools and frameworks you already use.

Getting started

Sign up at [**Alchemyst Platform**](https://platform.getalchemystai.com/auth?utm_source=docs\&utm_campaign=getting_started\&utm_medium=welcome_page\&utm_content=getting_started_link) and grab your secret key from the dashboard. ```bash theme={null} npm install @alchemystai/sdk ``` ```bash theme={null} pip install alchemystai ``` Push data to your namespace to make it immediately available to your agents. Native support for **LangChain, LlamaIndex, Agno,** and **Vercel AI SDK**. Connect Alchemyst as an **MCP Server** to Cursor, Claude Desktop, and VS Code. Learn the exact endpoints behind the Alchemyst AI Platform Blueprints for newsletter generators, support bots, and research agents.

Need help?

Join our community to share your projects or get technical support.

Connect with the community. Request new features or report issues.
# Anthropic Source: https://getalchemystai.com/docs/integrations/context-proxy/anthropic Proxy server for routing requests to Anthropic's LLM API ## Why use the proxy server ? By simply changing the `baseURL`, you can instantly add a memory layer to your LLM calls without altering your existing code. The proxy automatically handles storing and retrieving context across conversations, making your LLM smarter and more context-aware. Instead of managing memory, state, or custom logic in your app, the proxy does the heavy lifting, so your model responses feel coherent, continuous, and truly conversational. ## Get the AlchemystAI API key. Sign up and get you api key here : [Alchemyst platform](https://platform.getalchemystai.com/). Set your API key via environment variable or pass it directly when initializing the anthropic client. * Recommended env var: `ALCHEMYST_AI_API_KEY` ```bash theme={null} export ALCHEMYST_AI_API_KEY="your_api_key_here" ``` ## Quickstart ```ts theme={null} import Anthropic from '@anthropic-ai/sdk'; const anthropicURL = "https://api.anthropic.com" ; const anthropic = new Anthropic({ apiKey: process.env.ALCHEMYST_AI_API_KEY, baseURL: `https://platform-backend.getalchemystai.com/api/v1/proxy/${anthropicURL}/${ANTHROPIC_API_KEY}`, }); async function main() { const msg = await anthropic.messages.create({ model: 'claude-sonnet-4-5', max_tokens: 256, messages: [{ role: 'user', content: 'Hello, I am message via proxy llm.' }], }); } ``` # OpenAI Source: https://getalchemystai.com/docs/integrations/context-proxy/openai Proxy server for routing requests to OpenAI LLM API ## Why use the proxy server ? By simply changing the `baseURL`, you can instantly add a memory layer to your LLM calls without altering your existing code. The proxy automatically handles storing and retrieving context across conversations, making your LLM smarter and more context-aware. Instead of managing memory, state, or custom logic in your app, the proxy does the heavy lifting, so your model responses feel coherent, continuous, and truly conversational. ## Get the AlchemystAI API key. Sign up and get you api key here : [Alchemyst platform](https://platform.getalchemystai.com/). Set your API key via environment variable or pass it directly when initializing the anthropic client. * Recommended env var: `ALCHEMYST_AI_API_KEY` ```bash theme={null} export ALCHEMYST_AI_API_KEY="your_api_key_here" ``` ## Quickstart ```ts theme={null} import OpenAI from "openai"; const openaiURL = "https://api.openai.com/v1"; const client = new OpenAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, baseURL: `https://platform-backend.getalchemystai.com/api/v1/proxy/${openaiURL}/${process.env.OPENAI_API_KEY}`, }); async function main() { const completion = await client.chat.completions.create({ model: "gpt-4o-mini", messages: [ { role: "system", content: "Help me with the questions." }, { role: "user", content: "Hello, can you summarize how this proxy works?" }, ], }); console.log("Response from OpenAI via proxy:"); console.log(completion.choices[0].message); } main().catch(console.error); ``` # Amazon S3 Source: https://getalchemystai.com/docs/integrations/data-sources/cloud-storage/amazon-s3 Connect Amazon S3 to your Alchemyst context layer ## Introduction Amazon S3 (Simple Storage Service) is the industry-standard object storage platform, commonly used for document archives, media libraries, data lakes, and backups. With Alchemyst's [Amazon S3 integration](https://platform.getalchemystai.com/integrations?utm_source=getalchemystai.com\&utm_campaign=docs\&utm_medium=web), you can sync entire buckets, search semantically across documents and media, and keep your agent's knowledge synchronized with your storage. Your agent sees files as meaning, not just bytes. *** ## Why Connect Amazon S3? Traditional file-based workflows break down because: * Files are scattered across services * Manual operations are error-prone * Large files exceed context windows * There's no way to query across files semantically With Alchemyst's S3 integration, your files sync directly into your context layer, enabling seamless access to all your stored content. *** ## How to Connect **Prerequisites:** * AWS account with S3 access * S3 bucket with files to sync * IAM credentials with read permissions **What You Need:** * Bucket Name (S3 bucket identifier) * AWS Access Key ID (IAM user access key) * AWS Secret Access Key (IAM user secret key) * Region (AWS region, e.g., `us-east-1`) * Prefix/Folder (optional path filter) *** ## What Gets Indexed Alchemyst can index: **Documents:** * PDF, DOCX, PPTX, TXT, MD **Data:** * CSV, JSON, JSONL, XML, Parquet, YAML **Images:** * PNG, JPG, SVG (with OCR and vision models) **Code:** * All text-based source files *** ## IAM Permissions Create a dedicated IAM user with read-only S3 access. Grant only the following permissions to the specific buckets you want to sync: * `s3:GetObject` - Read objects from the bucket * `s3:ListBucket` - List objects in the bucket **Example IAM Policy:** ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*" ] } ] } ``` *** ## Security Best Practices For Amazon S3 integrations: * Use IAM roles instead of access keys when possible * Grant only read-only permissions * Enable bucket encryption (SSE-S3 or SSE-KMS) * Restrict public access to sensitive buckets * Use HTTPS-only access policies * Enable S3 access logging to monitor activity * Rotate credentials regularly * Use bucket policies to enforce encryption in transit * Enable versioning for critical data *** ## Performance & Cost Optimization **Sync Strategies:** * **Full Sync:** For small buckets with static content * **Incremental Sync:** For large buckets with frequent updates * **Event-Driven:** For real-time updates using S3 event notifications **Cost Reduction:** * Use S3 Intelligent-Tiering for infrequent access * Set lifecycle policies to archive old files * Limit sync frequency for static content * Use prefix filters to avoid listing entire buckets * Filter by file type to exclude unnecessary files * Monitor data transfer costs and optimize accordingly *** ## Prefix Filtering Use the Prefix/Folder field to sync only specific directories within your bucket: * Leave empty to sync the entire bucket * Use `documents/` to sync only the documents folder * Use `data/2024/` to sync a specific year's data * Combine with file type filters for precise control *** ## Next Steps Once Amazon S3 is connected, you can: * Search across your files semantically * Combine cloud storage with databases and other sources * Enable real-time sync with webhooks * Process multimodal content (PDFs, images, CSVs, JSON) Explore other integrations: [Databases](/docs/integrations/data-sources/databases) or [Productivity & Documents](/docs/integrations/data-sources/docs). # MongoDB Integration Source: https://getalchemystai.com/docs/integrations/data-sources/databases/Mongodb Connect MongoDB databases to your Alchemyst context layer ## Overview MongoDB is a document-oriented NoSQL database, ideal for: * User profiles and account data * Content management systems * Event logs and analytics * Flexible schema applications ## Why Connect MongoDB? Traditional AI agents struggle with operational data because: * **Data changes constantly** - Static exports become outdated quickly * **Manual exports go stale** - Syncing requires constant maintenance * **Querying requires technical knowledge** - Non-technical users can't access data easily With Alchemyst MongoDB integration, you can: * Sync fresh data whenever context is needed * Search semantically across collections and documents * Combine database results with other data sources * Query in natural language without writing aggregation pipelines Your databases become queryable context that responds to meaning, not just raw data. *** ## Getting Started Database Integration Setup To connect MongoDB to Alchemyst: 1. Navigate to the [Alchemyst Integrations page](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=mongodb_docs\&utm_medium=web) 2. Click **Add Integration** → **MongoDB** 3. Provide your connection credentials 4. Configure which data to sync 5. Start querying your data with natural language *** ## Connection Requirements ### Prerequisites * MongoDB cluster (Atlas, self-hosted, or cloud provider) * Database user with read permissions * Network access to your MongoDB cluster ### Required Information * **Connection URL** - MongoDB connection string in format: ``` mongodb+srv://username:password@cluster.mongodb.net/database ``` * **Auth Source** (optional, defaults to `admin`) * **Database Name** - Specific database to index * **Cluster Name** (optional, for Atlas clusters) *** ## What Gets Indexed Alchemyst can index and make searchable: * **Collections** - All documents within specified collections * **Documents** - Individual records with all fields * **Aggregation Results** - Pipeline outputs and computed data * **Embedded Documents** - Nested data structures * **Array Fields** - List data and sub-documents *** ## How Data is Structured When you sync MongoDB collections, Alchemyst preserves your document structure while optimizing for search: ### Example Query Patterns ``` "Find all premium users in the US region" → Filters: metadata.accountType="premium", metadata.region="us-east" "What features do active users prefer?" → Semantic search across user preferences and activity data "Show recent user feedback" → Time-filtered search in feedback collection ``` *** ## How to Connect 1. Go to [Alchemyst Integrations](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=mongodb_setup\&utm_medium=web) 2. Click **Add Integration** → **MongoDB** 3. Enter your connection details: * MongoDB connection URI * Select collections to index 4. Test the connection 5. Configure sync settings 6. Save and activate the integration *** ## Connection String Examples ### MongoDB Atlas ``` mongodb+srv://user:password@cluster0.abc123.mongodb.net/mydb?retryWrites=true&w=majority ``` ### Self-Hosted MongoDB ``` mongodb://admin:password@localhost:27017/database?authSource=admin ``` ### MongoDB with Replica Set ``` mongodb://user:password@host1:27017,host2:27017,host3:27017/database?replicaSet=myReplicaSet ``` *** ## Best Practices * **Use read-only roles** - Create users with `read` role only * **Enable authentication** - Always use authenticated connections * **Use connection pooling** - Improve performance for large collections * **Filter collections** - Index only necessary data to reduce load * **Monitor queries** - Track slow operations and optimize as needed *** ## Security Best Practices ### Access Control * **Use read-only credentials** - Prevent accidental data modification * **Create dedicated service accounts** - Separate Alchemyst access from application users * **Apply principle of least privilege** - Grant access only to required collections ### Network Security * **Enable SSL/TLS encryption** - Protect data in transit * **Whitelist Alchemyst IPs** - Restrict database access by IP address * **Use private networks** - Connect via VPN or private peering when possible * **Enable firewall rules** - Block unauthorized access attempts *** **Ready to connect MongoDB?** Visit the [Alchemyst Integrations page](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=mongodb_cta\&utm_medium=web) to get started. # PostgreSQL Integration Source: https://getalchemystai.com/docs/integrations/data-sources/databases/Postgresql Connect PostgreSQL databases to your Alchemyst context layer ## Overview PostgreSQL is the most popular open-source relational database, commonly used for: * Customer records and CRM data * Product catalogs and inventory * Transaction logs and financial data * Application state and configuration ## Why Connect PostgreSQL? Traditional AI agents struggle with operational data because: * **Data changes constantly** - Static exports become outdated quickly * **Manual exports go stale** - Syncing requires constant maintenance * **Querying requires SQL knowledge** - Non-technical users can't access data easily With Alchemyst PostgreSQL integration, you can: * Sync fresh data whenever context is needed * Search semantically across tables and collections * Combine database results with other data sources * Query in natural language without writing SQL Your databases become queryable context that responds to meaning, not just raw data. *** ## Getting Started To connect PostgreSQL to Alchemyst: 1. Navigate to the [Alchemyst Integrations page](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=postgresql_docs\&utm_medium=web) 2. Click **Add Integration** → **PostgreSQL** 3. Provide your connection credentials 4. Configure which data to sync 5. Start querying your data with natural language *** ## Connection Requirements ### Prerequisites * PostgreSQL instance (local, cloud-hosted, or managed service) * Read-only database user (strongly recommended) * Network access to your PostgreSQL instance ### Required Information * **Connection String** - Full PostgreSQL URL in format: ``` postgresql://username:password@host:port/database ``` * **Username** (optional if included in URL) * **Password** (optional if included in URL) * **Database Name** (optional if included in URL) * **Port** (default: 5432) *** ## What Gets Indexed Alchemyst can index and make searchable: * **Tables** - All rows and columns from specified tables * **Views** - Materialized and regular views * **Query Results** - Custom SQL query outputs * **Schema Definitions** - Table structures and relationships * **Stored Procedures** - Procedure outputs and results *** ## How Data is Structured When you sync PostgreSQL tables, Alchemyst automatically structures your data for optimal retrieval: ### Example Query Patterns ``` "Show me all high-priority support tickets from last month" → Filters: groupName includes "support_tickets", metadata.priority="high" "Find customer payment issues" → Semantic search across content for payment-related problems "What's the resolution pattern for login errors?" → Retrieves similar resolved tickets and identifies common solutions ``` *** ## How to Connect 1. Go to [Alchemyst Integrations](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=postgresql_setup\&utm_medium=web) 2. Click **Add Integration** → **PostgreSQL** 3. Enter your connection details: * Connection string or individual credentials * Select tables or provide custom queries 4. Test the connection 5. Configure sync frequency and data filters 6. Save and activate the integration *** ## Connection String Examples ### Local PostgreSQL ``` postgresql://myuser:mypassword@localhost:5432/mydb ``` ### Cloud PostgreSQL (AWS RDS) ``` postgresql://admin:password@mydb.abc123.us-east-1.rds.amazonaws.com:5432/production ``` ### Google Cloud SQL ``` postgresql://user:password@/database?host=/cloudsql/project:region:instance ``` *** ## Best Practices * **Use read-only users** - Create a dedicated service account with `SELECT` permissions only * **Enable SSL/TLS** - Always use encrypted connections for production data * **Whitelist IPs** - Restrict database access to Alchemyst service IPs * **Index strategically** - Start with critical tables, expand as needed * **Monitor performance** - Watch for slow queries or high load *** ## Security Best Practices ### Access Control * **Use read-only credentials** - Prevent accidental data modification * **Create dedicated service accounts** - Separate Alchemyst access from application users * **Apply principle of least privilege** - Grant access only to required tables/collections ### Network Security * **Enable SSL/TLS encryption** - Protect data in transit * **Whitelist Alchemyst IPs** - Restrict database access by IP address * **Use private networks** - Connect via VPN or private peering when possible * **Enable firewall rules** - Block unauthorized access attempts *** **Ready to connect PostgreSQL?** Visit the [Alchemyst Integrations page](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=postgresql_cta\&utm_medium=web) to get started. # Google Docs Source: https://getalchemystai.com/docs/integrations/data-sources/docs/google-docs Connect Google Docs to your Alchemyst context layer ## Introduction Google Docs is the most popular collaborative document editor, commonly used for meeting notes, project documentation, SOPs, knowledge base articles, and onboarding guides. With Alchemyst's [Google Docs integration](https://platform.getalchemystai.com/integrations?utm_source=docs.getalchemystai.com\&utm_campaign=docs\&utm_medium=web), you can sync documents anytime you want, search semantically across all your docs, and share team knowledge across collaborators. Your agent sees documents as living knowledge, not static files. *** ## Why Connect Google Docs? Traditional document workflows fail because: * Documents are scattered across drives * Manual exports become stale immediately * There's no way to query across multiple docs * Collaboration happens outside agent context With Alchemyst's Google Docs integration, your documents sync directly into your context layer, enabling seamless collaboration and always up-to-date information. *** ## How to Connect **Prerequisites:** * Google Cloud Project * Service Account with Google Docs API access * Documents shared with the service account email **What You Need:** * Client Email (service account email address) * Private Key (from service account JSON key file) * Shared Document URL **Important:** You must share each document or folder with the service account email address. The service account needs at least Viewer permission to access the content. *** ## What Gets Indexed Alchemyst can index: * Document text * Formatting * Comments * Suggestions * Embedded images * Links * Version history *** ## Setting Up a Service Account 1. Go to Google Cloud Console and create or select a project 2. Enable Google Docs API 3. Navigate to IAM & Admin → Service Accounts 4. Create a new service account 5. Generate a JSON key file 6. Extract the `client_email` and `private_key` from the JSON **The JSON key file contains:** * `client_email`: Service account email (e.g., `service@project.iam.gserviceaccount.com`) * `private_key`: Full private key string (including header and footer) *** ## Security Best Practices For Google Docs integrations: * Use service accounts instead of OAuth for programmatic access * Store private keys in environment variables or secrets managers * Never commit private keys to version control * Rotate keys every 90 days * Grant only Viewer permissions to service accounts * Use folder-level sharing for easier management * Enable access logging in Google Workspace Admin Console * Monitor for unusual activity and set up alerts *** ## Version Tracking Google Docs change constantly. Alchemyst automatically tracks versions by removing old content when documents update and indexing new content, ensuring searches always return the latest information. *** ## Next Steps Once Google Docs is connected, you can: * Search across all your documents * Combine document data with databases and other sources * Keep your agent synchronized with team collaboration Explore other integrations: [Google Sheets](/docs/integrations/data-sources/google-sheets), [Databases](/docs/integrations/data-sources/databases), or [Cloud Storage](/docs/integrations/data-sources/cloud-storage). # Google Sheets Source: https://getalchemystai.com/docs/integrations/data-sources/docs/google-sheets Connect Google Sheets to your Alchemyst context layer ## Introduction Google Sheets is a collaborative spreadsheet tool, commonly used for project tracking, budgets, customer lists, experiment results, and configuration data. With Alchemyst's [Google Sheets integration](https://platform.getalchemystai.com/integrations?utm_source=docs.getalchemystai.com\&utm_campaign=docs\&utm_medium=web), you can sync spreadsheets anytime you want, search semantically across all your sheets, and query sheets like structured databases. Your agent sees spreadsheets as living knowledge, not static files. *** ## Why Connect Google Sheets? Traditional spreadsheet workflows fail because: * Spreadsheets are scattered across drives * Manual exports become stale immediately * There's no way to query across multiple sheets * Collaboration happens outside agent context With Alchemyst's Google Sheets integration, your spreadsheets sync directly into your context layer, enabling seamless collaboration and always up-to-date information. *** ## How to Connect **Prerequisites:** * Google Cloud Project * Service Account with Google Sheets API access * Spreadsheets shared with the service account email **What You Need:** * Client Email (service account email address) * Private Key (from service account JSON key file) * Spreadsheet URL **Important:** You must share the spreadsheet with the service account email address. The service account needs at least Viewer permission to access the content. *** ## What Gets Indexed Alchemyst can index: * Cell values * Formulas * Named ranges * Sheet names * Structure * Charts (as text descriptions) * Comments *** ## Setting Up a Service Account 1. Go to Google Cloud Console and create or select a project 2. Enable Google Sheets API 3. Navigate to IAM & Admin → Service Accounts 4. Create a new service account 5. Generate a JSON key file 6. Extract the `client_email` and `private_key` from the JSON **The JSON key file contains:** * `client_email`: Service account email (e.g., `service@project.iam.gserviceaccount.com`) * `private_key`: Full private key string (including header and footer) *** ## Security Best Practices For Google Sheets integrations: * Use service accounts instead of OAuth for programmatic access * Store private keys in environment variables or secrets managers * Never commit private keys to version control * Rotate keys every 90 days * Grant only Viewer permissions to service accounts * Use folder-level sharing for easier management * Enable access logging in Google Workspace Admin Console * Monitor for unusual activity and set up alerts *** ## Version Tracking Google Sheets change constantly. Alchemyst automatically tracks versions by removing old content when spreadsheets update and indexing new content, ensuring searches always return the latest information. *** ## Next Steps Once Google Sheets is connected, you can: * Search across all your spreadsheets * Combine spreadsheet data with databases and other sources * Keep your agent synchronized with team collaboration Explore other integrations: [Google Docs](/docs/integrations/data-sources/google-docs), [Databases](/docs/integrations/data-sources/databases), or [Cloud Storage](/docs/integrations/data-sources/cloud-storage). # Introduction Source: https://getalchemystai.com/docs/integrations/data-sources/introduction Connect your databases, documents, and cloud storage to Alchemyst's context layer ## Overview Data source integrations bring your organization's knowledge directly into Alchemyst. Connect your existing systems and let Alchemyst automatically sync and search across everything—no manual uploads, no SQL required. **Available integrations:** * **Databases** - PostgreSQL, MongoDB * **Productivity Tools** - Google Docs, Google Sheets * **Cloud Storage** - Amazon S3 Query all your data in natural language and get unified results across all connected sources. *** ## Quick Start Visit the [Alchemyst Integrations page](https://platform.getalchemystai.com/integrations?utm_source=docs\&utm_campaign=intro\&utm_medium=web) and select your integration type Choose what data to sync and set your sync frequency Ask questions in plain English across all connected sources *** ## Integration Types Query PostgreSQL and MongoDB in natural language Sync Google Docs and Sheets Connect Amazon S3 buckets ### Databases Connect operational data sources: * **PostgreSQL** - Customer records, transactions, product catalogs * **MongoDB** - User profiles, event logs, content management [View database integration guide →](/docs/integrations/data-sources/databases) ### Productivity Tools Sync team knowledge: * **Google Docs** - Meeting notes, SOPs, project documentation * **Google Sheets** - Project tracking, budgets, customer lists [View productivity integration guide →](/docs/integrations/data-sources/docs) ### Cloud Storage Access files at scale: * **Amazon S3** - Documents, reports, media, code repositories * Supports PDF, DOCX, PPTX, CSV, JSON, images, and more [View cloud storage integration guide →](/docs/integrations/data-sources/cloud-storage) *** ## Key Benefits Search across all connected sources simultaneously with a single query Automatic syncing keeps your data fresh—no manual exports Query databases and spreadsheets without writing SQL or formulas Read-only access, encrypted connections, and granular permissions *** ## Security All integrations follow enterprise-grade security standards: Read-only access - never modifies or deletes your data SSL/TLS encrypted connections Minimal permissions - access only what you choose to sync Instant disconnect from your dashboard [Learn more about security best practices →](/docs/integrations/data-sources/databases#security-best-practices) *** ## Get Started PostgreSQL & MongoDB setup guides Google Docs & Sheets integration Amazon S3 configuration Visit the Alchemyst Integrations page to get started # Chrome Source: https://getalchemystai.com/docs/integrations/extensions/chrome Use Alchemyst AI's memory inside AI models through our Chrome extension. ## Installation and setup To install and configure the Chrome extension, follow the step-by-step guide: **[Chrome Extension Tutorial](/docs/tutorials/chrome-extension)** The tutorial covers: * Installing the [extension](https://chromewebstore.google.com/detail/alchemyst-ai-context-ai-m/aihninjmajjplfkgioojlgfdmagcmgkk?utm_source=tutotial\&utm_medium=docs\&utm_campaign=chrome_extension) * Connecting it to your Alchemyst workspace * Capturing memory and context * Using memory inside supported AI models ## Why memory at all? LLMs are stateless by design — every time you press **Send**, the model starts from a blank slate. When it lacks past interactions, domain facts, or user preferences, it can only guess at the bigger picture, producing answers that feel generic or even contradictory from turn to turn. Persistent **memory** solves this problem by: * **Preserving short-term continuity** - a rolling buffer of the current conversation keeps the model from re-asking questions it already “heard.” * **Holding long-term knowledge** - facts, policies, and prior decisions stay available across sessions, turning a reactive chatbot into a proactive collaborator. * **Personalising responses** - episodic, semantic, and procedural memories let the AI adapt to individual users and multi-step workflows instead of delivering one-size-fits-all output. Without this layered memory architecture, even the smartest model repeats itself, forgets goals, and forces you to copy-paste context manually. With it, AI can reason over time, reference earlier work, and finish complex tasks without starting from zero. ## How the Chrome extension works The extension acts as a lightweight memory layer between you and the model: 1. You capture context or memory directly from the browser 2. Alchemyst stores and indexes it securely 3. Relevant memory is automatically injected when you interact with an AI model 4. The model responds with awareness of past information and intent ## When to use the Chrome extension The Chrome extension is ideal when you: * Work directly in browser-based LLMs * Want memory without building custom integrations * Need consistent context across tools and sessions * Prefer a no-code way to use Alchemyst If you later need deeper control or automation, you can move seamlessly to the SDKs and APIs. ## Use Cases As you are all set to use the extension let's now look and some of the cool stuff you can do with it. ### **For Everyone :** #### **1. AI Models that actually remembers you** Tired of AI models forgetting who you are every time you open a new chat? With Alchemyst AI memory, you can make it remember your preferences, goals, or habits. Whether it's your fitness routine, favorite food, or daily schedule, AI Model will keep it in mind and talk like it actually knows you. #### **2. Continuous learning buddy** If you are learning a new skill, language, or preparing for exams, you don't need to start from scratch every session. AI Model will remember your progress, weak areas, and even your previous questions so it can build on them next time you open it. #### **3. Personal journal and reflection space** Want to track your thoughts or daily reflections? You can use memory to keep your past entries. AI Model can summarize your week, analyze your writing tone, or give you insights on how your mindset has changed over time. #### **4. Smarter recommendations** Every suggestion becomes better with memory. From movies, recipes, or books, AI Model will personalize recommendations based on what you've liked before, without you needing to remind it every time. *** ### **For Developers :** #### **1. Your AI coding partner with context** Developers can finally stop re-explaining their stack, framework, and project setup in every session. Once AI Model remembers your project details, it can help you faster and more accurately the next time you ask for help. #### **2. Smarter debugging sessions** No more “start from zero” debugging. AI Model will recall your previous error logs from alchemyst's memory, the fixes you tried, and what worked or didn't, so you can pick up where you left off seamlessly. #### **3. Technical writing made easier** If you often write documentation, commit messages, or changelogs, adding a single reference doc on the platform can help gpt remember your team's writing style and project tone. It can help you generate consistent documentation without having to guide it repeatedly. #### **4. Shared team memory** Teams can share one memory setup for a project so every member gets the same context inside AI Model. Perfect for consistent onboarding, documentation, and communication across dev teams. *** With Alchemyst AI's Chrome extension, AI models becomes more than just a chatbot. It becomes your personal assistant, teacher, or coding partner that actually remembers what matters to you. # Integrations Source: https://getalchemystai.com/docs/integrations/introduction Integrate Alchemyst's memory into your AI Stack Connect Alchemyst's context layer directly into your AI stack. Whether you're enhancing personal productivity with a browser extension or architecting agentic workflows via our SDK, Alchemyst ensures high-fidelity context retrieval across all platforms. By integrating with industry-standard frameworks like LangChain, Agno, and the Vercel AI SDK, you can eliminate LLM "amnesia" and power more intelligent, stateful interactions with minimal latency. ## Supported Integrations Get started by integrating Alchemyst's memory with your favorite AI frameworks and tools. Integrate memory with chatgpt, claude, gemini by downloading the chrome extension. Proxy server for routing requests to different LLM's API. Use Alchemyst SDK for integrating memory with you ai agents or apps. Integrate with langchain, lama index, agno ai and vercel ai sdk. # n8n Integration Source: https://getalchemystai.com/docs/integrations/no-code-tools/n8n Keep Alchemyst memory in sync with simple no-code workflows This guide shows how to connect n8n to Alchemyst's REST API, so every automation you build can read and write context. ## Prerequisites * An n8n account (cloud or self-hosted) * An Alchemyst API key from the [dashboard](https://platform.getalchemystai.com/settings) * Basic familiarity with n8n's node editor ## Connect n8n to Alchemyst ### Setting Up the HTTP Request Node 1. Add an **HTTP Request** node anywhere in your workflow. 2. Under **Authentication**, pick **Generic Credential Type → Bearer Token**. 3. Create a credential, paste your Alchemyst API key, and save it. 4. Set **Method** to `POST` and **Content Type** to `JSON`. 5. Use one of these endpoints: * Add context: `https://platform-backend.getalchemystai.com/api/v1/context/add` * Search context: `https://platform-backend.getalchemystai.com/api/v1/context/search` Re-use the same HTTP Request node as a template by duplicating it inside other workflows. ### Setting Up the MCP Node 1. Add an **MCP** node in your workflow by pasting the below code snippet. ```json theme={null} { "name": "Alchemyst MCP Client", "nodes": [ { "id": "alchemyst-mcp-client-1", "name": "Alchemyst MCP Client", "type": "@n8n/n8n-nodes-langchain.mcpClientTool", "typeVersion": 1.2, "position": [300, 300], "parameters": { "endpointUrl": "https://mcp.getalchemystai.com/mcp/sse", "serverTransport": "sse", "authentication": "bearerAuth", "include": "selected", "includeTools": [ "alchemyst_ai_context_mcp_search_context" ], "options": { "timeout": 60000 } }, "credentials": { "httpBearerAuth": { "id": "", "name": "" } } } ], "connections": {} } ``` 2. Open the node you just added and confirm the following settings: * **Endpoint**: `https://mcp.getalchemystai.com/mcp/sse` * **Authentication**: **Bearer Auth** 3. Create a Bearer Auth credential: * Click **Create New Credential** * Paste your Alchemyst API key into the **Bearer Token** field * Save the credential and select it for the MCP node Once these steps are complete, the MCP node can call Alchemyst tools inside your workflows. Follow our step-by-step tutorial to build your first workflow in minutes. # Python SDK Source: https://getalchemystai.com/docs/integrations/sdk/python-sdk Get started with the Alchemyst Python SDK ## Installation ```sh pip theme={null} pip install alchemystai ``` ```sh uv theme={null} uv add alchemystai ``` ## Usage ## Context: Add ```python theme={null} import os from alchemyst_ai import AlchemystAI client = AlchemystAI( api_key=os.environ.get("ALCHEMYST_AI_API_KEY"), # This is the default and can be omitted ) # Build documents array docs_array = [] docs_array.append({ "content": "files content", "metadata": { # optional "file_name": "file_name", "file_type": "pdf/txt/json", "group_name": ["group1", "group2"] } }) # Add documents to context response = client.v1.context.add( documents=docs_array, source="source of context data", context_type="resource", # one of: resource | conversation | instruction scope="internal", # one of: internal | external metadata={ "file_name": "name of the file", "file_type": "type", "last_modified": "timestamp", "file_size": 1234, # number "group_name": ["group1", "group2"] } ) ``` **Version Requirements**: The `groupName` field is introduced in Python SDK version 0.5.0. If you use `groupName` in previous versions, you will encounter an error. If `groupName` is not provided, it will be set to a default value automatically. **groupName**: The group name acts like a namespace which creates a scope for context. Documents with the same group name will be grouped together for better organization and retrieval. **Example Use Cases**: * `['project-alpha']` - Group all documents related to a specific project * `['customer-support', 'tier-1']` - Organize support documentation by department and priority * `['legal', 'contracts']` - Categorize legal documents by type and category * `['training', 'onboarding']` - Group training materials for new employee onboarding ## Context: Search ```python theme={null} from alchemyst_ai import AlchemystAI client = AlchemystAI() results = client.v1.context.search( query="your search query", similarity_threshold=0.8, minimum_similarity_threshold=0.5, scope="internal", # internal | external body_metadata={ # Optional - can be None "file_type": "ai/conversation", "file_name": "chatgpt-convo-1", "group_name": ["project-name"] } ) ``` While you can provide an `api_key` keyword argument, we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/) to add `ALCHEMYST_AI_API_KEY="My API Key"` to your `.env` file so that your API Key is not stored in source control. ## Async usage Simply import `AsyncAlchemystAI` instead of `AlchemystAI` and use `await` with each API call: ```python theme={null} import os import asyncio from alchemyst_ai import AsyncAlchemystAI client = AsyncAlchemystAI( api_key=os.environ.get("ALCHEMYST_AI_API_KEY"), # This is the default and can be omitted ) async def main() -> None: response = await client.v1.context.add( documents=[{"content": "files content"}], source="source of context data", context_type="resource", scope="internal", ) asyncio.run(main()) ``` Functionality between the synchronous and asynchronous clients is otherwise identical. ### With aiohttp By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend. You can enable this by installing `aiohttp`: ```sh theme={null} # install from PyPI pip install alchemystai[aiohttp] ``` Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`: ```python theme={null} import asyncio from alchemyst_ai import DefaultAioHttpClient from alchemyst_ai import AsyncAlchemystAI async def main() -> None: async with AsyncAlchemystAI( api_key="My API Key", http_client=DefaultAioHttpClient(), ) as client: response = await client.v1.context.add() asyncio.run(main()) ``` ## Using types Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like: * Serializing back into JSON, `model.to_json()` * Converting to a dictionary, `model.to_dict()` Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`. ## Nested params Nested parameters are dictionaries, typed using `TypedDict`, for example: ```python theme={null} from alchemyst_ai import AlchemystAI client = AlchemystAI() response = client.v1.context.add( metadata={}, ) print(response.metadata) ``` ## Handling errors When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `alchemyst_ai.APIConnectionError` is raised. When the API returns a non-success status code (that is, 4xx or 5xx response), a subclass of `alchemyst_ai.APIStatusError` is raised, containing `status_code` and `response` properties. All errors inherit from `alchemyst_ai.APIError`. ```python theme={null} import alchemyst_ai from alchemyst_ai import AlchemystAI client = AlchemystAI() try: client.v1.context.add() except alchemyst_ai.APIConnectionError as e: print("The server could not be reached") print(e.__cause__) # an underlying Exception, likely raised within httpx. except alchemyst_ai.RateLimitError as e: print("A 429 status code was received; we should back off a bit.") except alchemyst_ai.APIStatusError as e: print("Another non-200-range status code was received") print(e.status_code) print(e.response) ``` ### Troubleshooting and Errors Errors while adding or searching documents usually relate to payload structure, limits, or permissions. Refer to the **Add Documents** and **Search Context** sections above for correct usage ### Retries Certain errors are automatically retried 2 times by default, with a short exponential backoff. Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors are all retried by default. You can use the `max_retries` option to configure or disable retry settings: ```python theme={null} from alchemyst_ai import AlchemystAI # Configure the default for all requests client = AlchemystAI( # default is 2 max_retries=0, ) # Or, configure per-request client.with_options(max_retries=5).v1.context.add() ``` ### Timeouts By default requests time out after 1 minute. You can configure this with a `timeout` option, which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object: ```python theme={null} from alchemyst_ai import AlchemystAI # Configure the default for all requests client = AlchemystAI( # 20 seconds (default is 1 minute) timeout=20.0, ) # More granular control client = AlchemystAI( timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0), ) # Override per-request client.with_options(timeout=5.0).v1.context.add() ``` On timeout, an `APITimeoutError` is thrown. Note that requests that time out are [retried twice by default](#retries). ## Advanced ### Logging We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module. You can enable logging by setting the environment variable `ALCHEMYST_AI_LOG` to `info`. ```shell theme={null} $ export ALCHEMYST_AI_LOG=info ``` Or to `debug` for more verbose logging. ### How to tell whether `None` means `null` or missing In an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`: ```py theme={null} if response.my_field is None: if 'my_field' not in response.model_fields_set: print('Got json like {}, without a "my_field" key present at all.') else: print('Got json like {"my_field": null}.') ``` ### Accessing raw response data (e.g. headers) The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g., ```py theme={null} from alchemyst_ai import AlchemystAI client = AlchemystAI() response = client.v1.context.with_raw_response.add() print(response.headers.get('X-My-Header')) context = response.parse() # get the object that `v1.context.add()` would have returned print(context) ``` These methods return an [`APIResponse`](https://github.com/Alchemyst-ai/alchemyst-sdk-python/tree/main/src/alchemyst_ai/_response.py) object. The async client returns an [`AsyncAPIResponse`](https://github.com/Alchemyst-ai/alchemyst-sdk-python/tree/main/src/alchemyst_ai/_response.py) with the same structure, the only difference being `await`able methods for reading the response content. #### `.with_streaming_response` The above interface eagerly reads the full response body when you make the request, which may not always be what you want. To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods. ```python theme={null} with client.v1.context.with_streaming_response.add() as response: print(response.headers.get("X-My-Header")) for line in response.iter_lines(): print(line) ``` The context manager is required so that the response will reliably be closed. ### Making custom/undocumented requests This library is typed for convenient access to the documented API. If you need to access undocumented endpoints, params, or response properties, the library can still be used. #### Undocumented endpoints To make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other http verbs. Options on the client will be respected (such as retries) when making this request. ```py theme={null} import httpx response = client.post( "/foo", cast_to=httpx.Response, body={"my_param": True}, ) print(response.headers.get("x-foo")) ``` #### Undocumented request params If you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request options. #### Undocumented response properties To access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You can also get all the extra fields on the Pydantic model as a dict with [`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra). ### Configuring the HTTP client You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including: * Support for [proxies](https://www.python-httpx.org/advanced/proxies/) * Custom [transports](https://www.python-httpx.org/advanced/transports/) * Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality ```python theme={null} import httpx from alchemyst_ai import AlchemystAI, DefaultHttpxClient client = AlchemystAI( # Or use the `ALCHEMYST_AI_BASE_URL` env var base_url="http://my.test.server.example.com:8083", http_client=DefaultHttpxClient( proxy="http://my.test.proxy.example.com", transport=httpx.HTTPTransport(local_address="0.0.0.0"), ), ) ``` You can also customize the client on a per-request basis by using `with_options()`: ```python theme={null} client.with_options(http_client=DefaultHttpxClient(...)) ``` ### Managing HTTP resources By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting. ```py theme={null} from alchemyst_ai import AlchemystAI with AlchemystAI() as client: # make requests here ... # HTTP client is now closed ``` ## Versioning This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: 1. Changes that only affect static types, without breaking runtime behavior. 2. Changes to library internals which are technically public but not intended or documented for external use. *(Please open a GitHub issue to let us know if you are relying on such internals.)* 3. Changes that we do not expect to impact the vast majority of users in practice. We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. We are keen for your feedback; please open an [issue](https://www.github.com/Alchemyst-ai/alchemyst-sdk-python/issues) with questions, bugs, or suggestions. ### Determining the installed version If you've upgraded to the latest version but aren't seeing any new features you were expecting then your python environment is likely still using an older version. You can determine the version that is being used at runtime with: ```py theme={null} import alchemyst_ai print(alchemyst_ai.__version__) ``` ## Requirements Python 3.8 or higher. ## Troubleshooting and Errors If you encounter unexpected behavior or specific API errors, please refer to our [Troubleshooting Guide](/docs/advanced/troubleshooting) for detailed solutions and error code definitions. # Typescript SDK Source: https://getalchemystai.com/docs/integrations/sdk/typescript-sdk Get started with the Alchemyst Typescript SDK ### Installation ```bash Npm theme={null} npm install @alchemystai/sdk ``` ```bash Yarn theme={null} yarn add @alchemystai/sdk ``` ```bash Pnpm theme={null} pnpm add @alchemystai/sdk ``` ```bash Bun theme={null} bun add @alchemystai/sdk ``` ### Authentication Set your API key via environment variable or pass it directly when initializing the client. * Recommended env var: `ALCHEMYST_AI_API_KEY` ```bash theme={null} export ALCHEMYST_AI_API_KEY="your_api_key_here" ``` ### Quickstart ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); async function main() { const res = await client.v1.context.view.retrieve(); console.log(res); } main().catch(console.error); ``` ### Usage by Endpoint All methods return a promise you can `await`. Types are available out-of-the-box in TypeScript. #### Context: Add ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); try { await client.v1.context.add({ // [REQUIRED] The actual data to embed documents: [ { content: 'The content of the document', }, ], // [REQUIRED] System classifications context_type: 'resource', source: 'web-upload', scope: 'internal', // [OPTIONAL] Can be null. Use for filtering later. metadata: { fileName: 'notes.txt', fileType: 'text/plain', lastModified: new Date().toISOString(), fileSize: 1024, groupName: ['group1', 'group2'], }, }); console.log("Context successfully added.") } catch (error) { //Handles validation error (eg. missing required fields like 'documents') console.error("Error adding context:", error) } ``` **Version Requirements**: The `groupName` field is introduced in TypeScript SDK version 0.6.0. If you use `groupName` in previous versions, you will encounter an error. If `groupName` is not provided, it will be set to a default value automatically. **groupName**: The group name acts like a namespace which creates a scope for context. Documents with the same group name will be grouped together for better organization and retrieval. **Example Use Cases**: * `['project-alpha']` - Group all documents related to a specific project * `['customer-support', 'tier-1']` - Organize support documentation by department and priority * `['legal', 'contracts']` - Categorize legal documents by type and category * `['training', 'onboarding']` - Group training materials for new employee onboarding #### Context: Search ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); try { const { contexts } = await client.v1.context.search({ // [REQUIRED] Core search parameters query: 'Your search query here', similarity_threshold: 0.8, minimum_similarity_threshold: 0.5, scope: 'internal', // Optional - can be null body_metadata: { groupName: ['project-alpha'], fileType: 'ai/conversation', }, }); console.log(contexts); } catch (error) { console.error("Search failed:", error); } ``` #### Context: Delete ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); try { await client.v1.context.delete({ // [REQUIRED] Must specify the source to delete from source: 'web-upload', // [OPTIONAL] Target specific users or organizations user_id: 'your_user_id', organization_id: 'your_organization_id', // [REQUIRED] Flags to specify deletion scope (must set one) by_doc: true, by_id: false, }); console.log("Context deleted successfully."); } catch (error) { console.error("Failed to delete context:", error); } ``` #### Context: View (per-user) ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); try { // Retrieves context specific to the authenticated user const docs = await client.v1.context.view.docs(); console.log("User docs retrieved:", docs) } catch (error) { console.error("Could not retrieve user docs:", error) } ``` **Per-user View**: This endpoint gives the authenticated user their own context from the organization. #### Context: Traces ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); try { // List all traces const { traces } = await client.v1.context.traces.list(); console.log("Traces found:", traces); // Example: Delete a specific trace if (traces.length > 0) { const traceId = traces[0].id; await client.v1.context.traces.delete(traceId); console.log(`Trace ${traceId} deleted.`); } } catch (error) { console.error("Error managing traces:", error.message); } ``` #### Organization: View Context ```ts theme={null} import AlchemystAI from '@alchemystai/sdk'; const client = new AlchemystAI({ apiKey: process.env.ALCHEMYST_AI_API_KEY, }); try { // Retrieves context for specific users within the organization const res = await client.v1.org.context.view({ userIds: ['user_123', 'user_456'], }); console.log("Organization context retrieved:", res); } catch (error) { console.error("Organization view failed:", error); } ``` **Organization View**: This endpoint allows you to fetch context based on specific user IDs within your organization. ## Troubleshooting and Errors If you encounter unexpected behavior or specific API errors, please refer to our [Troubleshooting Guide](/docs/advanced/troubleshooting) for detailed solutions and error code definitions. # Agno Integration Source: https://getalchemystai.com/docs/integrations/third-party/agnoagi Integrate Alchemyst's memory with Agno # AgnoAGI Integration with Alchemyst AI ## Overview This guide demonstrates how to integrate **Alchemyst AI's memory capabilities** with the **AgnoAGI framework** in Python. You'll learn how to build lightning-fast, context-aware AI agents that can remember, learn, and maintain state across interactions using both frameworks together. ## What is AgnoAGI? **AgnoAGI** (formerly Phidata) is a lightweight Python framework designed for building multi-modal AI agents with exceptional performance. When combined with Alchemyst AI's memory system, it creates powerful applications that can: * Instantiate agents \~10,000x faster than LangGraph * Use \~50x less memory than traditional frameworks * Maintain persistent memory across sessions with Alchemyst AI * Learn from user interactions and provide contextually relevant responses * Scale from prototypes to production systems effortlessly ## Prerequisites Before starting, ensure you have: * Python 3.8 or higher * An Alchemyst AI account and API key ([Get one here](https://platform.getalchemystai.com)) * Basic understanding of Python and AI concepts ## Installation ### 1. Install Required Packages ```bash theme={null} pip install agno alchemystai anthropic ``` ### 2. Set Up Environment Variables Create a `.env` file in your project directory: ```bash theme={null} ALCHEMYST_AI_API_KEY=your_alchemyst_api_key_here ANTHROPIC_API_KEY=your_anthropic_api_key_here ``` ## Basic Integration ### Step 1: Initialize Alchemyst Memory Client ```python theme={null} import os from alchemystai import AlchemystAI # Initialize Alchemyst AI client for memory management alchemyst_client = AlchemystAI( api_key=os.getenv("ALCHEMYST_AI_API_KEY") ) ``` ### Step 2: Create Custom Memory Storage for Agno ```python theme={null} """ CLI QnA Agent with Alchemyst AI Memory and Knowledge Base Uses OpenAI for chat completion and Alchemyst AI for persistent memory """ import os from datetime import datetime from typing import Dict, List from alchemyst_ai import AlchemystAI from dotenv import load_dotenv from openai import OpenAI load_dotenv() class AlchemystKnowledgeAgent: """Agent that combines a knowledge base with Alchemyst's memory""" def __init__(self): # Initialize OpenAI client self.openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) # Initialize Alchemyst AI client for memory self.alchemyst_client = AlchemystAI(api_key=os.getenv("ALCHEMYST_AI_API_KEY")) # Session configuration self.session_id = f"session_{datetime.now().strftime('%Y%m%d_%H%M%S')}" self.context_group = "knowledge_agent" self.conversation_history: List[Dict[str, str]] = [] # Simple knowledge base (can be replaced with vector DB) self.knowledge_base: List[str] = ["Sample knowledge base text"] print(f"✓ Knowledge Agent initialized (Session: {self.session_id})") def add_knowledge_to_alchemyst(self, documents: List[str], source: str = "user"): """Add documents to both local knowledge base and Alchemyst memory""" doc_objects = [ { "content": doc, "metadata": { "filename": f"knowledge_{i}", "filetype": "txt", "groupName": [self.context_group] } } for i, doc in enumerate(documents) ] self.alchemyst_client.v1.context.add( documents=doc_objects, source=source, context_type="resource", scope="internal" ) self.knowledge_base.extend(documents) def save_to_memory(self, role: str, content: str): """Save conversation turn to Alchemyst memory""" try: self.alchemyst_client.v1.context.add( documents=[ { "content": f"{role}: {content}", "metadata": { "filename": f"{self.session_id}_{len(self.conversation_history)}", "filetype": "txt", "groupName": [self.context_group, self.session_id], }, } ], source="conversation", context_type="conversation", scope="internal", metadata={ "file_name": f"{self.session_id}_{len(self.conversation_history)}", "file_size": len(content), "file_type": "ai/conversation", "group_name": ["test_group"], "last_modified": datetime.now().isoformat(), }, ) except Exception as e: print(f"Warning: Failed to save to memory: {e}") def get_relevant_context(self, query: str, limit: int = 3) -> str: """Retrieve relevant context from Alchemyst memory""" try: results = self.alchemyst_client.v1.context.search( query=query, similarity_threshold=0.7, scope="internal", metadata={"groupName": [self.context_group]}, ) if hasattr(results, "contexts") and results.contexts: context_items = [] for i, ctx in enumerate(results.contexts[:limit]): content = getattr(ctx, "content", "") context_items.append(f"Context {i+1}: {content}") return "\n".join(context_items) return "" except Exception as e: print(f"Warning: Failed to retrieve context: {e}") return "" def ask(self, question: str) -> str: """Ask a question and get an answer with memory and knowledge context""" # Get relevant context from memory relevant_context = self.get_relevant_context(question) # Build enhanced prompt with context and knowledge base knowledge_context = "\n".join([f"KB {i+1}: {kb}" for i, kb in enumerate(self.knowledge_base[:3])]) system_message = "You are a helpful AI assistant with memory and a knowledge base." if relevant_context: system_message += f"\n\nRelevant context from memory:\n{relevant_context}" if knowledge_context: system_message += f"\n\nRelevant knowledge base entries:\n{knowledge_context}" # Add current question to conversation history self.conversation_history.append({"role": "user", "content": question}) # Prepare messages for OpenAI (last 10 messages to stay within token limits) messages = [ {"role": "system", "content": system_message} ] + self.conversation_history[-10:] # Get response from OpenAI try: response = self.openai_client.chat.completions.create( model="gpt-4o-mini", messages=messages, temperature=0.7, max_tokens=500 ) answer = response.choices[0].message.content # Add assistant response to conversation history self.conversation_history.append({"role": "assistant", "content": answer}) # Save both question and answer to Alchemyst memory self.save_to_memory("user", question) self.save_to_memory("assistant", answer) return answer except Exception as e: return f"Error: {e}" def show_history(self): """Display conversation history""" if not self.conversation_history: print("\nNo conversation history yet.") return print("\n" + "=" * 60) print("CONVERSATION HISTORY") print("=" * 60) for i, msg in enumerate(self.conversation_history, 1): role = "You" if msg["role"] == "user" else "Agent" print(f"\n[{i}] {role}: {msg['content']}") print("\n" + "=" * 60) def search_memory(self, query: str): """Search through all saved memories""" try: results = self.alchemyst_client.v1.context.search( query=query, similarity_threshold=0.5, scope="internal", minimum_similarity_threshold=0.2, body_metadata=None, ) print("🔍 Searching memory...") if hasattr(results, "contexts") and results.contexts: print(f"\n🔍 Found {len(results.contexts)} relevant memories:") print("=" * 60) for i, result in enumerate(results.contexts[:5], 1): content = getattr(result, "content", "") print(f"\n[{i}] {content}") print("\n" + "=" * 60) else: print("\n🔍 No relevant memories found.") except Exception as e: print(f"Error searching memory: {e}") def print_welcome(): """Print welcome message""" print("\n" + "=" * 60) print(" CLI Knowledge Agent WITH MEMORY") print(" Powered by OpenAI + Alchemyst AI") print("=" * 60) print("\nCommands:") print(" - Type your question to get an answer") print(" - 'history' - Show conversation history") print(" - 'search ' - Search through saved memories") print(" - 'addkb ' - Add text to knowledge base") print(" - 'exit' or 'quit' - Exit the program") print("\n" + "=" * 60 + "\n") def main(): """Main CLI loop""" print_welcome() try: agent = AlchemystKnowledgeAgent() except Exception as e: print(f"\n❌ Failed to initialize agent: {e}") print("\nPlease ensure you have set the following environment variables:") print(" - OPENAI_API_KEY") print(" - ALCHEMYST_AI_API_KEY") return while True: try: user_input = input("\n💬 You: ").strip() if not user_input: continue if user_input.lower() in ["exit", "quit", "q"]: print("\n👋 Goodbye! Your conversation has been saved to memory.") break if user_input.lower() == "history": agent.show_history() continue if user_input.lower().startswith("search "): query = user_input[7:].strip() if query: agent.search_memory(query) else: print("\n⚠️ Please provide a search query: search ") continue if user_input.lower().startswith("addkb "): kb_text = user_input[6:].strip() if kb_text: agent.add_knowledge_to_alchemyst([kb_text]) print("✅ Added to knowledge base and memory.") else: print("\n⚠️ Please provide text to add: addkb ") continue print("\n🤖 Agent: ", end="", flush=True) answer = agent.ask(user_input) print(answer) except KeyboardInterrupt: print("\n\n👋 Goodbye! Your conversation has been saved to memory.") break except Exception as e: print(f"\n❌ Error: {e}") if __name__ == "__main__": main() ``` ### Pattern 2: Multi-Agent Team with Shared Memory ```python theme={null} from agno.agent import Agent from agno.models.anthropic import Claude from agno.tools.yfinance import YFinanceTools from agno.tools.duckduckgo import DuckDuckGoTools class AlchemystMultiAgentTeam: """Multi-agent team with shared Alchemyst memory""" def __init__(self, alchemyst_client: AlchemystAI): self.client = alchemyst_client # Shared memory storage self.shared_storage = AlchemystMemoryStorage( alchemyst_client=self.client, context_id="multi_agent_team" ) # Research Agent self.researcher = Agent( name="Research Agent", role="Search the web for information", model=Claude(id="claude-sonnet-4-20250514"), tools=[DuckDuckGoTools(search=True, news=True)], storage=self.shared_storage, instructions=[ "Search for accurate, up-to-date information.", "Always include sources.", "Share findings with the team." ], markdown=True ) # Finance Agent self.finance_agent = Agent( name="Finance Agent", role="Analyze financial data", model=Claude(id="claude-sonnet-4-20250514"), tools=[ YFinanceTools( stock_price=True, analyst_recommendations=True, company_info=True ) ], storage=self.shared_storage, instructions=[ "Provide detailed financial analysis.", "Use tables to display data.", "Consider market trends." ], markdown=True ) # Team Leader self.team_leader = Agent( name="Team Leader", team=[self.researcher, self.finance_agent], model=Claude(id="claude-sonnet-4-20250514"), storage=self.shared_storage, instructions=[ "Coordinate team members effectively.", "Synthesize information from all agents.", "Provide comprehensive answers.", "Remember previous team decisions." ], markdown=True ) def share_insight(self, agent_name: str, insight: str): """Share an insight across all agents via Alchemyst""" self.client.v1.context.add( documents=[{ "content": f"{agent_name}: {insight}", "metadata": { "filename": f"insight_{agent_name}_{datetime.now().timestamp()}", "filetype": "txt", "groupName": ["multi_agent_team", "shared_insights"] } }], source="agent_insight", context_type="conversation", scope="internal", metadata={ "file_name": f"{self.session_id}_{len(self.conversation_history)}", "file_size": len(content), "file_type": "ai/conversation", "group_name": ["test_group"], "last_modified": datetime.now().isoformat(), }, ) def get_team_insights(self) -> List[str]: """Retrieve all team insights from Alchemyst""" results = self.client.v1.context.search( query="insight", similarity_threshold=0.5, scope="internal", body_metadata={"groupName": ["multi_agent_team", "shared_insights"]} ) return [result.get('content', '') for result in results] def execute_task(self, task: str, session_id: str = "team_session") -> str: """Execute a task using the multi-agent team""" response = self.team_leader.run(task, session_id=session_id) return response.content ``` ### Pattern 3: Reasoning Agent with Persistent Memory ```python theme={null} from agno.agent import Agent from agno.models.anthropic import Claude from agno.tools.reasoning import ReasoningTools from typing import Dict, Any class AlchemystReasoningAgent: """Reasoning agent with Alchemyst-backed memory""" def __init__(self, alchemyst_client: AlchemystAI): self.client = alchemyst_client self.storage = AlchemystMemoryStorage( alchemyst_client=self.client, context_id="reasoning_agent" ) self.agent = Agent( name="Reasoning Assistant", model=Claude(id="claude-sonnet-4-20250514"), tools=[ReasoningTools(add_instructions=True)], storage=self.storage, add_history_to_messages=True, num_history_runs=10, instructions=[ "Think step-by-step before answering.", "Show your reasoning process.", "Learn from previous interactions.", "Adapt your approach based on user feedback." ], markdown=True, show_tool_calls=True ) def learn_from_interaction( self, query: str, response: str, feedback: str, session_id: str ): """Store interaction with feedback in Alchemyst for learning""" learning_data = { "timestamp": datetime.now().isoformat(), "session_id": session_id, "query": query, "response": response, "feedback": feedback, "type": "learning_interaction" } self.client.v1.context.add( documents=[{ "content": str(learning_data), "metadata": { "filename": f"learning_{session_id}_{datetime.now().timestamp()}", "filetype": "json", "groupName": ["reasoning_agent", "learning"] } }], source="user_feedback", context_type="conversation", scope="internal" ) def get_learning_history(self) -> List[Dict[str, Any]]: """Retrieve learning history from Alchemyst""" results = self.client.v1.context.search( query="learning_interaction", similarity_threshold=0.6, scope="internal", body_metadata={"groupName": ["reasoning_agent", "learning"]} ) history = [] for result in results: try: import ast history.append(ast.literal_eval(result.get('content', '{}'))) except: continue return history def think_and_respond( self, question: str, session_id: str = "default", show_reasoning: bool = True ) -> str: """Use reasoning with access to learning history""" # Get relevant learning history learning_context = self.get_learning_history() # Enhance prompt with learning if learning_context: context_summary = "\n".join([ f"Previous learning: {item.get('feedback', '')}" for item in learning_context[-5:] # Last 5 learnings ]) enhanced_question = f""" Consider these previous learnings: {context_summary} Question: {question} """ else: enhanced_question = question # Get response with reasoning response = self.agent.run( enhanced_question, session_id=session_id, stream=False ) return response.content ``` ## Complete Example 1: Simple CLI-based QnA Agent ```python theme={null} """ Simple CLI QnA Agent with Alchemyst AI Memory Uses OpenAI for chat completion and Alchemyst AI for persistent memory """ import os from datetime import datetime from typing import Dict, List from alchemyst_ai import AlchemystAI from dotenv import load_dotenv from openai import OpenAI load_dotenv() class QnAAgent: """A simple CLI-based Question & Answer agent with memory""" def __init__(self): # Initialize OpenAI client self.openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) # Initialize Alchemyst AI client for memory self.alchemyst_client = AlchemystAI(api_key=os.getenv("ALCHEMYST_AI_API_KEY")) # Session configuration self.session_id = f"session_{datetime.now().strftime('%Y%m%d_%H%M%S')}" self.context_group = "qna_agent" self.conversation_history: List[Dict[str, str]] = [] print(f"✓ QnA Agent initialized (Session: {self.session_id})") def save_to_memory(self, role: str, content: str): """Save conversation turn to Alchemyst memory""" try: memory_entry = { "timestamp": datetime.now().isoformat(), "session_id": self.session_id, "role": role, "content": content, } self.alchemyst_client.v1.context.add( documents=[ { "content": f"{role}: {content}", "metadata": { "filename": f"{self.session_id}_{len(self.conversation_history)}", "filetype": "txt", "groupName": [self.context_group, self.session_id], }, } ], source="conversation", context_type="conversation", scope="internal", metadata={ "file_name": f"{self.session_id}_{len(self.conversation_history)}", "file_size": len(content), "file_type": "ai/conversation", "group_name": ["test_group"], "last_modified": datetime.now().isoformat(), }, ) except Exception as e: print(f"Warning: Failed to save to memory: {e}") def get_relevant_context(self, query: str, limit: int = 3) -> str: """Retrieve relevant context from Alchemyst memory""" try: results = self.alchemyst_client.v1.context.search( query=query, similarity_threshold=0.6, minimum_similarity_threshold=0.2, scope="internal", body_metadata=None, # {"groupName": [self.context_group]}, ) print("🔍 Retrieving relevant context from memory...") print(results.contexts) if results.contexts: context_items = [] for i, result in enumerate(results.contexts[:limit]): content = getattr(result, "content", "") context_items.append(f"{i + 1}. {content}") return "\n".join(context_items) return "" except Exception as e: print(f"Warning: Failed to retrieve context: {e}") return "" def ask(self, question: str) -> str: """Ask a question and get an answer with memory context""" # Get relevant context from memory relevant_context = self.get_relevant_context(question) # Build system message with context system_message = "You are a helpful AI assistant with memory. " if relevant_context: system_message += ( f"\n\nRelevant context from previous conversations:\n{relevant_context}" ) # Add current question to conversation history self.conversation_history.append({"role": "user", "content": question}) # Prepare messages for OpenAI (last 10 messages to stay within token limits) messages = [ {"role": "system", "content": system_message} ] + self.conversation_history[-10:] # Get response from OpenAI try: response = self.openai_client.chat.completions.create( model="gpt-4o-mini", messages=messages, temperature=0.7, max_tokens=500 ) answer = response.choices[0].message.content # Add assistant response to conversation history self.conversation_history.append({"role": "assistant", "content": answer}) # Save both question and answer to Alchemyst memory self.save_to_memory("user", question) self.save_to_memory("assistant", answer) return answer except Exception as e: return f"Error: {e}" def show_history(self): """Display conversation history""" if not self.conversation_history: print("\nNo conversation history yet.") return print("\n" + "=" * 60) print("CONVERSATION HISTORY") print("=" * 60) for i, msg in enumerate(self.conversation_history, 1): role = "You" if msg["role"] == "user" else "Agent" print(f"\n[{i}] {role}: {msg['content']}") print("\n" + "=" * 60) def search_memory(self, query: str): """Search through all saved memories""" try: results = self.alchemyst_client.v1.context.search( query=query, similarity_threshold=0.5, scope="internal", minimum_similarity_threshold=0.2, body_metadata=None, # {"groupName": [self.context_group]}, ) print("🔍 Searching memory...") print(results.contexts) if results.contexts: print(f"\n🔍 Found {len(results.contexts)} relevant memories:") print("=" * 60) for i, result in enumerate(results.contexts[:5], 1): content = getattr(result, "content", "") print(f"\n[{i}] {content}") print("\n" + "=" * 60) else: print("\n🔍 No relevant memories found.") except Exception as e: print(f"Error searching memory: {e}") def print_welcome(): """Print welcome message""" print("\n" + "=" * 60) print(" CLI QnA AGENT WITH MEMORY") print(" Powered by OpenAI + Alchemyst AI") print("=" * 60) print("\nCommands:") print(" - Type your question to get an answer") print(" - 'history' - Show conversation history") print(" - 'search ' - Search through saved memories") print(" - 'exit' or 'quit' - Exit the program") print("\n" + "=" * 60 + "\n") def main(): """Main CLI loop""" # Print welcome message print_welcome() # Initialize agent try: agent = QnAAgent() except Exception as e: print(f"\n❌ Failed to initialize agent: {e}") print("\nPlease ensure you have set the following environment variables:") print(" - OPENAI_API_KEY") print(" - ALCHEMYST_AI_API_KEY") return # Main interaction loop while True: try: # Get user input user_input = input("\n💬 You: ").strip() # Handle empty input if not user_input: continue # Handle exit commands if user_input.lower() in ["exit", "quit", "q"]: print("\n👋 Goodbye! Your conversation has been saved to memory.") break # Handle history command if user_input.lower() == "history": agent.show_history() continue # Handle search command if user_input.lower().startswith("search "): query = user_input[7:].strip() if query: agent.search_memory(query) else: print("\n⚠️ Please provide a search query: search ") continue # Process question print("\n🤖 Agent: ", end="", flush=True) answer = agent.ask(user_input) print(answer) except KeyboardInterrupt: print("\n\n👋 Goodbye! Your conversation has been saved to memory.") break except Exception as e: print(f"\n❌ Error: {e}") if __name__ == "__main__": main() ``` ## Complete Example 2: Personal Assistant with Memory ```python theme={null} import os from datetime import datetime from alchemystai import AlchemystAI from agno.agent import Agent from agno.models.anthropic import Claude from agno.tools.duckduckgo import DuckDuckGoTools from agno.tools.reasoning import ReasoningTools class PersonalAssistantWithMemory: """A personal assistant powered by Agno and Alchemyst AI""" def __init__(self): # Initialize Alchemyst client self.alchemyst = AlchemystAI( api_key=os.getenv("ALCHEMYST_AI_API_KEY") ) # Initialize custom storage self.storage = AlchemystMemoryStorage( alchemyst_client=self.alchemyst, context_id="personal_assistant" ) # Create the agent self.agent = Agent( name="Personal Assistant", model=Claude(id="claude-sonnet-4-20250514"), tools=[ ReasoningTools(add_instructions=True), DuckDuckGoTools(search=True, news=True) ], storage=self.storage, add_history_to_messages=True, num_history_runs=10, instructions=[ "You are a helpful personal assistant with memory.", "Remember user preferences and past interactions.", "Search the web for current information when needed.", "Think step-by-step for complex requests.", "Be proactive and helpful." ], markdown=True ) self.session_id = "main_session" def remember_preference(self, category: str, preference: str): """Store a user preference in Alchemyst memory""" pref_data = { "category": category, "preference": preference, "timestamp": datetime.now().isoformat() } self.alchemyst.v1.context.add( documents=[{ "content": f"User preference: {category} = {preference}", "metadata": { "filename": f"pref_{category}", "filetype": "txt", "groupName": ["personal_assistant", "preferences"] } }], source="user_preference", context_type="instruction", scope="internal" ) return f"✓ Remembered: {category} → {preference}" def get_preferences(self) -> Dict[str, str]: """Retrieve all stored preferences""" results = self.alchemyst.v1.context.search( query="User preference", similarity_threshold=0.7, scope="internal", body_metadata={"groupName": ["personal_assistant", "preferences"]} ) preferences = {} for result in results: content = result.get('content', '') if '=' in content: parts = content.split('=') if len(parts) == 2: key = parts[0].replace('User preference:', '').strip() value = parts[1].strip() preferences[key] = value return preferences def add_note(self, note: str, tags: List[str] = None): """Add a note to memory""" tags = tags or [] self.alchemyst.v1.context.add( documents=[{ "content": note, "metadata": { "filename": f"note_{datetime.now().timestamp()}", "filetype": "txt", "groupName": ["personal_assistant", "notes"] + tags } }], source="user_note", context_type="resource", scope="internal", metadata={"tags": tags} ) return "✓ Note saved" def search_notes(self, query: str) -> List[str]: """Search through saved notes""" results = self.alchemyst.v1.context.search( query=query, similarity_threshold=0.6, scope="internal", body_metadata={"groupName": ["personal_assistant", "notes"]} ) return [result.get('content', '') for result in results] def chat(self, message: str) -> str: """Chat with the assistant""" # Get relevant preferences and notes preferences = self.get_preferences() # Enhance message with context if preferences: pref_text = "\n".join([f"- {k}: {v}" for k, v in preferences.items()]) context = f"\nUser preferences:\n{pref_text}\n\n" else: context = "" # Search for relevant notes relevant_notes = self.search_notes(message) if relevant_notes: notes_text = "\n".join([f"- {note}" for note in relevant_notes[:3]]) context += f"\nRelevant notes:\n{notes_text}\n\n" enhanced_message = context + message if context else message # Get response from agent response = self.agent.run(enhanced_message, session_id=self.session_id) return response.content def get_conversation_history(self) -> List[Dict[str, Any]]: """Get conversation history from storage""" session_data = self.storage.read(self.session_id) if session_data and 'messages' in session_data: return session_data['messages'] return [] if __name__ == "__main__": # Initialize assistant assistant = PersonalAssistantWithMemory() print("=== Personal Assistant Demo ===\n") # Store some preferences print(assistant.remember_preference("communication_style", "concise and friendly")) print(assistant.remember_preference("timezone", "EST")) print(assistant.remember_preference("work_focus", "Python development and AI")) # Add some notes print("\n" + assistant.add_note( "Meeting with team on Friday at 2pm to discuss Q1 goals", tags=["meeting", "team"] )) print(assistant.add_note( "Need to review the new Agno documentation for the integration project", tags=["todo", "development"] )) # Chat with assistant print("\n=== Chat Session ===\n") print("User: What do you know about my preferences?") print(f"Assistant: {assistant.chat('What do you know about my preferences?')}\n") print("User: What meetings do I have coming up?") print(f"Assistant: {assistant.chat('What meetings do I have coming up?')}\n") print("User: Tell me about AgnoAGI and its performance benefits") print(f"Assistant: {assistant.chat('Tell me about AgnoAGI and its performance benefits')}\n") # Show conversation history print("\n=== Conversation History ===") history = assistant.get_conversation_history() print(f"Total messages in session: {len(history)}") ``` ## Best Practices ### 1. Memory Organization ```python theme={null} # Use consistent naming conventions storage = AlchemystMemoryStorage( alchemyst_client=client, context_id="project_name_agent_type" # Clear, hierarchical naming ) # Group related data with groupName documents = [{ "content": content, "metadata": { "groupName": ["project", "feature", "subtype"] # Hierarchical organization } }] ``` ### 2. Context Management ```python theme={null} def get_relevant_context(client, query, context_type="all"): """Intelligently fetch only relevant context""" # Use appropriate thresholds similarity_thresholds = { "exact": 0.9, "high": 0.7, "medium": 0.5, "low": 0.3 } results = client.v1.context.search( query=query, similarity_threshold=similarity_thresholds.get("high", 0.7), minimum_similarity_threshold=similarity_thresholds.get("low", 0.3), scope="internal" ) # Limit context to prevent token overflow return results[:5] ``` ### 3. Performance Optimization ```python theme={null} # Leverage Agno's speed for instantiation agents = [ Agent( model=Claude(id="claude-sonnet-4-20250514"), storage=shared_storage # Reuse storage instance ) for _ in range(100) # Create 100 agents in ~200μs total ] # Batch Alchemyst operations when possible def batch_add_memories(client, documents_list): """Add multiple documents in one API call""" client.v1.context.add( documents=documents_list, source="batch_operation", context_type="resource", scope="internal" ) ``` ### 4. Error Handling ```python theme={null} def safe_memory_operation(operation, *args, **kwargs): """Wrapper for safe memory operations""" max_retries = 3 for attempt in range(max_retries): try: return operation(*args, **kwargs) except Exception as e: if attempt == max_retries - 1: print(f"Memory operation failed after {max_retries} attempts: {e}") return None time.sleep(2 ** attempt) # Exponential backoff ``` ## Production Deployment ### 1. Environment Configuration ```python theme={null} import os from dotenv import load_dotenv load_dotenv() class Config: ALCHEMYST_API_KEY = os.getenv("ALCHEMYST_AI_API_KEY") ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") AGENT_CONTEXT_ID = os.getenv("AGENT_CONTEXT_ID", "production_agent") LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO") MAX_HISTORY_RUNS = int(os.getenv("MAX_HISTORY_RUNS", "10")) ``` ### 2. Monitoring and Logging ```python theme={null} import logging from datetime import datetime class MonitoredAgent: def __init__(self, alchemyst_client, agent_name): self.logger = logging.getLogger(agent_name) self.logger.setLevel(logging.INFO) self.storage = AlchemystMemoryStorage( alchemyst_client=alchemyst_client, context_id=agent_name ) self.agent = Agent( name=agent_name, model=Claude(id="claude-sonnet-4-20250514"), storage=self.storage, markdown=True ) def run_with_monitoring(self, query, session_id="default"): start_time = datetime.now() try: response = self.agent.run(query, session_id=session_id) duration = (datetime.now() - start_time).total_seconds() self.logger.info( f"Query processed in {duration:.2f}s | " f"Session: {session_id} | " f"Query length: {len(query)}" ) return response.content except Exception as e: self.logger.error(f"Error processing query: {e}") return "I encountered an error. Please try again." ``` ### 3. Docker Deployment ```dockerfile theme={null} FROM python:3.11-slim WORKDIR /app # Install dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy application COPY . . # Set environment variables ENV PYTHONUNBUFFERED=1 # Run the application CMD ["python", "main.py"] ``` ## Troubleshooting ### Common Issues **Memory not persisting:** * Check API credentials and network connectivity * Verify context\_id is consistent across sessions * Ensure proper error handling for memory operations **Slow performance:** * Agno agents are \~10,000x faster than alternatives * Use batch operations for Alchemyst API calls * Optimize search queries with appropriate similarity thresholds **Integration errors:** * Verify Agno and Alchemyst SDK versions are compatible * Check environment variables are properly set * Review API rate limits and quotas ### Debug Mode ```python theme={null} # Enable debug logging import logging logging.basicConfig(level=logging.DEBUG) # Test storage connection storage = AlchemystMemoryStorage(alchemyst_client, "test") storage.create("test_session", {"test": "data"}) result = storage.read("test_session") print(f"Storage test: {result}") ``` ## Performance Comparison Agno + Alchemyst offers exceptional performance: | Metric | Agno + Alchemyst | Traditional Frameworks | | ------------------- | ---------------- | ---------------------- | | Agent instantiation | \~2μs | \~20-30ms | | Memory footprint | \~3.75 KiB | \~200 KiB | | Context retrieval | \<100ms | 500-1000ms | | Multi-agent scaling | Linear | Exponential overhead | ## Resources * [Alchemyst AI Platform](https://getalchemystai.com) * [Agno Framework](https://www.agno.com) * [Agno Documentation](https://docs.agno.com) * [Alchemyst Python SDK](https://docs.getalchemystai.com/integrations/sdk/python-sdk) * [Agno GitHub Repository](https://github.com/agno-agi/agno) ## Next Steps 1. **Experiment** with different agent configurations and memory patterns 2. **Scale** your application using Agno's multi-agent teams 3. **Monitor** memory usage and performance in production 4. **Extend** functionality by integrating additional Agno tools This integration combines the blazing-fast performance of AgnoAGI with the powerful memory capabilities of Alchemyst AI, enabling you to build production-ready AI agents that are both intelligent and efficient. # Vercel AI SDK Source: https://getalchemystai.com/docs/integrations/third-party/aisdk Integrate Alchemyst's memory with Vercel AI SDK ## About Vercel AI SDK [Vercel AI SDK](https://ai-sdk.dev) is an open-source toolkit from the team behind Vercel and Next.js. It provides a **unified developer experience** for building AI-powered applications, including: * Easy integration with multiple model providers (OpenAI, Anthropic, etc.) * Support for **streaming responses** for real-time chat UIs * Type-safe APIs with excellent **TypeScript support** * Built-in support for **agents, tools, and structured outputs** * Ready-to-use React/Next.js hooks for managing conversation state By using the AI SDK, you can avoid handling low-level APIs directly and focus on creating seamless AI-driven experiences in your app. *** ## How It Works The AI SDK is split into modular packages: * **Core API**: A unified way to call LLMs and handle outputs * **Provider Adapters**: Packages like `@ai-sdk/openai` let you plug in specific providers * **UI Utilities**: Hooks such as `useChat` make it easy to build interactive experiences * **Tooling / Agents**: Support for calling external APIs or chaining workflows This modular design means you can start small and scale up to more complex AI flows as your application grows. ## When to Use Vercel AI SDK You should consider using the SDK if: * You want to build chatbots, assistants, or agent-like applications quickly * You need real-time streaming responses from your models * You want cross-provider flexibility without rewriting core logic * You prefer type safety and well-structured APIs For more details, check out the official [**Vercel AI SDK documentation**](https://ai-sdk.dev/docs/introduction) ## As a Tool in AI-SDK Alchemyst can be added to your AI SDK codebase as a regular tool as well, which is the recommended way for developer control. The snippet below shows how to set up a tool using Vercel's AI SDK, using OpenAI GPT-5-Nano. This tool uses [**Alchemyst AI SDK**](https://npmjs.com/package/@alchemystai/sdk) under the hood, and exposes a nifty set of tools, letting you control if you want to use memory, context or both (default). This assumes that you have an OpenAI Key and Alchemyst API Key. If you don't have the Alchemyst API Key, you can get them in the [**Alchemyst Settings page**](https://platform.getalchemystai.com/settings) ### Basic Setup ```ts aiSdkToolSetup.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search for users with the name rohan", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); ``` ### Complete Streaming Example This example shows how to handle streaming responses and tool calls: ```ts streamingExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "What information do we have about our product documentation?", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); // Stream the text response for await (const chunk of result.textStream) { process.stdout.write(chunk); } // Handle tool calls if any were made const toolCalls = await result.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nTool calls made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, toolCall.args); } } // Get the full text result const fullText = await result.text; console.log('\n\nFull response:', fullText); ``` ### Context Search Example This example demonstrates how the AI can search your stored context: ```ts contextSearchExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Find all information about our pricing plans and feature comparisons", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); // The AI will automatically use the search_context tool to find relevant information for await (const chunk of result.textStream) { process.stdout.write(chunk); } ``` ### Adding Context Example This example shows how to add context that the AI can later search: ```ts addContextExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // First, add some context const addResult = await streamText({ model: openai('gpt-4o-mini'), prompt: `store this information: rohan is a good boy`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); const toolCalls = await addResult.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nTool calls made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, JSON.stringify(toolCall, null, 2)); } } // Wait for the tool to execute await addResult.text; // Now search for it const searchResult = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search for users with the name rohan", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); for await (const chunk of searchResult.textStream) { process.stdout.write(chunk); } ``` ### Memory Management Example This example demonstrates using memory to store user preferences: ```ts memoryExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const userId = "user_123"; const memoryId = `memory_${userId}`; // Store user preferences in memory const storeMemory = await streamText({ model: openai('gpt-4o-mini'), prompt: `Remember that user ${userId} prefers: - Dark mode interface - Email notifications disabled - Preferred language: English - Timezone: IST`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) // Only memory, no context }); const toolCalls = await storeMemory.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nTool calls made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, JSON.stringify(toolCall, null, 2)); } } await storeMemory.text; // Later, retrieve and use the memory const retrieveMemory = await streamText({ model: openai('gpt-4o-mini'), prompt: `What are the preferences for user ${userId}?`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) }); for await (const chunk of retrieveMemory.textStream) { process.stdout.write(chunk); } ``` ### Chat Assistant with Context and Memory A complete chat assistant that uses both context and memory: ```ts chatAssistant.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; async function chatWithAssistant(userMessage: string, userId: string) { const result = await streamText({ model: openai('gpt-4o-mini'), messages: [ { role: 'system', content: 'You are a helpful assistant with access to company knowledge and user preferences.' }, { role: 'user', content: userMessage } ], tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) // Both context and memory }); // Stream the response let response = ''; for await (const chunk of result.textStream) { process.stdout.write(chunk); response += chunk; } // Check for tool calls const toolCalls = await result.toolCalls; if (toolCalls) { console.log('\n\n[Tools used:', toolCalls.map(t => t.toolName).join(', '), ']'); } return response; } // Example usage await chatWithAssistant("who is rohan?", "user_123"); ``` ### Tool Configuration Options Control which tools are available: ```ts toolConfiguration.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // Only context tools (search, add, delete context) const contextOnly = alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false); // Only memory tools (add, delete memory) const memoryOnly = alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true); // Both context and memory (default) const both = alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true); // Use context-only for knowledge base queries const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search our documentation for API examples", tools: contextOnly }); ``` ## MCP Client Setup Alchemyst can be added to your AI SDK codebase as an MCP Tool, which is (probably) the most convenient way to do so. The snippet below shows how to set up an **MCP (Model Context Protocol) Client** using Vercel's AI SDK. This client communicates with your server via SSE (Server-Sent Events) and can be configured with custom headers for authentication. ```ts aiSdkMcpSetup.ts theme={null} import { experimental_createMCPClient as createMCPClient } from 'ai'; const mcpClient = await createMCPClient({ transport: { type: 'sse', url: 'https://mcp.getalchemystai.com/sse', // Configure HTTP headers, e.g. for authentication headers: { Authorization: 'Bearer YOUR_ALCHEMYST_AI_API_KEY', }, }, }); ``` # AI SDK Middleware Source: https://getalchemystai.com/docs/integrations/third-party/aisdk/middleware Integrate Alchemyst's memory management as middleware with Vercel AI SDK ## About Vercel AI SDK with Memory [Vercel AI SDK](https://ai-sdk.dev) is an open-source toolkit from the team behind Vercel and Next.js. It provides a **unified developer experience** for building AI-powered applications with memory capabilities. ### Key Features for Memory Integration * Easy integration with multiple model providers (OpenAI, Anthropic, etc.) * Support for **streaming responses** for real-time chat UIs * Type-safe APIs with excellent **TypeScript support** * Built-in support for persistent user preferences and conversation history * Ready-to-use React/Next.js hooks for managing conversation state By using the AI SDK with Alchemyst memory, you can avoid handling low-level APIs directly and focus on creating seamless AI-driven experiences with persistent context. *** ## How Memory Works The AI SDK memory integration allows you to: * **Store user preferences**: Keep track of user-specific settings and preferences * **Maintain conversation context**: Remember important details across sessions * **Personalize experiences**: Build applications that adapt to individual users * **Enable long-term memory**: Create AI assistants that recall past interactions The Alchemyst memory tools work seamlessly with the AI SDK's modular architecture: * **Core API**: A unified way to call LLMs and handle outputs * **Provider Adapters**: Packages like `@ai-sdk/openai` let you plug in specific providers * **Memory Tools**: Add, retrieve, and manage user memories * **UI Utilities**: Hooks such as `useChat` make it easy to build interactive experiences *** ## Memory Management Examples ### Basic Memory Setup This example shows how to configure memory-only tools with proper groupName structure: ```ts memorySetup.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // Configure with memory tools only const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Remember my preferences", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true), // context: false, memory: true // Memory uses hierarchical groupName: ["user_preferences", "user_123"] }); ``` **Best Practice**: Use hierarchical groupName structure like `["domain", "category", "specific"]` for better organization. Maximum 3 layers for 90% of queries. ### Storing User Preferences This example demonstrates storing user preferences in memory: ```ts storePreferences.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const userId = "user_123"; const memoryId = `memory_${userId}`; // Store user preferences in memory const storeMemory = await streamText({ model: openai('gpt-4o-mini'), prompt: `Remember that user ${userId} prefers: - Dark mode interface - Email notifications disabled - Preferred language: English - Timezone: IST`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) // Only memory, no context }); const toolCalls = await storeMemory.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nTool calls made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, JSON.stringify(toolCall, null, 2)); } } await storeMemory.text; ``` ### Retrieving User Preferences Later, retrieve and use the stored memory: ```ts retrievePreferences.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const userId = "user_123"; // Retrieve user preferences from memory const retrieveMemory = await streamText({ model: openai('gpt-4o-mini'), prompt: `What are the preferences for user ${userId}?`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) }); for await (const chunk of retrieveMemory.textStream) { process.stdout.write(chunk); } ``` ### Personalized Chat Assistant A complete example using memory for personalization: ```ts personalizedAssistant.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; async function personalizedChat(userMessage: string, userId: string) { const result = await streamText({ model: openai('gpt-4o-mini'), messages: [ { role: 'system', content: `You are a helpful assistant that remembers user preferences. The current user is ${userId}.` }, { role: 'user', content: userMessage } ], tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) // Memory only }); // Stream the response let response = ''; for await (const chunk of result.textStream) { process.stdout.write(chunk); response += chunk; } // Check for tool calls const toolCalls = await result.toolCalls; if (toolCalls) { console.log('\n\n[Memory operations:', toolCalls.map(t => t.toolName).join(', '), ']'); } return response; } // Example: Store preferences await personalizedChat( "I prefer dark mode and want notifications disabled", "user_123" ); // Example: Use stored preferences await personalizedChat( "What are my current settings?", "user_123" ); ``` ### Memory with Streaming Handle streaming responses while managing memory: ```ts memoryStreaming.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Remember that I love TypeScript and Next.js", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) }); // Stream the text response for await (const chunk of result.textStream) { process.stdout.write(chunk); } // Handle memory operations if any were made const toolCalls = await result.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nMemory operations made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, toolCall.args); } } // Get the full text result const fullText = await result.text; console.log('\n\nFull response:', fullText); ``` *** ## Bulk Memory Operations For storing multiple user preferences efficiently, use bulk operations: ```ts bulkMemoryOperations.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // Store preferences for multiple users efficiently const users = [ { userId: "user_123", prefs: "Dark mode, English, IST timezone" }, { userId: "user_456", prefs: "Light mode, Spanish, EST timezone" }, { userId: "user_789", prefs: "Auto theme, French, CET timezone" } ]; // Process in batches of 1000 (optimal batch size) const BATCH_SIZE = 1000; for (let i = 0; i < users.length; i += BATCH_SIZE) { const batch = users.slice(i, i + BATCH_SIZE); for (const user of batch) { await streamText({ model: openai('gpt-4o-mini'), prompt: `Remember for ${user.userId}: ${user.prefs}`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) }); } console.log(`Processed ${Math.min(i + BATCH_SIZE, users.length)}/${users.length} users`); } ``` **Performance Tip**: For 1000+ operations, batch in groups of 1000 for optimal performance. Sequential operations for 1000 docs take \~30s, while batched operations take \~3s (10x faster). ### Error Handling for Bulk Operations ```ts robustBulkMemory.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; async function storeUserPreferences(users: Array<{userId: string, prefs: string}>) { const MAX_RETRIES = 3; const failures = []; for (const user of users) { let attempt = 0; let success = false; while (attempt < MAX_RETRIES && !success) { try { await streamText({ model: openai('gpt-4o-mini'), prompt: `Remember for ${user.userId}: ${user.prefs}`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true) }); success = true; } catch (error) { attempt++; console.warn(`Failed for ${user.userId} (attempt ${attempt}/${MAX_RETRIES})`); if (attempt < MAX_RETRIES) { // Exponential backoff: 1s, 2s, 4s await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt - 1)) ); } else { failures.push({ userId: user.userId, error: error.message }); } } } } if (failures.length > 0) { console.error(`${failures.length} users failed after retries:`, failures); } return { failures }; } ``` *** ## When to Use Memory Use Vercel AI SDK with Alchemyst memory when you need to: * **Build personalized experiences**: Remember user preferences, settings, and habits * **Create multi-session applications**: Maintain context across different sessions * **Implement user profiles**: Store and retrieve user-specific information * **Enable conversation continuity**: Remember previous interactions and context * **Track user journey**: Keep a history of user interactions and decisions For more details, check out the official [**Vercel AI SDK documentation**](https://ai-sdk.dev/docs/introduction) *** ## Tool Configuration ```ts theme={null} // Memory tools only (add, delete, retrieve memory) const memoryOnly = alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true); // Use in your application const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Your prompt here", tools: memoryOnly }); ``` If you don't have an Alchemyst API Key, you can get one in the [**Alchemyst Settings page**](https://platform.getalchemystai.com/settings) # AI SDK Tools Source: https://getalchemystai.com/docs/integrations/third-party/aisdk/tools Integrate Alchemyst's tools and context management with Vercel AI SDK ## About Vercel AI SDK with Tools [Vercel AI SDK](https://ai-sdk.dev) is an open-source toolkit from the team behind Vercel and Next.js. It provides a **unified developer experience** for building AI-powered applications with tool calling capabilities. ### Key Features for Tool Integration * Easy integration with multiple model providers (OpenAI, Anthropic, etc.) * Support for **streaming responses** for real-time chat UIs * Type-safe APIs with excellent **TypeScript support** * Built-in support for **agents, tools, and structured outputs** * Ready-to-use React/Next.js hooks for managing conversation state By using the AI SDK with Alchemyst tools, you can avoid handling low-level APIs directly and focus on creating seamless AI-driven experiences in your app. *** ## How It Works The AI SDK is split into modular packages: * **Core API**: A unified way to call LLMs and handle outputs * **Provider Adapters**: Packages like `@ai-sdk/openai` let you plug in specific providers * **UI Utilities**: Hooks such as `useChat` make it easy to build interactive experiences * **Tooling / Agents**: Support for calling external APIs or chaining workflows This modular design means you can start small and scale up to more complex AI flows as your application grows. ### Alchemyst Tools Integration Alchemyst provides specialized tools that you can integrate with the AI SDK: * **Context Management Tools**: Add, search, and retrieve context dynamically * **Search Tools**: Find relevant information in your stored context * **Delete Tools**: Remove outdated or unnecessary context * **Custom Tools**: Extend with your own business logic *** ## When to Use Vercel AI SDK with Tools You should consider using the SDK with Alchemyst tools if: * You want to build chatbots, assistants, or agent-like applications quickly * You need real-time streaming responses from your models * You want to give your AI access to dynamic context and knowledge bases * You need cross-provider flexibility without rewriting core logic * You prefer type safety and well-structured APIs For more details, check out the official [**Vercel AI SDK documentation**](https://ai-sdk.dev/docs/introduction) *** ## As a Tool in AI-SDK Alchemyst can be added to your AI SDK codebase as a regular tool, which is the recommended way for developer control. The snippet below shows how to set up a tool using Vercel's AI SDK, using OpenAI GPT-4o-mini. This tool uses [**Alchemyst AI SDK**](https://npmjs.com/package/@alchemystai/sdk) under the hood, and exposes a nifty set of tools, letting you control if you want to use memory, context or both (default). This assumes that you have an OpenAI Key and Alchemyst API Key. If you don't have the Alchemyst API Key, you can get them in the [**Alchemyst Settings page**](https://platform.getalchemystai.com/settings) ### Basic Setup ```ts aiSdkToolSetup.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search for users with the name rohan", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); ``` **Hierarchical groupName Strategy**: Use 2-3 layers for optimal organization: * Layer 1: Organization/Domain ("engineering", "marketing", "sales") * Layer 2: Category/Time ("q4\_2024", "backend", "campaign") * Layer 3: Specifics ("auth", "api", "billing") Example: \["engineering", "backend", "auth"] instead of flat \["engineering\_backend\_auth\_login\_jwt"] ### Complete Streaming Example This example shows how to handle streaming responses and tool calls: ```ts streamingExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "What information do we have about our product documentation?", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) }); // Stream the text response for await (const chunk of result.textStream) { process.stdout.write(chunk); } // Handle tool calls if any were made const toolCalls = await result.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nTool calls made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, toolCall.args); } } // Get the full text result const fullText = await result.text; console.log('\n\nFull response:', fullText); ``` ### Context Search Example This example demonstrates how the AI can search your stored context: ```ts contextSearchExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Find all information about our pricing plans and feature comparisons", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) // Context only }); // The AI will automatically use the search_context tool to find relevant information for await (const chunk of result.textStream) { process.stdout.write(chunk); } ``` ### Adding Context Example This example shows how to add context that the AI can later search: ```ts addContextExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // First, add some context const addResult = await streamText({ model: openai('gpt-4o-mini'), prompt: `store this information: rohan is a good boy`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) // Context only }); const toolCalls = await addResult.toolCalls; if (toolCalls && toolCalls.length > 0) { console.log('\n\nTool calls made:'); for (const toolCall of toolCalls) { console.log(`- ${toolCall.toolName}:`, JSON.stringify(toolCall, null, 2)); } } // Wait for the tool to execute await addResult.text; // Now search for it const searchResult = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search for users with the name rohan", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) }); for await (const chunk of searchResult.textStream) { process.stdout.write(chunk); } ``` **Document Size Best Practice**: Keep documents between 500-2000 words for optimal retrieval: * Too small (less than 100 words): Loses context, requires many docs * Too large (more than 10,000 words): Retrieves too much irrelevant content, wastes tokens * Just right (500-2000 words): Single cohesive topic with enough context ### Updating Context (Delete-Then-Add Pattern) When you need to update existing context, use the delete-then-add pattern to avoid 409 conflicts: ```ts updateContextExample.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // Update existing context about a user async function updateUserContext(userId: string, newInfo: string) { // Step 1: Delete old context const deleteResult = await streamText({ model: openai('gpt-4o-mini'), prompt: `Delete all information about ${userId}`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) }); await deleteResult.text; // Wait for deletion // Step 2: Small delay to ensure propagation await new Promise(resolve => setTimeout(resolve, 150)); // Step 3: Add updated context const addResult = await streamText({ model: openai('gpt-4o-mini'), prompt: `Store this updated information: ${newInfo}`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) }); return await addResult.text; } // Usage await updateUserContext("rohan", "rohan is an excellent developer who specializes in TypeScript"); ``` **Update Strategy**: Alchemyst uses metadata.fileName as the deduplication key. Same fileName = update attempt, which requires delete first to avoid 409 Conflict errors. This is by design to prevent accidental duplicates. ### Chat Assistant with Context and Memory A complete chat assistant that uses both context and memory: ```ts chatAssistant.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; async function chatWithAssistant(userMessage: string, userId: string) { const result = await streamText({ model: openai('gpt-4o-mini'), messages: [ { role: 'system', content: 'You are a helpful assistant with access to company knowledge and user preferences.' }, { role: 'user', content: userMessage } ], tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true) // Both context and memory }); // Stream the response let response = ''; for await (const chunk of result.textStream) { process.stdout.write(chunk); response += chunk; } // Check for tool calls const toolCalls = await result.toolCalls; if (toolCalls) { console.log('\n\n[Tools used:', toolCalls.map(t => t.toolName).join(', '), ']'); } return response; } // Example usage await chatWithAssistant("who is rohan?", "user_123"); ``` ### Tool Configuration Options Control which tools are available: ```ts toolConfiguration.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // Only context tools (search, add, delete context) const contextOnly = alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false); // Only memory tools (add, delete memory) const memoryOnly = alchemystTools("YOUR_ALCHEMYST_AI_KEY", false, true); // Both context and memory (default) const both = alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, true); // Use context-only for knowledge base queries const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search our documentation for API examples", tools: contextOnly }); ``` ### Advanced Context Management Working with dynamic context in real-time with proper metadata structure: ```ts advancedContext.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; // Add multiple pieces of context with lean metadata (5-field rule) const contexts = [ { content: "Our pricing: Basic $10/month, Pro $50/month, Enterprise custom", metadata: { category: "pricing", lastModified: "2024-12-29" } }, { content: "Support hours: 9am-5pm EST Monday-Friday", metadata: { category: "support", lastModified: "2024-12-29" } }, { content: "Return policy: 30-day money-back guarantee", metadata: { category: "policy", lastModified: "2024-12-29" } } ]; for (const ctx of contexts) { await streamText({ model: openai('gpt-4o-mini'), prompt: `Store this information: ${ctx.content}`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) }); } // Query across all stored context const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "What are all our policies and pricing?", tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) }); for await (const chunk of result.textStream) { process.stdout.write(chunk); } ``` **The 5-Field Metadata Rule**: Start with maximum 5 metadata fields. Only add more when you have a specific query pattern that requires it. **Store in metadata** if you: * Filter or sort by it (category, price, status) * Need exact matching (id, sku) * Use for access control (department, classification) **Store in content** if it's: * Descriptive text (description, features) * Rarely filtered (dimensions, weight) * Only needed when retrieved (warranty, specifications) ### Bulk Context Operations For adding large amounts of context efficiently: ```ts bulkContextOperations.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { alchemystTools } from '@alchemystai/aisdk'; async function bulkAddContext(documents: Array<{content: string}>) { const BATCH_SIZE = 1000; // Optimal batch size const MAX_RETRIES = 3; for (let i = 0; i < documents.length; i += BATCH_SIZE) { const batch = documents.slice(i, i + BATCH_SIZE); console.log(`Processing batch ${Math.floor(i/BATCH_SIZE) + 1}/${Math.ceil(documents.length/BATCH_SIZE)}`); for (const doc of batch) { let attempt = 0; let success = false; while (attempt < MAX_RETRIES && !success) { try { await streamText({ model: openai('gpt-4o-mini'), prompt: `Store this: ${doc.content}`, tools: alchemystTools("YOUR_ALCHEMYST_AI_KEY", true, false) }); success = true; } catch (error) { attempt++; if (attempt < MAX_RETRIES) { // Exponential backoff: 1s, 2s, 4s await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt - 1)) ); } } } } // Small delay between batches if (i + BATCH_SIZE < documents.length) { await new Promise(resolve => setTimeout(resolve, 100)); } } } ``` **Performance Guidelines**: * 100 docs: \~0.5s (single call) * 1,000 docs: \~3s (single call) * 10,000 docs: \~35s (10 batches of 1000) * Always use batches of 1000 for optimal performance * Include retry logic with exponential backoff ## MCP Client Setup Alchemyst can be added to your AI SDK codebase as an MCP Tool, which is (probably) the most convenient way to do so. The snippet below shows how to set up an **MCP (Model Context Protocol) Client** using Vercel's AI SDK. This client communicates with your server via SSE (Server-Sent Events) and can be configured with custom headers for authentication. ```ts aiSdkMcpSetup.ts theme={null} import { experimental_createMCPClient as createMCPClient } from 'ai'; const mcpClient = await createMCPClient({ transport: { type: 'sse', url: 'https://mcp.getalchemystai.com/sse', // Configure HTTP headers, e.g. for authentication headers: { Authorization: 'Bearer YOUR_ALCHEMYST_AI_API_KEY', }, }, }); ``` ### Using MCP Client with Tools Once you've created the MCP client, you can use it with the AI SDK: ```ts mcpUsage.ts theme={null} import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; import { experimental_createMCPClient as createMCPClient } from 'ai'; const mcpClient = await createMCPClient({ transport: { type: 'sse', url: 'https://mcp.getalchemystai.com/sse', headers: { Authorization: 'Bearer YOUR_ALCHEMYST_AI_API_KEY', }, }, }); // Use the MCP client's tools const result = await streamText({ model: openai('gpt-4o-mini'), prompt: "Search for information about our product", tools: mcpClient.tools }); for await (const chunk of result.textStream) { process.stdout.write(chunk); } ``` If you don't have an Alchemyst API Key, you can get one in the [**Alchemyst Settings page**](https://platform.getalchemystai.com/settings) # Integrations Source: https://getalchemystai.com/docs/integrations/third-party/introduction Integrate Alchemyst's memory into your AI Stack Alchemyst integrates into your AI stack as a shared memory layer, allowing models, tools, and workflows to read from and write to the same persistent context. ## Supported Integrations Get started by integrating Alchemyst's memory with your favorite AI frameworks and tools. Integrate with Vercel's AI SDK for seamless TypeScript/JavaScript AI development. Python-first integration for Agno (coming soon). Use Alchemyst with Langchain for advanced LLM workflows in Python and JS. Integrate with LlamaIndex for data-augmented generation and retrieval. # Langchain JS Integration Source: https://getalchemystai.com/docs/integrations/third-party/langchain/js Integrate Alchemyst's memory with Langchain in JS/TS ## Why use LangChain with Alchemyst AI? [LangChain](https://js.langchain.com/) is a popular open-source framework for building context-aware AI applications in JavaScript and TypeScript. It lets you chain together LLMs, retrievers, memory, and tools to create powerful, production-ready AI agents. However, LLMs alone are "forgetful"—they don't remember previous conversations, business rules, or your proprietary data. This is where **context** becomes critical. Without context, AI agents give generic, disconnected answers. With context, they become knowledgeable partners that can reason, personalize, and act based on your data and workflows. (See [What is AI Context?](/docs/ai-context/what-is-ai-context) and [Why you need AI Context?](/docs/ai-context/why-you-need-ai-context)) **Alchemyst AI's LangChain integration** solves this by providing a plug-and-play retriever that connects your LangChain agents to the context stored in Alchemyst's memory architecture. This means your agents can: * Instantly access relevant documents, files, and knowledge bases. * Maintain both short-term and long-term memory across sessions. * Personalize responses and follow complex workflows using your proprietary data. * Avoid repetitive questions and deliver context-aware outputs. With Alchemyst, you simply upload your data, and the retriever handles context injection for you—no need to build your own memory system. (See [How Alchemyst Works](/docs/ai-context/how-alchemyst-works)) ## Installation To get started with the Alchemyst Langchain Integration, install the `@alchemystai/langchain-js` package from npm. ```sh npm theme={null} npm i @alchemystai/langchain-js ``` ```sh yarn theme={null} yarn add @alchemystai/langchain-js ``` ```sh pnpm theme={null} pnpm add @alchemystai/langchain-js ``` ```sh bun theme={null} bun add @alchemystai/langchain-js ``` See Source > **NOTE**: In accordance with the release cycle of LangChain 1.0 release, we have decided to maintain the project separately, as discussed with the maintainers of Langchain Community as well. ## Usage ### As Retriever The `AlchemystRetriever` class can be used like any other Retriever class in LangChain. See the example below: **groupName**: The group name acts like a namespace which creates a scope for context. Documents with the same group name will be grouped together for better organization and retrieval. You can pass `groupName` in the `Metadata` parameter when instantiating the retriever. ```typescript retriever.ts theme={null} import { AlchemystRetriever } from "@alchemystai/langchain-js"; import { StringOutputParser } from "@langchain/core/output_parsers"; import { RunnableSequence } from "@langchain/core/runnables"; import dotenv from "dotenv"; // filepath: /Users/anuran/Alchemyst/integrations/playground/example.ts dotenv.config(); // Instantiate the retriever with your API key and optional config const retriever = new AlchemystRetriever({ apiKey: process.env.ALCHEMYST_AI_API_KEY!, similarityThreshold: 0.8, minimumSimilarityThreshold: 0.5, scope: "internal", body_metadata: { // Optional filter for context search fileType: "text/plain", groupName: ["project-name"], }, }); // Example: Use the retriever in a LangChain pipeline async function main() { // Create a simple pipeline that retrieves documents and outputs their content const pipeline = RunnableSequence.from([ async (input: string) => { const docs = await retriever.getRelevantDocuments(input); return docs.map(doc => doc.pageContent).join("\n---\n"); }, new StringOutputParser() ]); const query = "Tell me about Quantum Entanglement"; // Put your query here const result = await pipeline.invoke(query); console.log("Retrieved Documents:\n", result); } main().catch(console.error); ``` ### As Memory The `AlchemystMemory` class can be used like any other Memory class in LangChain as well. See the example below: ```typescript memory.ts theme={null} import { AlchemystMemory } from "@alchemystai/langchain-js"; import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts"; import { RunnablePassthrough, RunnableSequence } from "@langchain/core/runnables"; import { ChatOpenAI } from "@langchain/openai"; import { randomUUID } from "crypto"; async function main() { console.log("Boot: starting test with env:", { OPENAI_API_KEY: process.env.OPENAI_API_KEY ? "set" : "missing", ALCHEMYST_AI_API_KEY: process.env.ALCHEMYST_AI_API_KEY ? "set" : "missing", }); const sessionId = randomUUID(); console.log("Session:", sessionId); const memory = new AlchemystMemory({ apiKey: process.env.ALCHEMYST_AI_API_KEY || "YOUR_ALCHEMYST_API_KEY", sessionId, }); const model = new ChatOpenAI({ model: "gpt-5-nano", }); // Create a prompt template with message history const prompt = ChatPromptTemplate.fromMessages([ ["system", "You are a helpful AI assistant. Have a conversation with the human, using the chat history for context."], new MessagesPlaceholder("history"), ["human", "{input}"], ]); // Create the chain using LCEL (LangChain Expression Language) const chain = RunnableSequence.from([ RunnablePassthrough.assign({ history: async () => { const memoryVars = await memory.loadMemoryVariables({}); return memoryVars.history || []; }, }), prompt, model, ]); console.log("Invoke #1 ->"); const first = await chain.invoke({ input: "Hi, my name is Anuran. Anuran is from Bangalore." }); // Save to memory await memory.saveContext( { input: "Hi, my name is Anuran. Anuran is from Bangalore." }, { output: first.content } ); console.log("First reply:", first.content); console.log("Invoke #2 ->"); const second = await chain.invoke({ input: "Who is Anuran? Where is Anuran from?" }); // Save to memory await memory.saveContext( { input: "Who is Anuran? Where is Anuran from?" }, { output: second.content } ); console.log("Second reply:", second.content); } main().catch((err) => { console.error(err); process.exit(1); }); ``` # Langchain Python Integration Source: https://getalchemystai.com/docs/integrations/third-party/langchain/python Integrate Alchemyst's memory with Langchain in Python ## Why use LangChain with Alchemyst AI? [LangChain](https://python.langchain.com/) is a popular open-source framework for building context-aware AI applications in Python. It lets you chain together LLMs, retrievers, memory, and tools to create powerful, production-ready AI agents. However, LLMs alone are "forgetful"—they don't remember previous conversations, business rules, or your proprietary data. This is where **context** becomes critical. Without context, AI agents give generic, disconnected answers. With context, they become knowledgeable partners that can reason, personalize, and act based on your data and workflows. (See [What is AI Context?](/docs/ai-context/what-is-ai-context) and [Why you need AI Context?](/docs/ai-context/why-you-need-ai-context)) **Alchemyst AI's LangChain integration** solves this by providing a plug-and-play memory system that connects your LangChain agents to the context stored in Alchemyst's memory architecture. This means your agents can: * Instantly access relevant documents, files, and knowledge bases. * Maintain both short-term and long-term memory across sessions. * Personalize responses and follow complex workflows using your proprietary data. * Avoid repetitive questions and deliver context-aware outputs. With Alchemyst, you simply upload your data, and the memory system handles context injection for you—no need to build your own memory system. (See [How Alchemyst Works](/docs/ai-context/how-alchemyst-works)) ## Installation To get started with the Alchemyst LangChain Integration, install the `alchemyst-langchain` package from PyPI. ```sh pip theme={null} theme={null} pip install alchemyst-langchain ``` The `alchemyst-langchain` package includes all necessary Alchemyst dependencies. You'll also need to install your preferred LLM provider: ```sh theme={null} theme={null} pip install langchain-openai python-dotenv ``` View on PyPI ## Usage ### As Memory The `AlchemystMemory` class can be used like any other Memory class in LangChain. See the example below: **groupName**: The group name acts like a namespace which creates a scope for context. Documents with the same group name will be grouped together for better organization and retrieval. In this implementation, we use the `session_id` as the group name to isolate conversations by session. ```python memory.py theme={null} theme={null} from dotenv import load_dotenv import os from langchain_openai import ChatOpenAI from langchain.chains import ConversationChain from alchemyst_langchain import AlchemystMemory import uuid load_dotenv() def main(): print("Boot: starting test with env:", { "OPENAI_API_KEY": "set" if os.getenv("OPENAI_API_KEY") else "missing", "ALCHEMYST_AI_API_KEY": "set" if os.getenv("ALCHEMYST_AI_API_KEY") else "missing", }) session_id = str(uuid.uuid4()) print(f"Session: {session_id}") # Initialize Alchemyst Memory memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY", "YOUR_ALCHEMYST_API_KEY"), session_id=session_id ) # Initialize your LLM model = ChatOpenAI( model="gpt-4o-mini", temperature=0, ) # Create conversation chain with persistent memory chain = ConversationChain(llm=model, memory=memory) print("Invoke #1 ->") first_response = chain.invoke({ "input": "Hi, my name is Alice. Alice is from New York." }) print("First reply:", first_response.get('response', first_response)) print("Invoke #2 ->") second_response = chain.invoke({ "input": "Who is Alice? Where is Alice from?" }) print("Second reply:", second_response.get('response', second_response)) if __name__ == "__main__": main() ``` ### Memory Operations The `AlchemystMemory` class provides several key operations: **Load Memory Variables**: Automatically retrieves relevant context based on the current input ```python theme={null} theme={null} # Happens automatically when you use the chain memory_vars = memory.load_memory_variables({"input": "your query here"}) print(memory_vars["history"]) ``` **Save Context**: Stores both user input and AI output after each interaction ```python theme={null} theme={null} # Happens automatically after each conversation turn memory.save_context( inputs={"input": "user message"}, outputs={"output": "AI response"} ) ``` **Clear Memory**: Remove all stored context for a session ```python theme={null} theme={null} # Clear all memory for this session memory.clear() ``` ### Multi-User Applications For applications with multiple users, create separate sessions for each user: ```python multi_user.py theme={null} theme={null} from alchemyst_langchain import AlchemystMemory from langchain_openai import ChatOpenAI from langchain.chains import ConversationChain import os def get_user_memory(user_id: str): """Create or retrieve memory for a specific user""" return AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id=f"user_{user_id}" ) # Usage alice_memory = get_user_memory("alice_123") bob_memory = get_user_memory("bob_456") model = ChatOpenAI(model="gpt-4o-mini", temperature=0) # Create separate chains for each user alice_chain = ConversationChain(llm=model, memory=alice_memory) bob_chain = ConversationChain(llm=model, memory=bob_memory) # Each user has isolated conversation history alice_chain.invoke({"input": "I love Python programming"}) bob_chain.invoke({"input": "I prefer JavaScript"}) ``` ### Hierarchical Session Organization For complex applications, use hierarchical naming to organize conversations: ```python hierarchical_sessions.py theme={null} theme={null} from alchemyst_langchain import AlchemystMemory import os # Layer 1: Organization/Domain # Layer 2: Category/Project # Layer 3: Specific identifier # Example 1: Customer support tickets support_memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id="support_customer_alice_ticket_1234" ) # Example 2: Department-specific conversations engineering_memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id="engineering_backend_review_2024" ) # Example 3: Project-based sessions project_memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id="project_alpha_team_design" ) ``` **Hierarchical Naming Best Practice**: Use underscores to separate logical layers in your session\_id. This makes it easier to organize, search, and manage conversations at scale. Think of it like a file path: `domain_category_specific_identifier` ### Topic-Based Sessions Organize conversations by topic or purpose: ```python topic_sessions.py theme={null} theme={null} from alchemyst_langchain import AlchemystMemory import os # Different sessions for different purposes support_memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id="support_ticket_789" ) onboarding_memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id="onboarding_new_user" ) research_memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id="research_project_ai" ) ``` ### Resuming Previous Conversations Simply reuse the same `session_id` to continue where you left off: ```python resume_conversation.py theme={null} theme={null} from alchemyst_langchain import AlchemystMemory from langchain_openai import ChatOpenAI from langchain.chains import ConversationChain import os # First conversation session session_id = "conversation_abc123" memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id=session_id ) model = ChatOpenAI(model="gpt-4o-mini", temperature=0) chain = ConversationChain(llm=model, memory=memory) response = chain.invoke({"input": "Remember that I work at Acme Corp"}) print(response.get('response')) # ... application closes or restarts ... # Later, resume the same conversation with the same session_id memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id=session_id # Same session ID ) chain = ConversationChain(llm=model, memory=memory) # Previous context is automatically loaded! response = chain.invoke({"input": "Where do I work?"}) print(response.get('response')) # Will remember "Acme Corp" ``` ## Complete Example Here's a comprehensive example demonstrating the full capabilities: ```python complete_example.py theme={null} theme={null} from dotenv import load_dotenv import os from langchain_openai import ChatOpenAI from langchain.chains import ConversationChain from alchemyst_langchain import AlchemystMemory import uuid load_dotenv() def main(): print("Alchemyst-LangChain Integration Demo") print("=" * 50) # Use a consistent session_id to continue previous conversations # or generate a new one for a fresh start session_id = str(uuid.uuid4()) print(f"Session ID: {session_id}\n") # Initialize Alchemyst Memory memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id=session_id ) # Initialize your preferred LLM model = ChatOpenAI( model="gpt-4o-mini", temperature=0, ) # Create conversation chain chain = ConversationChain(llm=model, memory=memory) # Test conversation with context persistence test_messages = [ "Hi, my name is Alice and I'm from New York.", "I'm a software engineer working on AI applications.", "What do you remember about me?" ] for i, message in enumerate(test_messages, 1): print(f"[Message {i}] User: {message}") response = chain.invoke({"input": message}) print(f"Assistant: {response.get('response', response)}\n") print("=" * 50) print(f"Session {session_id} completed!") print("Use the same session_id to continue this conversation later.") # Optional: Clear memory when done # memory.clear() if __name__ == "__main__": main() ``` ## Key Features **Persistent Memory**: Context survives app restarts and persists indefinitely\ **Seamless Integration**: Drop-in replacement for LangChain's built-in memory\ **Session Isolation**: Keep different conversations separate and organized\ **Automatic Context Retrieval**: Smart relevance-based memory loading\ **Multi-User Support**: Easy to implement user-specific memory\ **Production Ready**: Built on Alchemyst's robust memory infrastructure ## Configuration Options ### AlchemystMemory Parameters | Parameter | Type | Description | | ------------ | ----- | --------------------------------------------------------- | | `api_key` | `str` | Your Alchemyst API key (required) | | `session_id` | `str` | Unique identifier for the conversation session (required) | | `**kwargs` | | Additional LangChain memory parameters | ### Memory Variables The memory exposes the following variables: * **`history`**: Contains the conversation history as a string ## Best Practices ### 1. Session ID Naming Strategy Use meaningful, hierarchical session IDs to organize conversations at scale: ```python theme={null} theme={null} # Good - Clear hierarchy "support_customer_alice_ticket_1234" "engineering_backend_auth_review" "sales_enterprise_acme_corp" # Avoid - Random or flat naming "abc123xyz" "conversation_1" "session" ``` **Benefits of hierarchical naming:** * Easy to filter and search conversations * Clear ownership and categorization * Scalable for large applications ### 2. Memory Lifecycle Management Decide when to clear memory based on your use case: ```python theme={null} theme={null} # Customer support - clear after ticket resolution if ticket_resolved: memory.clear() # Personal assistant - never clear (indefinite memory) # No clear() call # Training session - clear after session ends if training_complete: memory.clear() ``` ### 3. Handle API Keys Securely Always use environment variables for API keys, never hardcode them: ```python theme={null} theme={null} # Good api_key=os.getenv("ALCHEMYST_AI_API_KEY") # Never do this api_key="alch_1234567890abcdef" ``` ### 4. Session ID Persistence For resumable conversations, store session IDs in your database: ```python theme={null} theme={null} # Example with a database user = db.get_user(user_id) if user.session_id: # Resume existing conversation memory = AlchemystMemory( api_key=api_key, session_id=user.session_id ) else: # Create new conversation session_id = str(uuid.uuid4()) db.update_user(user_id, session_id=session_id) memory = AlchemystMemory( api_key=api_key, session_id=session_id ) ``` ### 5. Error Handling The memory system handles errors gracefully, but monitor your logs: ```python theme={null} theme={null} import logging logging.basicConfig(level=logging.INFO) try: memory = AlchemystMemory( api_key=os.getenv("ALCHEMYST_AI_API_KEY"), session_id=session_id ) chain = ConversationChain(llm=model, memory=memory) response = chain.invoke({"input": user_input}) except Exception as e: logging.error(f"Memory error: {e}") # Fallback to stateless conversation or retry ``` ## Performance Considerations ### Conversation Length The memory system is optimized for typical conversation lengths: * **Optimal**: 10-100 message exchanges per session * **Good**: 100-500 message exchanges * **Consider splitting**: 500+ message exchanges For very long conversations, consider creating new sessions periodically: ```python theme={null} theme={null} # Track message count message_count = 0 MAX_MESSAGES_PER_SESSION = 500 if message_count >= MAX_MESSAGES_PER_SESSION: # Archive old session old_session_id = session_id # Create new session session_id = f"{old_session_id}_continued_{int(time.time())}" memory = AlchemystMemory(api_key=api_key, session_id=session_id) message_count = 0 ``` ### Context Retrieval Speed The memory system uses semantic search for context retrieval: * **Typical retrieval time**: 100-300ms * **Factors affecting speed**: * Total documents in session * Query complexity * Network latency For time-sensitive applications, consider caching or pre-loading context. ## Troubleshooting ### Memory not loading **Symptom**: Previous conversation context not appearing in responses **Solutions**: 1. Ensure your `session_id` remains consistent across requests: ```python theme={null} # Wrong - generates new UUID each time memory = AlchemystMemory(api_key=api_key, session_id=str(uuid.uuid4())) # Correct - reuse existing session_id memory = AlchemystMemory(api_key=api_key, session_id=existing_session_id) ``` 2. Verify the session\_id has data: ```python theme={null} memory_vars = memory.load_memory_variables({"input": "test"}) print(f"Loaded history: {memory_vars['history']}") ``` ### API key errors **Symptom**: Authentication errors or 401 responses **Solutions**: 1. Check your environment variables: ```bash theme={null} echo $ALCHEMYST_AI_API_KEY ``` 2. Verify API key format (should start with `alch_`) 3. Use a `.env` file for local development: ```env theme={null} ALCHEMYST_AI_API_KEY=alch_your_api_key_here OPENAI_API_KEY=sk-your_openai_key_here ``` ### Empty context returned **Symptom**: `history` is empty even with previous messages **Explanation**: This is normal for the first message in a new session. Context builds up as the conversation progresses. ```python theme={null} theme={null} # First message - no context yet response1 = chain.invoke({"input": "Hi, I'm Alice"}) # Context: (empty) # Second message - previous context available response2 = chain.invoke({"input": "What's my name?"}) # Context: "Hi, I'm Alice" ``` ### Import errors **Symptom**: `ModuleNotFoundError: No module named 'alchemyst_langchain'` **Solutions**: 1. Verify installation: ```bash theme={null} pip list | grep alchemyst ``` 2. Reinstall the package: ```bash theme={null} pip install --upgrade alchemyst-langchain ``` 3. Check Python environment (virtual env, conda, etc.) ### Session ID conflicts **Symptom**: Unexpected context from other conversations **Cause**: Two different conversations sharing the same session\_id **Solution**: Use unique, namespaced session IDs: ```python theme={null} theme={null} # Include user ID or unique identifier session_id = f"user_{user_id}_{conversation_type}_{timestamp}" ``` ## How It Works Under the Hood ### Automatic Deduplication AlchemystMemory automatically handles message deduplication using internal identifiers. You don't need to worry about duplicate messages being stored - the system intelligently manages updates. ### Context Search Algorithm When loading memory variables, AlchemystMemory: 1. Takes your input query 2. Searches through the session's conversation history 3. Returns relevant context based on semantic similarity 4. Formats it as a string for the LLM ### Metadata Structure Each conversation turn is stored with minimal metadata following best practices: ```python theme={null} theme={null} # Automatically generated metadata (you don't need to set this) { "source": session_id, "messageId": timestamp, "type": "text", "group_name": [session_id] # For session isolation } ``` This lean metadata approach ensures: * Fast queries and retrieval * Minimal storage overhead * No metadata bloat * Follows the "5-field rule" from best practices ## Migration from Custom Implementation If you were previously using a custom `AlchemystMemory` implementation, migrating to the published package is simple: **Before** (custom implementation): ```python theme={null} theme={null} from langchain.memory.chat_memory import BaseChatMemory from alchemyst_ai import AlchemystAI class AlchemystMemory(BaseChatMemory): # Custom implementation code... pass ``` **After** (using published package): ```python theme={null} theme={null} from alchemyst_langchain import AlchemystMemory ``` The interface remains exactly the same, so your existing code will work without any changes! ## Summary By combining LangChain's workflow capabilities with Alchemyst's persistent memory, developers can build intelligent agents that: * **Retain user context and preferences** across sessions * **Continue conversations** days, weeks, or months later * **Improve personalization** over time with accumulated context * **Scale** to production with reliable, persistent storage * **Organize** conversations by user, topic, or any custom grouping This integration makes your LLM applications more human-like and contextually aware — without losing information after every run. # LLaMAIndex JS Integration Source: https://getalchemystai.com/docs/integrations/third-party/llamaindex/js Integrate Alchemyst's memory with LLaMAIndex in JS/TS Coming soon # LLaMAIndex Integration Source: https://getalchemystai.com/docs/integrations/third-party/llamaindex/python Integrate Alchemyst's memory with LLaMAIndex in Python Coming soon # Claude Desktop Source: https://getalchemystai.com/docs/mcps/claude-desktop Configure Claude Desktop MCP with Alchemyst AI It covers two methods of connection: * **Docker Based Setup** * **npx (Node.js) Setup** ### Prerequisites Before you start, ensure you have the following: * **Node.js** (v18 or higher) * **Docker** (if using the Docker Setup) * **SuperGateway** access (via Docker or npx) * **Alchemyst API key** - Obtain it from your [Alchemyst AI dashboard](https://getalchemyst.com). * **Claude Desktop** (latest version) ### Run with Docker 1. Click on the **☰ Hamburger Menu** in the top-left corner of **Claude Desktop**. 2. Go to **File → Settings...**. 3. In the sidebar, go to **Developer** Tab. 4. Click on **Edit Config**. 5. It will take you to a file called **`claude_desktop_config.json`**. 6. Open the file and add the following configurations: ```json theme={null} "mcpServers": { "alchemyst_context_processor_mcp": { "command": "docker", "args": [ "run", "-i", "--rm", "supercorp/supergateway", "--sse", "https://mcp.getalchemystai.com/mcp/sse", "--oauth2Bearer", "YOUR_ALCHEMYST_PLATFORM_API_KEY", "--keepAlive" ] } } ``` 7. Save the file and restart your **Claude Desktop**. 8. After restart, navigate back to **Developer** Tab in **File → Settings...**. 9. You will be able to see your added MCP Server. 10. There should be a **running** (blue colored) tag in front of your MCP server name. It will ensure that the server is running fine. If there is a **running** tag then **"Congratulations"**, your **Claude Desktop** is integrated with **Alchemyst AI** via Docker Setup. ### Common Error If there is a failed tag, then click on the **Error logs** button and this will open a folder **Error Logs** in which navigate and open the file named **`alchemyst_context_processor_mcp`**. This contains the error stopping the MCP server from running. Try to solve the error and try again. **Note that these instructions are valid for all desktop applications that use the STDIO MCP mode.** ### Run with npx 1. Click on the **☰ Hamburger Menu** in the top-left corner of **Claude Desktop**. 2. Go to **File → Settings...**. 3. In the sidebar, go to **Developer** Tab. 4. Click on **Edit Config**. 5. It will take you to a file called **`claude_desktop_config.json`**. 6. Open the file and add the following configurations: ```json theme={null} "mcpServers": { "alchemyst_context_processor_mcp": { "command": "npx", "args": [ "-y", "supergateway", "--sse", "https://mcp.getalchemystai.com/mcp/sse", "--oauth2Bearer", "YOUR_ALCHEMYST_PLATFORM_API_KEY" ] } } ``` 7. Save the file and restart your **Claude Desktop**. 8. After restart, navigate back to **Developer** Tab in **File → Settings...**. 9. You will be able to see your added MCP Server. 10. There should be a **running** (blue colored) tag in front of your MCP server name. It will ensure that the server is running fine. If there is a **running** tag then **"Congratulations"**, your **Claude Desktop** is integrated with **Alchemyst AI** via npx. **Note that these instructions are valid for all desktop applications that use the STDIO MCP mode.** ### Troubleshooting | **Issue / Error** | **Possible Cause** | **Solution / Fix** | | :------------------------------------------------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | | **Container stops immediately after start** | Docker is not running or missing admin privileges. | Run **Docker Desktop as Administrator**.
Ensure the Docker service is active with:
`net start com.docker.service`. | | **System error 5 has occurred. Access is denied.** | Command Prompt lacks administrator rights. | Open **Command Prompt as Administrator**, then re-run:
`net start com.docker.service`. | | **"Connecting to SSE…" but nothing happens** | Incorrect SSE URL or invalid Alchemyst API key. | Verify the URL:
`https://mcp.getalchemystai.com/mcp/sse`
and ensure your API key is valid and not expired. | | **`401 Unauthorized` or `403 Forbidden`** | Invalid or expired API key provided to Supergateway. | Regenerate your API key from the **Alchemyst Dashboard** and replace it in the command:
`--oauth2Bearer YOUR_API_KEY`. | | **Claude or MCP not showing as connected** | MCP configuration not detected or extension not reloaded. | 1. Restart **VS Code**.
2. Open Command Palette → "MCP: List Active MCP Servers".
3. Confirm `supergateway` is listed and running. | # Cursor Source: https://getalchemystai.com/docs/mcps/cursor Configure Cursor MCP with Alchemyst AI ### Prerequisites Before starting, make sure you have: * **Visual Studio Code v1.101+** installed. * A valid **Alchemyst Platform API key**. * MCP must be enabled in Cursor. Now, to configure **Alchemyst AI** with **Cursor** via **MCP**, follow the below commands: ### Configuring via mcp.json 1. Launch **Cursor** application on your (Mac/Windows). 2. Invoke the **Command Palette** with `⌘K` (Mac) or `Ctrl+Shift+P` (Windows). 3. Search for and select: **Settings → Cursor Settings.** 4. In the **Settings** sidebar, search and navigate to: **`Tools & MCP`** 5. On the **Tools & MCP** page, you will be able to see a button named: **`New MCP server`** Click on it. 6. When you click on the **New MCP Server** button, the `mcp.json` file will be opened automatically. 7. Now, in the `mcp.json` file, you will see the **"mcpServers"** object. Add the following section inside the **"mcpServers"** object: ```json theme={null} "your_mcp_server_name": { "url": "https://mcp.getalchemystai.com/mcp/sse", "headers": { "Authorization": "Bearer YOUR_ALCHEMYST_PLATFORM_API_KEY" } } ``` 8. Change `your_mcp_server_name` to the name you want to give your MCP server. e.g., `Alchemyst`. 9. Change `YOUR_ALCHEMYST_PLATFORM_API_KEY` to your own key, which you will get after logging into the **[Alchemyst Platform](https://platform.getalchemystai.com)**. 10. Now, save the file and navigate back to the **`Tools & MCP`** page inside the **Cursor settings**. 11. Here, you will be able to see your added MCP Server. 12. Make sure the toggle button in front of the MCP server is **ON (green)**, and there should be a green dot on the icon of your MCP server, indicating the server is running successfully. 13. If so, then congratulations to you. Your **Cursor** is now integrated with **Alchemyst AI**. **Your Alchemyst MCP server is now live inside Cursor!** ## Troubleshooting | Issue | Possible Cause | Fix | | :----------------------- | :--------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | | MCP toggle is missing | Outdated Cursor version | Update Cursor to the latest version | | SSE connection fails | Network restrictions or firewall | Allow outbound access to `https://mcp.getalchemystai.com` | | "Authorization failed" | Incorrect or expired API key | Regenerate your API key from [**Alchemyst Dashboard**](https://getalchemystai.com?utm_source=docs.getalchemystai.com\&utm_campaign=docs\&utm_medium=web) | | MCP server not appearing | `mcp.json` not formatted correctly | Validate your JSON syntax | | No context syncing | MCP service not started | Click **Start** beside the MCP server entry in Cursor | # MCPs and Context Source: https://getalchemystai.com/docs/mcps/introduction MCP Compatibility: How Tools Connect to Alchemyst ## The Context Layer as Infrastructure At its core, Alchemyst functions as a **centralized context service**. Instead of embedding documents, files, or historical interactions directly into prompts, Alchemyst stores context externally and exposes it through structured interfaces. These interfaces allow AI tools and agents to retrieve only the **most relevant information** at the moment it is needed. This approach decouples: * context storage from model execution * memory from individual tools * knowledge from single-session interactions The result is AI behavior that is more consistent, scalable, and reliable over time. *** ## MCP Compatibility: How Tools Connect to Alchemyst Alchemyst's memory layer behaves like an **MCP (Model Context Protocol) server**. It exposes well-defined APIs and tool interfaces that can be connected to MCP-compatible clients such as: * VS Code * Cursor * Claude Desktop * Custom agents or internal tooling Through MCP, external tools can: * store context (documents, conversations, instructions) * fetch relevant memory at query time * reuse the same context across multiple environments This ensures that context is **portable**, not locked to a single editor or AI product. *** ## What Is MCP (Model Context Protocol)? **MCP (Model Context Protocol)** is an open-source standard for connecting AI applications to external systems. It defines how AI tools can securely interact with: * data sources (files, databases, APIs) * external tools (search, computation, automation) * workflows and long-lived memory systems Using MCP, AI applications like Claude or Cursor can operate with **shared, persistent context** instead of isolated, stateless prompts. *** ## Benefits of MCP-Based Context Integration Integrating Alchemyst via MCP provides several practical advantages: * **Persistent project knowledge**\ Coding conventions, architectural decisions, and domain rules remain consistent across sessions. * **Faster iteration**\ The AI no longer needs repeated explanations of APIs, schemas, or prior decisions. * **Cross-tool continuity**\ The same memory is available in VS Code, Cursor, Claude Desktop, and other MCP-enabled tools. * **Reduced prompt overhead**\ Context is retrieved dynamically instead of being manually injected into every prompt. Conceptually, this is like working with a teammate who already understands the project—without constant re-onboarding. *** ## How Alchemyst + MCP Improves Real Workflows Consider a common scenario:\ You're working inside an AI-powered editor and hit a point where the model lacks sufficient context to help you move forward. Without a context layer, your options are limited: * re-explain the problem * paste large files into prompts * accept shallow or incorrect responses With Alchemyst, the workflow changes. You upload the relevant files, documents, or references to Alchemyst's context processor. Once connected via MCP, the AI tool can retrieve that information on demand—locally, inside the editor. No retraining.\ No custom models.\ No prompt stuffing. The AI simply has access to the context it was missing. *** ## Design Principle > **Context should be stored once, retrieved selectively, and reused everywhere.** Alchemyst operationalizes this principle by treating memory as shared infrastructure rather than transient prompt data. *** ## Prerequisites Before integrating Alchemyst with an MCP-enabled tool, ensure the following: | **Requirement** | **Details** | | ---------------------------- | -------------------------------------------------------------------- | | **Alchemyst API access** | A valid API key and required credentials | | **Context service endpoint** | URL or command to access the memory layer (local or hosted) | | **Supported editor or tool** | VS Code, Cursor, Claude Desktop, or another MCP-compatible client | | **Permissions & scopes** | Read/write access to the context store as needed | | **Secrets management** | API keys stored securely via environment variables or editor secrets | | **Local dependencies** | Node.js, Python, or other runtime if running services locally | | **Network access** | Required for HTTP/SSE-based MCP transports | *** ## Summary Alchemyst provides a shared, persistent context layer for AI systems.\ MCP provides the protocol that allows tools to use it. Together, they enable AI workflows that are: * context-aware * tool-agnostic * scalable * and far more reliable than prompt-based approaches # MCPs Source: https://getalchemystai.com/docs/mcps/mcps Integrate our context processor MCP across popular tools ## Overview Use the instructions below to connect the Alchemyst Context Processor MCP to your preferred environment. Replace `YOUR_ALCHEMYST_PLATFORM_API_KEY` with your real API key. # Visual Studio Code Source: https://getalchemystai.com/docs/mcps/visual-studio-code Configure Visual Studio Code MCP with Alchemyst AI This guide explains **two integration methods**: 1. HTTP / Server-Sent Events (recommended) 2. Direct configuration via `settings.json` ## Prerequisites Before proceeding, ensure that: * You have **Visual Studio Code v1.101+** installed. * You have a valid **Alchemyst Platform API key**. * Your VS Code supports **MCP integration** (either via the OpenAI MCP extension or natively if available). * You are familiar with editing VS Code's `settings.json` ### 1. Integration via HTTP (Server-Sent Events) 1. Open Command Palette via: `Ctrl` (or `Cmd`) + `Shift` + `P`. 2. Type MCP and select `MCP: Add Server....` 3. Choose HTTP (HTTP or Server-Sent Events) as the transport type. 4. Enter the URL: `https://mcp.getalchemystai.com/mcp/sse` 5. Select Server ID: This is going to be your server name. e.g., `Alchemyst-server-mcp`. 6. Then, you will be asked to choose whether to save settings at User-level `settings.json` or Workspace level. 7. You'll be redirected to your respective `settings.json` file. 8. Then edit the headers inside the MCP server object (name you gave to your server) in `settings.json` with: ```json theme={null} "headers": { "Authorization": "Bearer YOUR_ALCHEMYST_PLATFORM_API_KEY" } ``` 9. You will see a faint Start button popping right up on top of the MCP object in your present settings.json file. 10. Click on that and your MCP server will be ready to use! **You're done! Your MCP server is now connected via HTTP (SSE).** ### 2. Configuration via `settings.json` 1. **Open Command Palette** * Press `Ctrl` (or `Cmd`) + `Shift` + `P`. * Type and select **"Preferences: Open User Settings (JSON)"**. 2. Now, you are in **User Settings JSON**. 3. Add the following **MCP Configuration block**. ```json theme={null} "mcp": { "servers": { "alchemyst-context-mcp": { "url": "https://mcp.getalchemystai.com/mcp/sse", "headers": { "Authorization": "Bearer YOUR_ALCHEMYST_PLATFORM_API_KEY" } } } } ``` 4. Save your `settings.json` file. 5. You will see a faint Start button popping right up on top of the MCP object in your present settings.json file. 6. Click on that and your MCP server will be ready to use! **You're done! Your MCP server is now connected via directly configuring the `settings.json` file.** ## Troubleshooting | **Issue** | **Possible Cause** | **Fix** | | :------------------------- | :------------------------------ | :----------------------------------------------------------------------------------------- | | MCP server not starting | Invalid or expired API key | Regenerate your API key from **[Alchemyst Platform](https://platform.getalchemystai.com)** | | "Start" button not visible | Outdated VS Code version | Upgrade to v1.101+ | | No response from server | Network/firewall blocking SSE | Allow outbound access to `https://mcp.getalchemystai.com` | | Local setup not working | Missing Node/Python environment | Verify local dependencies | # Self Hosting Source: https://getalchemystai.com/docs/self-hosting/self-hosting > Deploy your own instance of Alchemyst AI on-premise for enterprise-grade security and control This guide is intended for **enterprise customers only** who have specifically opted for self-hosting as part of their enterprise plan. If you're on a standard plan, please use our hosted API at [platform.getalchemystai.com](https://platform.getalchemystai.com). ## Prerequisites Before you start, you'll need to gather several API keys and set up accounts with various services. This comprehensive guide will walk you through obtaining each required component. ### Enterprise Deployment Package Alchemyst AI's on-premise deployment is designed for security, observability, and ease of configuration. At its core, the platform includes a proprietary Context Processor—a confidential build component responsible for advanced contextual analysis and model orchestration. This processor is delivered as a compiled artifact and does not expose internal logic or proprietary data pathways. To ensure seamless monitoring and insights, Alchemyst AI integrates with OpenTelemetry, enabling standardized observability and compatibility with popular tracing and metrics backends. Configuration and secret management are securely handled through Infisical, which provides encrypted storage and automated injection of environment variables across environments. Together, these components create a robust, transparent, and secure on-premise deployment architecture. ## Architecture Overview ```mermaid theme={null} graph LR subgraph ES[Enterprise Server] CP[Context Processor] TD[Traditional DB] VD[Vector DB] CP --> TD CP --> VD end LV[Licence Verification] <--> ES ES --> OS[Observability Stack] ``` ## Core Components ### 1. Context Processor * **Type**: Proprietary compiled artifact * **Purpose**: Advanced contextual analysis and model orchestration * **Security**: No source code exposure, compiled binary only * **Integration**: Seamlessly connects with vector databases and caching layers ### 2. OpenTelemetry Integration * **Purpose**: Standardized observability and monitoring * **Features**: * Distributed tracing * Metrics collection * Performance monitoring * **Compatibility**: Works with popular backends (Jaeger, Prometheus, Grafana) ### 3. Infisical Configuration Management * **Purpose**: Secure configuration and secret management * **Features**: * Encrypted storage * Environment-specific configurations * Automated secret injection * Access control and audit logs ## Monitoring and Observability ### OpenTelemetry Setup Configure your observability stack to receive telemetry data from Alchemyst AI: ### Metrics and Dashboards Set up monitoring dashboards to track: * **API Performance**: Request latency, throughput, error rates * **Context Processing**: Processing time, queue depth, success rates * **Resource Usage**: CPU, memory, disk usage * **Business Metrics**: Active users, context additions, search queries ## Security Considerations ### 1. Network Security * Deploy behind a reverse proxy (nginx/traefik) * Configure SSL/TLS termination * Set up proper firewall rules * Use private networks for internal communication ### 2. Data Protection * Encrypt data at rest and in transit * Implement proper access controls * Regular security audits * Backup and disaster recovery procedures ### 3. Compliance * GDPR compliance for EU customers * SOC 2 Type II certification * HIPAA compliance for healthcare use cases * Custom compliance requirements ## Support and Maintenance ### Enterprise Support * 24/7 dedicated support channel * Priority response times * Direct access to engineering team * Custom SLA agreements ### Updates and Patches * Automated security updates * Zero-downtime deployments * Rollback capabilities * Change management procedures ## Getting Started 1. **Contact Sales**: Reach out to our enterprise team at [anuran@getalchemystai.com](mailto:anuran@getalchemystai.com) 2. **Architecture Review**: We'll review your infrastructure requirements 3. **Deployment Package**: Receive your customized deployment package 4. **Implementation**: Our team will guide you through the setup process 5. **Go Live**: Launch your self-hosted Alchemyst AI instance Contact our enterprise team for self-hosting options # Chrome Extension Source: https://getalchemystai.com/docs/tutorials/chrome-extension Adding the Alchemyst AI - Chrome Extension for AI Models.