mistral-multi-env-setup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMistral AI Multi-Environment Setup
Mistral AI 多环境配置
Overview
概述
Configure Mistral AI across development, staging, and production environments.
在开发、预发布和生产环境中配置Mistral AI。
Prerequisites
前置条件
- Separate Mistral AI API keys per environment
- Secret management solution (Vault, AWS Secrets Manager, GCP Secret Manager)
- CI/CD pipeline with environment variables
- Environment detection in application
- 每个环境独立的Mistral AI API密钥
- 密钥管理方案(Vault、AWS Secrets Manager、GCP Secret Manager)
- 带有环境变量的CI/CD流水线
- 应用中的环境检测能力
Environment Strategy
环境策略
| Environment | Purpose | API Keys | Model Selection |
|---|---|---|---|
| Development | Local dev | Test keys | mistral-small-latest |
| Staging | Pre-prod testing | Staging keys | Same as prod |
| Production | Live traffic | Production keys | Optimized selection |
| 环境 | 用途 | API密钥 | 模型选择 |
|---|---|---|---|
| 开发环境 | 本地开发 | 测试密钥 | mistral-small-latest |
| 预发布环境 | 生产前测试 | 预发布密钥 | 与生产环境一致 |
| 生产环境 | 线上流量 | 生产密钥 | 优化选型 |
Instructions
操作步骤
Step 1: Configuration Structure
步骤1:配置结构
config/
├── mistral/
│ ├── base.ts # Shared configuration
│ ├── development.ts # Dev overrides
│ ├── staging.ts # Staging overrides
│ └── production.ts # Prod overridesconfig/
├── mistral/
│ ├── base.ts # Shared configuration
│ ├── development.ts # Dev overrides
│ ├── staging.ts # Staging overrides
│ └── production.ts # Prod overridesStep 2: Base Configuration
步骤2:基础配置
typescript
// config/mistral/base.ts
export const baseConfig = {
defaultModel: 'mistral-small-latest',
timeout: 30000,
maxRetries: 3,
cache: {
enabled: true,
ttlSeconds: 300,
},
rateLimits: {
requestsPerMinute: 60,
tokensPerMinute: 500000,
},
};typescript
// config/mistral/base.ts
export const baseConfig = {
defaultModel: 'mistral-small-latest',
timeout: 30000,
maxRetries: 3,
cache: {
enabled: true,
ttlSeconds: 300,
},
rateLimits: {
requestsPerMinute: 60,
tokensPerMinute: 500000,
},
};Step 3: Environment-Specific Configs
步骤3:环境专属配置
typescript
// config/mistral/development.ts
import { baseConfig } from './base';
export const developmentConfig = {
...baseConfig,
apiKey: process.env.MISTRAL_API_KEY_DEV,
debug: true,
cache: {
enabled: false, // Disable cache in dev for testing
ttlSeconds: 60,
},
rateLimits: {
requestsPerMinute: 10,
tokensPerMinute: 100000,
},
};typescript
// config/mistral/staging.ts
import { baseConfig } from './base';
export const stagingConfig = {
...baseConfig,
apiKey: process.env.MISTRAL_API_KEY_STAGING,
debug: false,
cache: {
enabled: true,
ttlSeconds: 300,
},
};typescript
// config/mistral/production.ts
import { baseConfig } from './base';
export const productionConfig = {
...baseConfig,
apiKey: process.env.MISTRAL_API_KEY_PROD,
debug: false,
timeout: 60000,
maxRetries: 5,
cache: {
enabled: true,
ttlSeconds: 600,
},
};typescript
// config/mistral/development.ts
import { baseConfig } from './base';
export const developmentConfig = {
...baseConfig,
apiKey: process.env.MISTRAL_API_KEY_DEV,
debug: true,
cache: {
enabled: false, // Disable cache in dev for testing
ttlSeconds: 60,
},
rateLimits: {
requestsPerMinute: 10,
tokensPerMinute: 100000,
},
};typescript
// config/mistral/staging.ts
import { baseConfig } from './base';
export const stagingConfig = {
...baseConfig,
apiKey: process.env.MISTRAL_API_KEY_STAGING,
debug: false,
cache: {
enabled: true,
ttlSeconds: 300,
},
};typescript
// config/mistral/production.ts
import { baseConfig } from './base';
export const productionConfig = {
...baseConfig,
apiKey: process.env.MISTRAL_API_KEY_PROD,
debug: false,
timeout: 60000,
maxRetries: 5,
cache: {
enabled: true,
ttlSeconds: 600,
},
};Step 4: Environment Detection
步骤4:环境检测
typescript
// config/mistral/index.ts
import { developmentConfig } from './development';
import { stagingConfig } from './staging';
import { productionConfig } from './production';
type Environment = 'development' | 'staging' | 'production';
const configs = {
development: developmentConfig,
staging: stagingConfig,
production: productionConfig,
};
export function detectEnvironment(): Environment {
const env = process.env.NODE_ENV || 'development';
if (env === 'production') return 'production';
if (env === 'staging' || process.env.VERCEL_ENV === 'preview') return 'staging';
return 'development';
}
export function getMistralConfig() {
const env = detectEnvironment();
const config = configs[env];
if (!config.apiKey) {
throw new Error(`MISTRAL_API_KEY not set for environment: ${env}`);
}
return {
...config,
environment: env,
};
}typescript
// config/mistral/index.ts
import { developmentConfig } from './development';
import { stagingConfig } from './staging';
import { productionConfig } from './production';
type Environment = 'development' | 'staging' | 'production';
const configs = {
development: developmentConfig,
staging: stagingConfig,
production: productionConfig,
};
export function detectEnvironment(): Environment {
const env = process.env.NODE_ENV || 'development';
if (env === 'production') return 'production';
if (env === 'staging' || process.env.VERCEL_ENV === 'preview') return 'staging';
return 'development';
}
export function getMistralConfig() {
const env = detectEnvironment();
const config = configs[env];
if (!config.apiKey) {
throw new Error(`MISTRAL_API_KEY not set for environment: ${env}`);
}
return {
...config,
environment: env,
};
}Step 5: Secret Management
步骤5:密钥管理
Local Development (.env.local)
bash
undefined本地开发 (.env.local)
bash
undefined.env.local (git-ignored)
.env.local (git-ignored)
MISTRAL_API_KEY_DEV=your-dev-api-key
**GitHub Actions (secrets)**
```yamlMISTRAL_API_KEY_DEV=your-dev-api-key
**GitHub Actions (密钥)**
```yaml.github/workflows/deploy.yml
.github/workflows/deploy.yml
jobs:
deploy-staging:
environment: staging
env:
MISTRAL_API_KEY_STAGING: ${{ secrets.MISTRAL_API_KEY_STAGING }}
deploy-production:
environment: production
env:
MISTRAL_API_KEY_PROD: ${{ secrets.MISTRAL_API_KEY_PROD }}
**AWS Secrets Manager**
```bashjobs:
deploy-staging:
environment: staging
env:
MISTRAL_API_KEY_STAGING: ${{ secrets.MISTRAL_API_KEY_STAGING }}
deploy-production:
environment: production
env:
MISTRAL_API_KEY_PROD: ${{ secrets.MISTRAL_API_KEY_PROD }}
**AWS Secrets Manager**
```bashStore secrets
Store secrets
aws secretsmanager create-secret
--name mistral/production/api-key
--secret-string "your-api-key"
--name mistral/production/api-key
--secret-string "your-api-key"
aws secretsmanager create-secret
--name mistral/production/api-key
--secret-string "your-api-key"
--name mistral/production/api-key
--secret-string "your-api-key"
Retrieve in code
Retrieve in code
aws secretsmanager get-secret-value
--secret-id mistral/production/api-key
--secret-id mistral/production/api-key
```typescript
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const sm = new SecretsManager({ region: 'us-east-1' });
async function getMistralApiKey(env: string): Promise<string> {
const { SecretString } = await sm.getSecretValue({
SecretId: `mistral/${env}/api-key`,
});
return SecretString!;
}GCP Secret Manager
bash
undefinedaws secretsmanager get-secret-value
--secret-id mistral/production/api-key
--secret-id mistral/production/api-key
```typescript
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const sm = new SecretsManager({ region: 'us-east-1' });
async function getMistralApiKey(env: string): Promise<string> {
const { SecretString } = await sm.getSecretValue({
SecretId: `mistral/${env}/api-key`,
});
return SecretString!;
}GCP Secret Manager
bash
undefinedStore secret
Store secret
echo -n "your-api-key" | gcloud secrets create mistral-api-key-prod --data-file=-
echo -n "your-api-key" | gcloud secrets create mistral-api-key-prod --data-file=-
Grant access
Grant access
gcloud secrets add-iam-policy-binding mistral-api-key-prod
--member="serviceAccount:your-sa@project.iam.gserviceaccount.com"
--role="roles/secretmanager.secretAccessor"
--member="serviceAccount:your-sa@project.iam.gserviceaccount.com"
--role="roles/secretmanager.secretAccessor"
```typescript
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
const client = new SecretManagerServiceClient();
async function getMistralApiKey(env: string): Promise<string> {
const [version] = await client.accessSecretVersion({
name: `projects/my-project/secrets/mistral-api-key-${env}/versions/latest`,
});
return version.payload?.data?.toString()!;
}gcloud secrets add-iam-policy-binding mistral-api-key-prod
--member="serviceAccount:your-sa@project.iam.gserviceaccount.com"
--role="roles/secretmanager.secretAccessor"
--member="serviceAccount:your-sa@project.iam.gserviceaccount.com"
--role="roles/secretmanager.secretAccessor"
```typescript
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
const client = new SecretManagerServiceClient();
async function getMistralApiKey(env: string): Promise<string> {
const [version] = await client.accessSecretVersion({
name: `projects/my-project/secrets/mistral-api-key-${env}/versions/latest`,
});
return version.payload?.data?.toString()!;
}Step 6: Environment Isolation
步骤6:环境隔离
typescript
// Prevent accidental cross-environment operations
function validateEnvironment(operation: string, requiredEnv: Environment): void {
const currentEnv = detectEnvironment();
if (currentEnv !== requiredEnv) {
throw new Error(
`Operation "${operation}" requires ${requiredEnv} but running in ${currentEnv}`
);
}
}
// Protect production-only operations
function requireProduction(operation: string): void {
validateEnvironment(operation, 'production');
}
// Usage
async function deployModel() {
requireProduction('deployModel');
// Production-only code
}typescript
// Prevent accidental cross-environment operations
function validateEnvironment(operation: string, requiredEnv: Environment): void {
const currentEnv = detectEnvironment();
if (currentEnv !== requiredEnv) {
throw new Error(
`Operation "${operation}" requires ${requiredEnv} but running in ${currentEnv}`
);
}
}
// Protect production-only operations
function requireProduction(operation: string): void {
validateEnvironment(operation, 'production');
}
// Usage
async function deployModel() {
requireProduction('deployModel');
// Production-only code
}Step 7: Feature Flags by Environment
步骤7:按环境配置功能开关
typescript
interface FeatureFlags {
useNewModel: boolean;
enableFunctionCalling: boolean;
maxConcurrentRequests: number;
}
const featureFlags: Record<Environment, FeatureFlags> = {
development: {
useNewModel: true,
enableFunctionCalling: true,
maxConcurrentRequests: 2,
},
staging: {
useNewModel: true,
enableFunctionCalling: true,
maxConcurrentRequests: 5,
},
production: {
useNewModel: false, // Gradual rollout
enableFunctionCalling: true,
maxConcurrentRequests: 10,
},
};
export function getFeatureFlags(): FeatureFlags {
const env = detectEnvironment();
return featureFlags[env];
}typescript
interface FeatureFlags {
useNewModel: boolean;
enableFunctionCalling: boolean;
maxConcurrentRequests: number;
}
const featureFlags: Record<Environment, FeatureFlags> = {
development: {
useNewModel: true,
enableFunctionCalling: true,
maxConcurrentRequests: 2,
},
staging: {
useNewModel: true,
enableFunctionCalling: true,
maxConcurrentRequests: 5,
},
production: {
useNewModel: false, // Gradual rollout
enableFunctionCalling: true,
maxConcurrentRequests: 10,
},
};
export function getFeatureFlags(): FeatureFlags {
const env = detectEnvironment();
return featureFlags[env];
}Output
输出结果
- Multi-environment config structure
- Environment detection logic
- Secure secret management
- Production safeguards enabled
- 多环境配置结构
- 环境检测逻辑
- 安全的密钥管理
- 生产环境防护已启用
Error Handling
错误处理
| Issue | Cause | Solution |
|---|---|---|
| Wrong environment | Missing NODE_ENV | Set environment variable |
| Secret not found | Wrong secret path | Verify secret manager config |
| Config validation | Invalid settings | Use Zod schema validation |
| Cross-env leak | Missing guards | Add environment checks |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 环境识别错误 | 未设置NODE_ENV | 配置环境变量 |
| 密钥未找到 | 密钥路径错误 | 验证密钥管理器配置 |
| 配置验证失败 | 设置无效 | 使用Zod schema验证 |
| 跨环境泄露 | 缺少防护机制 | 添加环境校验 |
Examples
示例
Quick Environment Check
快速环境检查
typescript
const config = getMistralConfig();
console.log(`Running in ${config.environment}`);
console.log(`Model: ${config.defaultModel}`);
console.log(`Cache enabled: ${config.cache.enabled}`);typescript
const config = getMistralConfig();
console.log(`Running in ${config.environment}`);
console.log(`Model: ${config.defaultModel}`);
console.log(`Cache enabled: ${config.cache.enabled}`);Vercel Environment Detection
Vercel环境检测
typescript
function getVercelEnvironment(): Environment {
const vercelEnv = process.env.VERCEL_ENV;
if (vercelEnv === 'production') return 'production';
if (vercelEnv === 'preview') return 'staging';
return 'development';
}typescript
function getVercelEnvironment(): Environment {
const vercelEnv = process.env.VERCEL_ENV;
if (vercelEnv === 'production') return 'production';
if (vercelEnv === 'preview') return 'staging';
return 'development';
}Resources
参考资源
Next Steps
后续步骤
For observability setup, see .
mistral-observability如需搭建可观测性,请查看 。
mistral-observability