Skip to content
언어 기능

생성형 UI

표, 차트, 폼, 차이 비교 등 풍부한 인터랙티브 컴포넌트를 인라인으로 렌더링하는 에이전트 — 텍스트만이 아닙니다. 프론트엔드 코드가 필요 없습니다.

기본 내장
11가지 컴포넌트
커스텀 확장 가능

텍스트를 넘어서

기존 챗봇 UI는 모든 것을 텍스트 말풍선으로 렌더링합니다. 하지만 에이전트는 구조화된 데이터 — 쿼리 결과, 유효성 검사 보고서, 배포 상태, 비교 차이 — 를 생성합니다. 이 모든 것을 마크다운으로 렌더링하는 것은 좋지 않은 경험입니다.

Haira의 생성형 UI는 도구가 출력이 표시되는 방식을 선언적으로 제어할 수 있게 합니다. 데이터베이스 쿼리는 표로 렌더링됩니다. 유효성 검사 결과는 상태 카드로 렌더링됩니다. 배포 파이프라인은 진행 상황 추적기로 렌더링됩니다. 모두 채팅 인라인으로, 프론트엔드 코드 작성 없이.

작동 방식

도구는 ui 모듈을 사용하여 UI 컴포넌트를 반환합니다. 런타임은 모든 결과에 대해 두 가지 작업을 수행합니다:

사용자를 위해
풍부한 컴포넌트
ARP 프로토콜을 통해 프론트엔드로 스트리밍되어 인터랙티브한 표, 카드, 차트 또는 폼으로 렌더링됩니다.
에이전트를 위해
텍스트 요약
LLM이 데이터에 대해 추론하고 다음 단계를 결정할 수 있도록 간결한 텍스트 표현이 전송됩니다.

어느 경로도 희생되지 않습니다. 사용자는 아름다운 표를 보고, 에이전트는 구조화된 데이터를 봅니다.

예제 — UI 출력이 있는 도구
haira
import "ui"

tool query_database(query: string) -> any {
    """Executes a SQL query and displays results."""
    rows, err = postgres.query(db, query)
    if err != nil {
        return ui.status_card("error", "Query Failed", conv.to_string(err))
    }
    return ui.table("Query Results", headers, rows)
}

한 줄로 에이전트에 UI를 활성화합니다:

haira
agent DataExplorer {
    provider: OpenAI
    tools: [query_database, search_data]
    ui: ui
    memory: conversation(max_turns: 30)
}

11가지 기본 컴포넌트

status-card
접을 수 있는 섹션이 있는 성공, 오류, 경고 결과 카드
table
탭과 고정 헤더가 있는 검색 가능하고 스크롤 가능한 데이터 표
code-block
복사 버튼과 여러 탭이 있는 구문 강조 코드
diff
구문 강조가 있는 이전/이후 나란히 비교
key-value
메타데이터 표시를 위한 스타일 값이 있는 속성 목록
progress
단계별 상태가 있는 다단계 파이프라인 추적기
chart
선형, 막대, 파이, 영역, 산점도 데이터 시각화
form
텍스트, 선택, 체크박스, 텍스트영역 필드가 있는 인터랙티브 폼
confirm
파괴적 작업을 위한 예/아니요 확인 대화상자
choices
사용자 선택을 위한 버튼 또는 목록 옵션 선택기
product-cards
전자상거래 및 카탈로그 표시를 위한 이미지 카드 그리드
사용법
haira
import "ui"

ui.status_card("success", "Deploy Complete", "All 3 services updated")
ui.table("Results", ["Name", "Email"], [["Alice", "a@co"], ["Bob", "b@co"]])
ui.key_value("Server Info", {"Region": "us-east-1", "Status": "healthy"})
ui.chart("bar", "Revenue", ["Q1", "Q2", "Q3", "Q4"], [dataset])
ui.confirm("Delete this record?", "Yes, delete", "Cancel")
ui.group(
    ui.status_card("success", "Query Complete", "42 rows"),
    ui.table("Results", headers, rows)
)

자동 생성 웹 UI

모든 Haira 워크플로는 자동으로 웹 UI를 갖습니다. 워크플로를 정의하면 Haira가 폼을 생성합니다:

haira
@webui(title: "File Summarizer", description: "Upload a file and get an AI summary")
@post("/summarize")
workflow Summarize(document: file, context: string) -> { summary: string } {
    content, err = io.read_file(document)
    if err != nil { return { summary: "Failed to read file." } }
    reply, err = Summarizer.ask("Summarize: ${content}")
    if err != nil { return { summary: "AI error." } }
    return { summary: reply }
}

@webui 데코레이터는 제목과 설명을 설정합니다. file 파라미터는 업로드 입력으로 렌더링됩니다. 스트리밍 워크플로 (-> stream)는 전체 채팅 인터페이스를 갖습니다.

스트리밍 채팅 UI

스트리밍 워크플로는 가장 풍부한 경험을 제공합니다 — 실시간 토큰 스트리밍, 도구 실행 카드, 인라인 UI 컴포넌트:

haira
@webhook("/chat")
workflow Chat(message: string, session_id: string) -> stream {
    return Assistant.stream(message, session: session_id)
}

fn main() {
    http.Server([Chat]).listen(8080)
}

채팅 UI는 ARP 프로토콜을 통해 통신합니다 — WebSocket 또는 SSE를 통해 텍스트 델타, 도구 수명 주기 이벤트, 풍부한 컴포넌트 렌더링을 처리합니다.

커스텀 컴포넌트

도메인별 요구 사항을 위해 TypeScript 웹 컴포넌트를 components/ 디렉토리에 추가합니다:

components/gantt-chart.ts
typescript
export class HairaGanttChart extends HTMLElement {
  connectedCallback() {
    this.attachShadow({ mode: "open" });
  }
  setProps(props) {
    // Render your custom UI
  }
}

export default {
  tag: "haira-gantt-chart",
  component: HairaGanttChart,
};

커스텀 컴포넌트는 CSS 커스텀 속성을 통해 Haira의 테마를 상속하며 채팅 메시지가 되는 haira-action 이벤트를 발송할 수 있습니다. 컴파일러가 빌드 시 이를 자동으로 발견하고, 번들링하고, 포함시킵니다.

파이프라인

1
도구
ui.* 함수를 통해 타입화된 데이터 반환
2
런타임
WebSocket 또는 SSE를 통해 ARP 메시지 내보냄
3
프론트엔드
채팅 인라인에 일치하는 컴포넌트 렌더링

별도의 프론트엔드 저장소 없음. 유지할 API 클라이언트 없음. 설치할 컴포넌트 라이브러리 없음. 하나의 .haira 파일, 하나의 바이너리, 완전한 UI.

Released under the Apache-2.0 License.