Felo API PlatformFelo API Platform

오피스

리서치 페이지를 슬라이드 덱으로 바꾸기

페이지를 추출해 LiveDoc 맥락으로 저장하고 PPT Task API가 deck을 만드는 동안 완료 링크를 폴링합니다.

소요 시간15분난이도초급업데이트2026-10-29
대상컨설턴트영업·마케팅내부 도구

프롬프트 복사

대괄호 항목을 바꾼 뒤 Claude Code, Codex 또는 터미널에 접근할 수 있는 AI에 붙여넣으세요. Felo 스킬을 설치하고 크레딧을 쓰기 전에 확인한 뒤 워크플로를 실행합니다.

이 소스를 슬라이드 덱으로 만들어 주세요: [공개 URL 또는 PDF 경로].

대상: [누가 보는가]. 페이지 수: [6–10장]. 언어: [언어]. 테마: [테마명 또는 "default"].

공개 페이지(또는 업로드 파일)에 Web Fetch를 사용하고, 소스를 LiveDoc 컨텍스트로 저장하고, PPT 작업을 만든 뒤 덱이 완성될 때까지 폴링하세요.

다음을 작성해 주세요.
1. 슬라이드 한 장당 한 줄 개요.
2. 생성된 덱 링크.
3. 컨텍스트로 사용한 LiveDoc 링크.

규칙:
- 소스에 없는 사실을 지어내지 마세요. 빈틈은 "소스에 없음"으로 표시하세요.
- PPT 작업은 크레딧을 쓰므로 제출 전에 먼저 물어보세요.
- 소스 URL, 개요, 덱 링크를 함께 보관하세요.
- 워크스페이스 밖에 덱을 게시하거나 공유하지 마세요.
- 개요를 ./deck-outline.md에 쓰고 채팅에서 요약해 주세요.

복사 내용에는 설치 단계와 안전 규칙도 포함됩니다.

완성되는 것

실행 시 예제 출력입니다. 실시간 생성이 아닙니다.

덱 개요 예시(발췌)

소스 -> 덱 개요

  1. 이 보고서가 중요한 이유
  2. 이번 분기에 바뀐 것
  3. 세 가지 고객 세그먼트
  4. 증거가 얇은 곳
  5. 다음에 시험할 것

덱: https://felo.ai/slides/... 컨텍스트: https://felo.ai/livedoc/...

실제 호출

개발자용: 같은 워크플로를 실행 순서대로 담은 복사 가능한 코드.

실제 API 호출 보기
  1. 소스 페이지 추출하기

    Web Fetch로 공개 페이지를 Markdown으로 만들고 제목과 본문을 남깁니다.

    deck.ts
    const BASE = "https://openapi.felo.ai";
    const headers = {
      Authorization: `Bearer ${process.env.FELO_API_KEY}`,
      "Content-Type": "application/json",
    };
    
    async function felo<T>(path: string, body?: unknown): Promise<T> {
      const res = await fetch(`${BASE}${path}`, {
        method: body ? "POST" : "GET",
        headers,
        body: body ? JSON.stringify(body) : undefined,
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<T>;
    }
    
    type ExtractData = { data: { content: string } };
    
    const page = await felo<ExtractData>("/v2/web/extract", {
      url: "https://example.com/research",
      output_format: "markdown",
      with_readability: true,
    });
  2. LiveDoc 맥락으로 저장하기

    LiveDoc을 만들고 소스를 문서 리소스로 추가해 short_id를 받습니다.

    deck.ts
    type LiveDocData = { data: { short_id: string } };
    type ResourceData = { data: { id: string } };
    
    const doc = await felo<LiveDocData>("/v2/livedocs", {
      name: "Quarterly research deck",
      description: "Source material for the next deck",
    });
    
    const resource = await felo<ResourceData>(
      `/v2/livedocs/${doc.data.short_id}/resources/doc`,
      {
        title: "Source page",
        content: page.data.content,
      },
    );
  3. 슬라이드 작업 제출하기

    PPT Task API에 페이지 내용과 LiveDoc short_id를 넘겨 task_id를 받습니다.

    deck.ts
    type PptTaskData = {
      data: { task_id: string; livedoc_short_id: string };
    };
    
    const task = await felo<PptTaskData>("/v2/ppts", {
      query: "Six slides for a product review: findings, evidence, next steps",
      livedoc_short_id: doc.data.short_id,
    });
    
    console.log(task.data.task_id);

    예제 출력

    {
      "data": {
        "livedoc_short_id": "PvyKouzJirXjFdst4uKRK3",
        "ppt_business_id": "BfLPuQKmChk9SPmyQawxgr",
        "task_id": "019cad6d-e874-55ef-d577-686344b5a7e9"
      }
    }
  4. 완료될 때까지 폴링하기

    작업 상태를 조회해 완료되면 슬라이드 링크를 읽습니다.

    deck.ts
    type TaskState = {
      data: { task_status: string; ppt_url?: string; live_doc_url?: string };
    };
    
    async function waitForDeck(taskId: string) {
      for (let attempt = 0; attempt < 40; attempt++) {
        const state = await felo<TaskState>(`/v2/tasks/${taskId}/historical`);
        if (state.data.task_status === "COMPLETED") return state.data;
        if (["FAILED", "EXPIRED", "CANCELED"].includes(state.data.task_status)) {
          throw new Error(`Deck task ${state.data.task_status}`);
        }
        await new Promise((resolve) => setTimeout(resolve, 3000));
      }
      throw new Error("Deck task timed out");
    }
    
    const result = await waitForDeck(task.data.task_id);
    console.log(result.ppt_url);

    예제 출력

    {
      "task_status": "COMPLETED",
      "ppt_url": "https://felo.ai/slides/oM8A9iJHg8dT4ZKgHThQTx",
      "live_doc_url": "https://felo.ai/livedoc/oM8A9iJHg8dT4ZKgHThQTx"
    }

포함되는 것

  • 소스 페이지의 깔끔한 Markdown 추출
  • 재사용 가능한 맥락으로 저장한 LiveDoc
  • 완료 링크를 반환하는 비동기 PPT 작업
  • 공유 전 확인할 슬라이드 개요

하지 않는 것

  • 소스는 공개 페이지나 업로드 파일만. 로그인 전용 페이지는 실패할 수 있음
  • 생성 슬라이드는 소스를 따르며 브랜드 시스템 전체를 덮지 않음
  • 한 번에 deck 하나. 여러 개는 루프 필요
  • 기존 deck 편집이나 시각적 완전 일치를 보장하지 않음
  • deck 게시나 공유는 하지 않음

자주 묻는 질문

URL 대신 PDF를 쓸 수 있나요?

네. PPT 작업을 multipart form data로 바꿔 파일을 보내면 플랫폼이 LiveDoc 리소스로 저장하고 deck을 만듭니다.

테마를 고를 수 있나요?

네. 먼저 테마 목록을 가져오고 작업 생성 시 테마 id를 전달합니다.

deck은 얼마나 걸리나요?

비동기 작업입니다. 작업 기록을 완료까지 폴링하며 긴 deck은 짧은 deck보다 오래 걸립니다.

기존 deck을 편집하나요?

아니요. 소스에서 새 deck을 만듭니다. 기존 deck 편집은 다른 워크플로입니다.

deck 하나 비용은?

슬라이드 생성은 사용량 기반 크레딧입니다. 현재 요금은 가격 페이지에 있고 프롬프트는 쓰기 전에 승인을 요청합니다.

소스를 재사용할 수 있나요?

네. LiveDoc이 소스를 저장하며 이후 deck이나 mindmap에서 short_id를 재사용합니다.

관련 워크플로

내 방식으로 바꾸기

같은 레시피를 실제 배포 방식에 맞게 조정합니다.

PDF 소스로 바꾸기

multipart로 PDF를 업로드하면 먼저 LiveDoc 리소스로 저장됩니다.

테마 지정하기

사용 가능한 테마를 나열하고 작업 생성 시 테마 id를 전달합니다.

다음 deck에 재사용하기

같은 LiveDoc short_id로 새 PPT 작업을 만듭니다.

이 레시피의 배경이 되는 참고 페이지와 다음에 볼 곳.