Hybrid Local-Cloud QA Pipeline for LangSmith Thread Analysis
Project description
Geniable
A hybrid local-cloud QA pipeline for analyzing LangSmith conversation threads, running evaluations, and creating issue tickets.
Components
| Component | Description | Documentation |
|---|---|---|
| CLI | Local command-line interface for analysis | cli/README.md |
| Integration Service | AWS Lambda for LangSmith/Jira/Notion integration | cloud/ |
| Evaluation Service | AWS Lambda for running evaluation tools | cloud/ |
Quick Start (CLI)
# Install
pip install -r requirements.txt
# Initialize (configures credentials and syncs to AWS Secrets Manager)
geni init
# Run analysis
geni analyze-latest
See cli/README.md for full CLI documentation.
Lambda Deployment (Legacy)
AWS Lambda function that polls LangSmith annotation queues, analyzes conversation threads for issues, and creates issue pages in Notion.
Features
- On-demand invocation via API Gateway or direct Lambda invoke
- DynamoDB state persistence for tracking processed threads
- Direct Notion SDK integration with dynamic property detection
- Automatic issue classification based on error patterns, performance, and token usage
- SAM-based deployment for infrastructure as code
Architecture
LangSmith Annotation Queue
│
▼
AWS Lambda (geniable)
│
├──► Analyze threads for issues
│ - Performance (long execution time > 30s)
│ - Token usage (high token count > 50K)
│ - Errors in execution steps
│
├──► Create issues in Notion
│
└──► Track state in DynamoDB
Quick Start
Prerequisites
- Python 3.11+
- AWS CLI configured
- AWS SAM CLI installed
- Docker (for building with native dependencies)
- LangSmith API key
- Notion integration token with database access
Configuration
- Copy environment template:
cp .env.example .env
- Fill in your credentials in
.env:
| Variable | Required | Description |
|---|---|---|
LANGSMITH_API_KEY |
Yes | LangSmith API key from https://smith.langchain.com/settings |
LANGSMITH_PROJECT |
No | Project name (default: insights-agent-v2) |
LANGSMITH_QUEUE |
Yes | Annotation queue name (exact match required) |
NOTION_API_KEY |
Yes | Notion integration token |
NOTION_DATABASE_ID |
Yes | Target Notion database ID |
NOTION_DATA_SOURCE_ID |
Yes | Data source ID for page creation |
Deployment
# Build with Docker (required for native dependencies)
sam build --use-container
# Deploy to dev environment
make deploy-dev
After deployment, update Lambda environment variables directly:
aws lambda update-function-configuration \
--function-name geniable-dev \
--region ap-southeast-2 \
--environment "Variables={
LANGSMITH_API_KEY=your_key,
LANGSMITH_PROJECT=insights-agent-v2,
LANGSMITH_QUEUE=Your Queue Name,
NOTION_API_KEY=your_notion_key,
NOTION_DATABASE_ID=your_db_id,
NOTION_DATA_SOURCE_ID=your_ds_id,
DYNAMODB_TABLE_NAME=langsmith-thread-state-dev,
AWS_REGION_NAME=ap-southeast-2,
LOG_LEVEL=INFO
}"
Usage
Actions
| Action | Description |
|---|---|
poll |
Check annotation queue for new threads |
full |
Poll + process all new threads (creates Notion issues) |
status |
Get processing statistics |
process |
Process a specific thread by ID |
Direct Lambda Invocation (Recommended)
Poll for new threads:
aws lambda invoke \
--function-name geniable-dev \
--payload '{"action":"poll"}' \
--cli-binary-format raw-in-base64-out \
--region ap-southeast-2 \
/dev/stdout
Full processing (poll + create issues):
aws lambda invoke \
--function-name geniable-dev \
--payload '{"action":"full"}' \
--cli-binary-format raw-in-base64-out \
--region ap-southeast-2 \
/dev/stdout
Check status:
aws lambda invoke \
--function-name geniable-dev \
--payload '{"action":"status"}' \
--cli-binary-format raw-in-base64-out \
--region ap-southeast-2 \
/dev/stdout
Process specific thread:
aws lambda invoke \
--function-name geniable-dev \
--payload '{"action":"process","thread_id":"your-thread-uuid"}' \
--cli-binary-format raw-in-base64-out \
--region ap-southeast-2 \
/dev/stdout
Makefile Commands
make invoke-dev-full # Poll + process all new threads
make invoke-dev-poll # Just poll for new threads
make invoke-dev-status # Get processing statistics
make logs-dev # Tail Lambda logs
make outputs-dev # Show stack outputs
API Gateway (requires API key)
# Poll
curl -X POST https://{api-id}.execute-api.ap-southeast-2.amazonaws.com/dev/analyze \
-H "x-api-key: {api-key}" \
-H "Content-Type: application/json" \
-d '{"action": "poll"}'
# Full processing
curl -X POST https://{api-id}.execute-api.ap-southeast-2.amazonaws.com/dev/analyze \
-H "x-api-key: {api-key}" \
-H "Content-Type: application/json" \
-d '{"action": "full"}'
# Status
curl https://{api-id}.execute-api.ap-southeast-2.amazonaws.com/dev/status \
-H "x-api-key: {api-key}"
Get API key: make get-api-key-dev
Issue Detection
The analyzer identifies these issue types:
| Issue Type | Trigger | Priority |
|---|---|---|
| Long Execution | Duration > 30 seconds | Medium |
| High Token Usage | Tokens > 50,000 | Medium |
| Step Errors | Any step with error | Based on severity |
| Thread Errors | Thread-level errors | Based on severity |
Notion Database
The client automatically detects your database schema and adapts to available properties.
Supported properties:
- Title property (required, auto-detected)
- Priority (select)
- Category (select)
- Complexity (select)
- Status (status or select)
AWS Resources Created
| Resource | Name |
|---|---|
| Lambda Function | geniable-{env} |
| DynamoDB Table | langsmith-thread-state-{env} |
| API Gateway | geniable-api-{env} |
| CloudWatch Logs | /aws/lambda/geniable-{env} |
| CloudWatch Alarm | Error threshold monitoring |
Project Structure
langsmith-lambda/
├── src/
│ ├── handler.py # Lambda entry point
│ ├── config.py # Environment configuration
│ ├── langsmith_client.py # LangSmith API client
│ ├── notion_issue_client.py # Notion SDK integration
│ ├── state_manager.py # DynamoDB state operations
│ ├── issue_classifier.py # Issue classification logic
│ └── models/ # Data models
├── template.yaml # SAM template
├── samconfig.toml # SAM configuration
├── Makefile # Build/deploy commands
├── requirements.txt # Python dependencies
└── .env # Environment variables (not committed)
Troubleshooting
Check Lambda Logs
make logs-dev
# or
aws logs tail /aws/lambda/geniable-dev --since 10m --region ap-southeast-2
Reset Processed State
To reprocess a thread, delete it from DynamoDB:
aws dynamodb delete-item \
--table-name langsmith-thread-state-dev \
--region ap-southeast-2 \
--key '{"pk": {"S": "THREAD#your-thread-id"}, "sk": {"S": "METADATA"}}'
Common Issues
-
Missing environment variables: SAM parameter overrides may not work correctly with special characters. Update Lambda configuration directly via AWS CLI or console.
-
Notion property errors: The client auto-detects database properties. Check logs to see detected properties:
Database properties: [...] -
Queue not found: Verify the exact queue name matches (including any typos in the original name).
-
No new threads found: Threads are tracked in DynamoDB. Use the reset command above to reprocess.
Development
# Install dependencies
make install-dev
# Run tests
make test
# Run with coverage
make test-coverage
# Format code
make format
# Lint
make lint
# Local testing with SAM
make local
Estimated Costs
| Usage | Lambda | DynamoDB | API Gateway | Total |
|---|---|---|---|---|
| 10 invocations/day | $0.50 | $1.00 | $0.50 | ~$2/month |
| 100 invocations/day | $2.00 | $5.00 | $3.50 | ~$10/month |
Cleanup
# Delete dev stack
make delete-dev
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geniable-2.2.8.tar.gz.
File metadata
- Download URL: geniable-2.2.8.tar.gz
- Upload date:
- Size: 87.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53b023bf45323f9e9adc3263fd519216e982e6db02f2bf03b2cb5505c81557fd
|
|
| MD5 |
9bc7c6900d35a22ca5fa31f5e8869e62
|
|
| BLAKE2b-256 |
9e31970b1cfd6e7540db117fe5db30a09b0da31bcf6c7ccf6605a88f2e992a13
|
File details
Details for the file geniable-2.2.8-py3-none-any.whl.
File metadata
- Download URL: geniable-2.2.8-py3-none-any.whl
- Upload date:
- Size: 98.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94f640782e7092b10529a583c207d74d1a330e1246a709553a6058fe72ab8edd
|
|
| MD5 |
7ef5ae3a5421af165e7864d986141f77
|
|
| BLAKE2b-256 |
df8996dcd6632f19c54e76738c97190aa64d31efcb34cd5d90b4acdd450c114f
|