Discourse AI - 웹 아티팩트

AI 아티팩트란?

AI 아티팩트는 사용자가 Discourse 게시글 내에서 동적인 웹 기반 컴포넌트를 생성, 임베드 및 상호작용할 수 있도록 해주는 강력한 도구입니다. 이러한 컴포넌트는 커스텀 HTML, CSS, JavaScript를 포함할 수 있으며, 다음과 같은 다양한 사용 사례를 지원합니다:

  • 인터랙티브 퀴즈 또는 양식 임베드.
  • 풍부한 그래픽과 애니메이션을 통한 데이터 시각화.
  • 경량 웹 애플리케이션 또는 도구 통합.
  • 웹 프레임워크, JavaScript 라이브러리 등에 대한 학습 도구.

AI 아티팩트는 상호작용성을 추가하면서 안전한 브라우징 경험을 보장함으로써 Discourse 게시글을 자연스럽게 향상시킵니다.


사이트 설정

관리자는 여러 설정을 구성할 수 있습니다:

1. 기능 활성화

  • 설정: discourse_ai_enabled
    • AI 아티팩트가 작동하려면 이 전역 설정이 활성화되어 있는지 확인하십시오.

2. 보안 모드

  • 설정: ai_artifact_security
    • 옵션:
      • disabled: 아티팩트 시스템 비활성화
      • lax: 사용자 상호작용 없이 아티팩트가 게시글에 자동으로 표시됩니다.
      • hybrid: 기본적으로 실행을 위해 클릭이 필요하지만, 게시글 작성자는 임베드 마크업에 data-ai-artifact-autorun을 추가하여 특정 아티팩트가 즉시 실행되도록 할 수 있습니다.
      • strict: 사용자가 브라우저에서 “보기” 또는 “실행” 버튼을 클릭하여 아티팩트를 명시적으로 활성화해야 합니다. 보안에 민감한 환경에서 이 설정을 권장합니다. (기본값)

3. 아티팩트 생성자 접근 권한

  • 기본적으로 아티팩트 생성자 에이전트스태프 사용자만 사용할 수 있습니다. 이 제한은 신뢰할 수 있는 개인만 아티팩트를 생성할 수 있도록 하여 부적절하거나 악의적인 사용 위험을 최소화합니다.
  • 더 넓은 접근이 필요하면 사이트 관리자가 수동으로 권한을 구성해야 합니다.

게시글에서 AI 아티팩트 사용

아티팩트는 요청 시 아티팩트 생성자 에이전트에 의해 자동으로 생성됩니다.

위 아티팩트는 GPT-4o와 anime.js 라이브러리를 사용하여 생성되었습니다

생성된 아티팩트는 기본적으로 작성자와 아티팩트 생성자 에이전트에게만 비공개입니다. AI 대화를 공유할 수 있는 권한이 있는 사용자(ai bot public sharing allowed groups에 속한 사용자)는 대화를 공유하여 아티팩트를 공개로 만들 수도 있습니다.

공유가 완료되면 다음 HTML 마크업을 사용하여 게시글에 렌더링할 수 있습니다:

<div class="ai-artifact" data-ai-artifact-version="3" data-ai-artifact-id="71"></div>

(여기서 버전과 아티팩트 ID는 사용자의 버전화된 아티팩트 정보입니다)

보안 고려 사항

AI 아티팩트는 커스텀으로 작성된 HTML, CSS, JavaScript를 실행할 수 있으므로 Discourse는 견고한 안전 장치를 구현했습니다:

1. iFrame 샌드박스 처리

  • 아티팩트는 sandbox 속성을 가진 격리된 iframe 컨테이너 내에서 렌더링되어 잠재적으로 위험한 작업을 제한합니다:
    • 크로스 사이트 스크립팅.
    • 외부 사이트 또는 API에 대한 접근.

2. 콘텐츠 보안 정책 (CSP)

3. 보안 모드

  • Strict 모드: 아티팩트를 완전히 신뢰할 수 없는 환경에서 권장됩니다. 사용자는 렌더링 전에 브라우저에서 아티팩트를 수동으로 활성화해야 합니다.

4. 접근 및 권한

  • 아티팩트는 다음 사용자만 볼 수 있습니다:
    • 생성자.
    • 관련 게시글(예: 개인 메시지)을 볼 권한이 있는 사용자.
  • 공개 아티팩트는 AI 대화를 공유하여 명시적으로 공개로 표시되어야 합니다.

5. 길이 제한

  • 아티팩트의 HTML, CSS, JavaScript 크기는 각각 64KB로 제한됩니다. 이를 통해 컴포넌트가 경량을 유지하고 사용자나 시스템에 부담을 주지 않도록 합니다.

아티팩트 저장소

웹 아티팩트는 선택적으로 사용자별 데이터를 저장할 수 있습니다. 이렇게 하려면 아티팩트 생성자에게 “사용자 저장소 사용” 또는 유사한 지시를 하십시오.

이 시스템은 키, 값 쌍을 저장할 수 있습니다:

  • 비공개 (관리자와 특정 사용자만 볼 수 있음)
  • 공개 (익명 사용자를 포함한 모든 사용자에게 표시됨)

키 값 쌍은 아티팩트가 유래한 게시글에 대해 보안 처리되지만, 아티팩트를 공개적으로 공유하면 모든 사용자에게 키 추가가 허용됩니다.

저장을 제어하려면 숨겨진 설정을 사용할 수 있습니다:

  • ai_artifact_kv_value_max_length (기본적으로 항목은 5000자 이하만 허용)
  • ai_artifact_max_keys_per_user_per_artifact (기본값 100)

FAQ

누가 AI 아티팩트를 생성할 수 있나요?

기본적으로 스태프 사용자(예: 관리자 또는 모더레이터)만 아티팩트 생성자 에이전트를 통해 아티팩트를 생성할 수 있습니다. 이 에이전트는 HTML, CSS, JavaScript를 사용하여 인터랙티브 웹 위젯을 설계하는 과정을 단순화합니다.

아티팩트를 클릭하면 어떻게 되나요?

  • lax 모드에서는 아티팩트가 자동으로 표시됩니다.
  • hybrid 모드에서는 기본적으로 클릭이 필요하지만, 임베드에 data-ai-artifact-autorun이 포함되어 있으면 자동 실행됩니다.
  • strict 모드에서는 “실행” 버튼을 클릭하면 아티팩트가 활성화되어 브라우저에서 로드됩니다.

AI 아티팩트는 안전한가요?

네. AI 아티팩트는 엄격하게 제어된 환경에서 실행됩니다:

  • 샌드박스에 격리되어 Discourse 애플리케이션이나 사용자 컨텍스트와 직접 상호작용할 수 없으며, iframe 메시징을 통해서만 가능합니다.
  • strict 모드는 활성화에 대한 제어권을 제공합니다.
  • 아티팩트는 기본적으로 비공개이며, 전역 접근을 허용하려면 능동적으로 공유해야 합니다.

아티팩트의 소스 코드를 볼 수 있나요?

네. Discourse AI가 아티팩트를 생성할 때 전체 마크업, CSS 및 JavaScript를 포함합니다.

어떤 LLM이 지원되나요?

아티팩트는 구성한 모든 LLM을 사용하여 생성할 수 있지만, 다양한 LLM은 아티팩트 생성에 특화되어 더 세밀하게 조정되어 있습니다.

o3, Anthropic Claude Sonnet 3.7 - 4.0, GPT-4.1, Gemini Pro 2.5 등에서 좋은 결과를 확인했습니다. 일반적으로 더 고급 모델일수록 더 잘 작동합니다.

아티팩트 생성에는 시행착오의 측면이 크므로, 실험이 핵심입니다.

23개의 좋아요

It’d be really neat to have slightly more granular control over artifact privacy so that they can be shared only with certain groups. Quite similar to how category permissions currently work :smiley:

I think that if you add the group to the bot pm it may work?

1개의 좋아요

I’m gonna test it out and report back here. I have a niche use case that requires artifacts to be accessible only to one group in one private category

1개의 좋아요

So I tagged the Web Artifact Creator bot in a new topic in a private category which the group has access so it can make an artifact only viewable to me and that particular group. However the artifact iframe window only shows that default " Oops! That page doesn’t exist or is private." that pops up when a user doesn’t have access to a particular page

So I made a data explorer query to check who could view that topic and the users in that group that should be able to see the artifact are indeed shown to be able to view it according to the database.

So perhaps this is a bug?

My SQL query
-- [params]
-- int :artifact_id = 22

WITH artifact_info AS (
  SELECT 
    a.id,
    a.user_id as creator_id,
    a.post_id,
    p.topic_id,
    t.category_id,
    t.archetype,
    c.read_restricted,
    t.title as topic_title
  FROM ai_artifacts a
  LEFT JOIN posts p ON a.post_id = p.id
  LEFT JOIN topics t ON p.topic_id = t.id
  LEFT JOIN categories c ON t.category_id = c.id
  WHERE a.id = :artifact_id
),
users_with_access AS (
  -- Creator always has access
  SELECT 
    ai.creator_id as user_id,
    'Creator' as access_reason
  FROM artifact_info ai
  
  UNION
  
  -- Users with access to private messages
  SELECT 
    tau.user_id,
    'Private Message Access' as access_reason
  FROM artifact_info ai
  JOIN topic_allowed_users tau ON ai.topic_id = tau.topic_id
  WHERE ai.archetype = 'private_message'
  
  UNION
  
  -- Group members with access to private messages
  SELECT 
    gu.user_id,
    'Private Message Group Access' as access_reason
  FROM artifact_info ai
  JOIN topic_allowed_groups tag ON ai.topic_id = tag.topic_id
  JOIN group_users gu ON tag.group_id = gu.group_id
  WHERE ai.archetype = 'private_message'
  
  UNION
  
  -- Users with access to restricted categories
  SELECT 
    gu.user_id,
    'Category Group Access' as access_reason
  FROM artifact_info ai
  JOIN category_groups cg ON ai.category_id = cg.category_id
  JOIN group_users gu ON cg.group_id = gu.group_id
  WHERE ai.read_restricted = true
    AND ai.archetype != 'private_message'
    AND cg.permission_type IN (1, 2) -- full access or create/reply/see
  
  UNION
  
  -- All users if topic is public (not restricted and not private message)
  SELECT 
    u.id as user_id,
    'Public Access' as access_reason
  FROM artifact_info ai
  CROSS JOIN users u
  WHERE (ai.read_restricted = false OR ai.read_restricted IS NULL)
    AND (ai.archetype != 'private_message' OR ai.archetype IS NULL)
    AND u.active = true
)

SELECT 
  u.id as user_id,
  u.username,
  u.name,
  u.trust_level,
  uwa.access_reason,
  ai.topic_title
FROM users_with_access uwa
JOIN users u ON uwa.user_id = u.id
CROSS JOIN artifact_info ai
WHERE u.active = true
ORDER BY u.username