# AI 어시스턴트

## Content

SpreadJS AI 기능은 스프레드시트의 데이터와 구문 분석 기능을 AI 모델에 제공하여 보다 정확하고 스프레드시트에 특화된 응답을 생성할 수 있도록 지원하는 프레임워크를 제공합니다.

## 설치 및 설정

### AI 기능 추가

SpreadJS에서 AI 기능을 사용하려면 프로젝트에 AI 스크립트를 포함해야 합니다.

#### 헤더 참조 방식

```javascript
<script src="gc.spread.sheets.ai.x.x.x.min.js"></script>
```

#### 모듈 방식

```auto
import '@mescius/spread-sheets-ai-addon';
```

### 컨텍스트 인텔리전스

SpreadJS는 워크시트 데이터를 지능적으로 추출 및 정리하여 AI 모델에 관련된 컨텍스트를 제공하므로 보다 정확한 출력을 생성합니다.
**예시 시나리오:**

* 컨텍스트 없이: `=SUM(A1:A10)`
* 컨텍스트 포함: `=SUM(table1[sales])`

## AI 모델 통합 방식

SpreadJS는 AI 모델에 연결하기 위한 유연한 통합 방식을 제공합니다.

### 1\. 보안 백엔드 프록시

API 키를 노출하지 않으려면 요청을 서버로 전송하고 응답만 반환하도록 설정할 수 있습니다.
가장 안전한 방식 - API 키를 서버 측에 보관합니다.

#### 프론트엔드 구현

```auto
const backendAIProxy = async (request) => {
    // SpreadJS 메타데이터 추가
    request.metadata = {
        spreadsheetId: workbook.getActiveSheet().name(),
        userId: currentUser.id,
        timestamp: new Date().toISOString()
    };
    
    const response = await fetch('/api/spreadjs-ai', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-Request-ID': generateUUID()
        },
        body: JSON.stringify(request)
    });
    
    if (!response.ok) {
        const error = await response.json();
        throw new Error(error.message || 'AI request failed');
    }
    
    return response;
};

workbook.injectAI(backendAIProxy);
```

#### 백엔드 구현 (Node.js):

```auto
const { OpenAI } = require('openai');
const express = require('express');
const app = express();

// AI 클라이언트 초기화
const aiClient = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
    organization: process.env.ORG_ID,
    timeout: 30000
});

// AI 프록시 엔드포인트
app.post('/api/spreadjs-ai', async (req, res) => {
    try {
        // 1. 유효성검사 request
        if (!req.body.messages || !Array.isArray(req.body.messages)) {
            return res.status(400).json({ error: 'Invalid request format' });
        }

        // 2. 사용자 지정 로직과 함께 프로세스 요청
        const completion = await aiClient.chat.completions.create({
            model: req.body.model || 'gpt-4-turbo',
            messages: req.body.messages,
            temperature: req.body.temperature || 0.5,
            max_tokens: req.body.max_tokens || 1000,
            stream: false
        });

        // 3. 로그 분석
        logAnalytics(req.body.metadata, completion.usage);

        // 4. 서식화된 response 반환
        res.json({
            success: true,
            data: completion.choices[0].message.content,
            usage: completion.usage
        });
        
    } catch (error) {
        console.error('AI Processing Error:', error);
        res.status(500).json({ 
            error: error.message,
            type: error.type || 'ai_service_error' 
        });
    }
});
```

### **2\. 직접 API 구성**

HTTP 요청 본문에 AI 구성을 노출하는 것에 문제가 없다면(API 키 공개는 권장되지 않음), 구성 정보를 환경 변수로 주입할 수 있습니다.

```auto
// SpreadJS 워크북 초기화
const workbook = new GC.Spread.Sheets.Workbook('ss');

// AI 서비스 자격 정보를 직접 구성
workbook.injectAI({
    model: 'gpt-4-turbo',  // 사용할 AI 모델 지정
    key: 'sk-your-api-key-here',  // API 키
    basePath: 'https://api.openai.com/v1',  // API 엔드포인트

    // 선택적 고급 매개변수
    organization: 'your-org-id',  // OpenAI 조직 ID
    timeout: 30000,  // 요청 타임아웃(ms)
    defaultTemperature: 0.7  // 기본 창의성 수준
});
```

### 3. **사용자 정의 클라이언트 측 핸들러**

HTTP 요청 본문에 AI 구성을 노출하는 것에 문제가 없지만, 요청 본문에 민감한 데이터가 포함되어 있는지 확인하고 데이터를 정제(cleaning)하는 등의 작업을 수행하고 싶은 경우, 아래와 같이 처리할 수 있습니다.

```auto
const aiHandler = async (requestConfig) => {
    // 1. 필요한 모델 구성 추가
    requestConfig.model = 'gpt-4-turbo';

    // 2. 데이터 정제 예시
    const sanitizedMessages = requestConfig.messages.map(msg => ({
        ...msg,
        content: msg.content.replace(/credit-card-\d{4}/g, '****')
    }));

    // 3. 사용자 정의 헤더 및 매개변수
    const requestOptions = {
        method: 'POST',
        headers: {
            'Authorization': `Bearer ${API_KEY}`,
            'Content-Type': 'application/json',
            'X-SpreadJS-Version': '16.0.0'
        },
        body: JSON.stringify({
            ...requestConfig,
            messages: sanitizedMessages
        })
    };
    
    // 4. 재시도 로직을 포함한 에러 처리
    let retries = 3;
    while (retries > 0) {
        try {
            const response = await fetch('https://api.openai.com/v1/chat/completions', requestOptions);
            if (!response.ok) throw new Error(`HTTP ${response.status}`);
            return response;
        } catch (error) {
            if (--retries === 0) throw error;
            await new Promise(resolve => setTimeout(resolve, 1000));
        }
    }
};

workbook.injectAI(aiHandler);
```

## **언어 지역화**

SpreadJS는 워크북의 현재 언어를 기준으로 AI 응답 언어를 자동 요청합니다:

```auto
let culture = GC.Spread.Common.CultureManager.culture(); // 예: 'ja-jp'
let language = GC.Spread.Common.CultureManager.getCultureInfo(culture).displayName // 예: 'Japanese (Japan)'

// 프롬프트 내에서 사용 예시
// 'please return the answer by this language: ' + language;
```

## **보안 모범 사례**

**1\. 데이터 보호**

* 민감한 스프레드시트 데이터를 항상 정제(sanitize).
* 콜백에서 필드 제거(redaction)를 고려.

**2\. 자격 증명 보안**

* 클라이언트 측 코드에서 API 키를 직접 노출하는 것은 권장되지 않습니다.
* 프로덕션 환경에서는 서버 프록시(proxy)를 사용.

**3, 검증**

* AI가 생성한 모든 수식/콘텐츠를 검증.
* 출력물 정제를 구현.

>type=warning
> AI 생성 콘텐츠에 대한 면책 조항
> **1\. 콘텐츠 생성 위험성**
> 본 서비스는 사용자가 주입한 제3자 AI 모델을 활용하여 출력을 생성합니다. 모델의 구조와 학습 데이터의 한계로 인해 결과물에는 부정확한 내용, 누락 또는 오해의 소지가 있을 수 있습니다. 저희는 프롬프트 엔지니어링과 기술적 제약을 통해 출력을 최적화하고 있지만, 모델 결함으로 인한 오류 위험을 완전히 제거할 수는 없습니다.
> **2\. 사용자 검증 의무**
> 이 서비스를 사용하는 경우, 다음 사항에 동의한 것으로 간주됩니다:
>
> * 생성된 모든 콘텐츠를 수동으로 검토할 것
> * 검증되지 않은 결과를 법률, 의료, 금융 등 고위험 시나리오에서 사용하지 않을 것
> * 생성된 콘텐츠에 의존해 발생한 직접적/간접적 손해에 대해 당사에 책임을 묻지 않을 것
>
> **3\. 기술적 한계**
> 당사는 다음 사항에 대해 책임지지 않습니다:
>
> * 제3자 모델 결함 또는 논리 오류로 인한 출력 실패
> * 오류 복구 시도 실패
> * 현재 AI 기술의 기술적 제약
>
> **4\. 지적 재산권 준수**
> 사용자는 다음 사항을 보장해야 합니다:
>
> * 주입된 모델/콘텐츠가 제3자의 권리를 침해하지 않을 것
> * 불법 또는 민감한 자료를 서비스에 처리하지 않을 것
> * 모델 제공자의 지식재산권 약관을 준수할 것
>
> **5\. 약관 업데이트**
> 당사는 다음과 같은 경우 약관을 수정할 권리를 보유합니다:
>
> * 기술 발전(예: 새로운 AI 안전 프로토콜)
> * 규제 변경(예: AI 거버넌스 프레임워크 갱신)
> * 서비스 아키텍처 개선