mistral-multi-env-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Mistral 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

环境策略

EnvironmentPurposeAPI KeysModel Selection
DevelopmentLocal devTest keysmistral-small-latest
StagingPre-prod testingStaging keysSame as prod
ProductionLive trafficProduction keysOptimized 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 overrides
config/
├── mistral/
│   ├── base.ts           # Shared configuration
│   ├── development.ts    # Dev overrides
│   ├── staging.ts        # Staging overrides
│   └── production.ts     # Prod overrides

Step 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)**
```yaml
MISTRAL_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**
```bash
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**
```bash

Store secrets

Store secrets

aws secretsmanager create-secret
--name mistral/production/api-key
--secret-string "your-api-key"
aws secretsmanager create-secret
--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

```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
undefined
aws secretsmanager get-secret-value
--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
undefined

Store 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"

```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"

```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

错误处理

IssueCauseSolution
Wrong environmentMissing NODE_ENVSet environment variable
Secret not foundWrong secret pathVerify secret manager config
Config validationInvalid settingsUse Zod schema validation
Cross-env leakMissing guardsAdd 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