OpenAI API 클라우드 파일 첨부

Dorong·6일 전
0

AI

목록 보기
1/1
  • openAI API를 활용해 문서를 작성하는 프로젝트를 진행하는 과정에서 파일을 분석해 해당 내용을 기반으로 작성하는 부분이 있었음
  • 일반적인 대화형 및 이미지 첨부는 해봤는데, 파일 첨부는 처음이기도 했고 생각보다 삽질을 하는 바람에 기록을 남김 허헣
  • 참고로 구현환경은 nest.js임

파일 생성(files.create)

  • 일반적으로 우리가 사용하는 chatGPT UI와는 다르게, 파일 업로드에는 openai platform의 storage에 파일을 추가하는 과정이 불가피함.
  • 이미지의 경우 url로 직접 넘길 수도 있지만, 파일은 그 방식이 불가함.
  • 보통 예시로 많이 보이는 fs를 통해 파일을 직접 업로드 하는 방식이 아니라, cloud 등에 있는 파일의 url을 통해 업로드 하는 방법을 사용함.
  • openAI sdk의 files.create를 사용했고, 해당 함수는 결과값으로 업로드된 file의 정보를 반환함.
 async uploadFile(fileDetail: InformationFileDTO): Promise<string | null> {
        try {
            const response = await this.httpService.axiosRef.get(fileDetail.urls[0], {
                responseType: 'arraybuffer',
            });
            const fileExtension = fileDetail.urls[0].split('.').pop() || 'txt';
            let fileType = ''
            switch (fileExtension) {
                case 'docx': {
                    fileType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                    break;
                }
                case 'doc': {
                    fileType = 'application/msword';
                    break;
                }
                default: {
                    fileType = 'application/pdf';
                }
            }
            console.log(`확장자 포함 파일명: ${fileDetail.name}.${fileExtension}, MIME 타입: ${fileType}`);
            const file = new File([response.data], `${fileDetail.name}.${fileExtension}`, { type: fileType });
            const uploaded = await this.openai.files.create({
                file: file,
                purpose: 'assistants'
            })
            return uploaded.id;
        } catch (error) {
            console.error(`파일 처리 중 오류 발생: ${error.message}`);
            return null;
        }
    }
  • nest.js 내당 httpModule을 사용해서 파일을 불러왔음
  • 파일을 File 객체로 생성하고 있는데, 이는 브라우저에서 주로 사용하는 방법인거? 아는데 이 방법으로만 성공해서 일단 이렇게 두었음.. 향후 개선의 여지가 아주 많다..
    +) fs를 활용한 임시 파일 저장 및 buffer를 사용한 stream 방식 등도 시도해 봤지만, openai의 Uploadable 형식에 맞지 않아 실패함
  • 데이터 DTO에 정의된 name에 확장자 명이 포함이 안되어있었는데, files.create에서 파일에 확장자 명이 없으면 Openai Storage에서 mimeType을 인식하지 못한다.(None으로 나옴)
  • 그러니 꼭 파일 확장자명이 포함된 이름을 사용할것!
  • 추가적으로 openAI API로 hwp, hwpx 파일을 업로드해 사용하는 것은 🚧불가능🚧 하다.
    => 혹시라도 방법을 찾고있다면 고생은 이미 제가 해봤으니 조속히 다른 길을 찾으시길..

파일 첨부해서 질문하기

  • 파일 첨부의 경우 일단 chat.completion을 기반으로 했음
  • 이 경우 우리가 사용하는 chatGPT UI에서 파일을 첨부하는 방식과 동일하다고 보면 됨.
    const messageContents: ChatCompletionContentPart[] = [
      {
        type: 'text',
        text: promptTemplate.fileAnalayzeTemplate,
      },
    ];


    const fileData = await Promise.all(
      bmService.files.map(async (file, idx) => {
        const fileDetail = file as unknown as InformationFileDTO;
        const uploadedFileId = await this.uploadFile(fileDetail);
        if (uploadedFileId) {
          console.log(
            `------------파일 업로드 완료: ${fileDetail.name}------------`,
          );
          messageContents.push({
            type: 'file',
            file: {
              file_id: uploadedFileId,
            },
          });
        } else {
          console.warn(`파일 처리 실패: ${fileDetail.name}`);
        }
      }),
    );

    await this.openai.vectorStores.create({
      metadata: {},
    });
    const result = await this.openai.chat.completions.create({
      model: 'gpt-4.1-mini',
      messages: [
        {
          role: 'user',
          content: messageContents,
        },
      ],
      temperature: 0.3,
    });
  • message content에 type을 file로 해서, 이전에 획득한 업로드 파일의 id를 넣어주면 된다.
  • 모델은 가성비 목적으로 4.1-mini를 사용했으며, 큰 의미는 없다.

  • 추가적으로 파일과 프롬프트가 길 경우 RAG 방식을 고려해 볼 수 있겠는데, 그 경우에는 o3와 같은 추론 모델이 강력할 것으로 보이긴 함.
  • 또는 Agent를 기반으로 구현하는 방법도 고려해볼 수 있겠음.
profile
🥳믓진 개발자가 되겠어요🥳

0개의 댓글