원문 캡처 · tanstack.com
원문 캡처 · tanstack.com

TanStack AI가 안정화된 핵심 API를 갖춘 1.0을 출시했다. 새 에이전트 하네스는 실험 단계이며, 제공업체·프레임워크·샌드박스·통신 프로토콜을 사용자가 선택하는 방향은 유지한다.

1년도 채 되지 전 TanStack AI는 chat() 함수와 제공업체 네 곳, 그리고 종속되지 않도록 하겠다는 약속으로 시작했다. 이후 채팅, 도구, 미디어, MCP, 영속성, 샌드박스, 에이전트를 다루는 도구 모음으로 확장됐다. 현재 제공업체 어댑터는 23개이며 UI 프레임워크는 여덟 개다. 140명 넘는 사람이 개발에 참여했다.

채팅은 시작점일 뿐 전체 앱일 필요는 없다. 편집기에 이미지 생성을 넣거나 음성을 인터페이스로 쓰고, 사용자가 다른 일을 하는 동안 계속 작동하는 에이전트를 만들 수 있다. TanStack AI는 기존 앱의 기능, 독립 제품, 다른 사람이 기반으로 삼을 프레임워크를 만드는 데 활용할 수 있다. 직접 코드를 작성하거나 코딩 에이전트에 만들고 싶은 것을 설명하는 경우 모두를 대상으로 한다.

1.0에서 달라진 점

1.0은 개발자가 기반으로 삼는 API를 공식적으로 안정화한다는 약속이다. 핵심 API는 안정 버전으로 프로덕션에 사용할 수 있지만, 새 하네스 API는 실험적이다.

이미 TanStack AI를 사용하는 앱에는 새로운 개념이 추가되지 않았다. 0.x에서 폐기 예정으로 표시한 API를 모두 제거했으며, 대체 API는 0.x에서도 이미 제공됐다. 폐기 경고에 따라 코드를 업데이트했다면 대부분의 변경을 마친 셈이다.

  • 업그레이드할 때 안정 버전인 @tanstack/ai* 패키지를 함께 1.0으로 올려야 한다. 1.0 클라이언트에는 1.0 서버가 필요하다. 실험적인 하네스 패키지는 계속 0.x를 사용한다.
  • 새 에이전트 하네스는 예외로, API가 실험적이며 변경될 수 있다.

TanStack AI가 알파에서 1.0에 이르기까지 거친 주요 단계는 다음과 같다.

알파와 1.0의 지원 범위는 다음과 같다.

항목알파1.0
제공업체 어댑터4개23개, 모든 OpenAI 스타일 API용 openaiCompatible 포함
UI 프레임워크React, Solid, vanilla JSReact, Vue, Solid, Svelte, Preact, Angular, Octane, Remix, vanilla JS
코딩 에이전트없음Claude Code, Codex, OpenCode, Grok Build, 모든 ACP 에이전트
샌드박스 제공업체없음11개

엔드투엔드 테스트는 모든 풀 리퀘스트에서 실행된다. 테스트는 실제 API를 호출하지 않고 결정론적 모델 픽스처를 사용해 제공업체 어댑터와 도구 실행 흐름을 확인한다.

RC 이후 추가된 기능

에이전트 기능에는 chat()과 useChat에서 이름이 지정된 하위 에이전트(예: 조사자나 작가)에게 턴을 넘기고 입력 형식과 한도를 지정하는 하위 에이전트, 형식이 지정된 선택·점수·불리언 결정을 위한 decide()가 포함된다. 도구 호출 모델은 필요할 때 SKILL.md 기술을 불러올 수 있으며, Portable Agent Skills는 이를 지원한다. 대화 압축은 긴 대화가 컨텍스트 한도를 넘지 않도록 하며, 제공업체가 자체 압축 기능을 제공하면 이를 사용한다. 컴퓨터 사용 기능은 모델이 스크린샷을 바탕으로 웹페이지를 조작하도록 하며, 동일한 코드가 OpenAI와 Anthropic에서 작동한다.

모델 관련 기능으로는 제공업체마다 같은 방식으로 쓰고 모델별 형식을 적용하는 chat({ reasoning }), 자동 프롬프트 캐싱, 캐시를 잃지 않고 대화 도중 도구나 시스템 프롬프트를 바꾸는 기능, 속도 제한이 걸린 모델 호출을 위한 chat({ retry })가 있다. 대화 기록을 모델 간에 재생해 한 대화를 다른 모델로 옮길 수 있고, 제공업체별 Files API도 하나의 인터페이스로 제공한다.

키와 로그인 기능으로는 defineByok와 키가 포함된 어댑터를 사용해 자신의 API 키를 가져오는 방식이 있다. 사용자는 ChatGPT, GitHub Copilot 또는 OpenRouter로 로그인하거나 Claude OAuth 토큰을 사용할 수 있다. 따라서 로컬 앱 사용자가 API 키를 직접 붙여넣지 않아도 된다.

MCP 기능에는 TanStack 도구를 Claude Desktop, Cursor 등 MCP 호스트에 제공하는 createMCPServer, MCP 클라이언트용 도구 필터·승인·작업 기반 도구가 포함된다. WebMCP는 양방향으로 작동한다. 브라우저 에이전트가 클라이언트 도구를 호출할 수 있고, 채팅은 웹페이지의 도구를 사용할 수 있다.

새 제공업체 어댑터로는 Cloudflare Workers AI와 AI Gateway, Lovable AI Gateway, Azure OpenAI, World Labs Marble, TypeSafe, Ollaya가 추가됐다. Remix 3를 지원하고 Svelte용 개발자 도구를 제공한다. 새 샌드박스 제공업체는 Blaxel, Upstash Box, E2B, boxd, Railway다.

개발과 테스트 기능에는 사용자 정의 어댑터를 사용해 어떤 프레임워크에도 적용하는 형식 지정 헤드리스 채팅 UI 팩토리(사용자 정의 어댑터), 네트워크와 API 키 없이 chat()·도구·미들웨어를 시험하는 fakeText(), 설치한 버전에 맞는 TanStack AI 코드를 Claude Code나 Cursor가 작성하도록 돕는 코딩 보조 도구용 Agent Skills가 있다.

문서와 0.x 업그레이드

TanStack AI는 1.0에 맞춰 직접 작성한 문서 페이지를 모두 다시 썼다. 각 페이지는 문제와 몇 분 안에 복사해 실행할 수 있는 설정으로 시작한다. 세부 내용은 페이지 끝의 고급 항목이나 별도의 고급 문서로 옮겼다. 제공업체 어댑터 문서는 서로 비교하기 쉽도록 같은 순서로 구성했다. 처음 사용하는 사람은 빠른 시작을 따라 약 5분 안에 스트리밍 채팅을 만들 수 있다.

대부분의 앱은 코드 변환 도구(codemod)를 한 번 실행하고 타입 검사를 하면 업그레이드할 수 있다.

  1. 코드 변환 도구를 실행한다. 자주 쓰이는 이름 변경을 자동으로 처리한다.
shell
npx jscodeshift \\
   --parser=tsx \\
   -t https://raw.githubusercontent.com/TanStack/ai/main/codemods/ag-ui-compliance/transform.ts \\
   "src/**/*.{ts,tsx}"
  1. 안정 버전인 @tanstack/ai* 패키지를 모두 1.0으로 올린다. 실험적인 하네스 패키지는 0.x에 둔다. 사용 중이라면 1.0 릴리스가 없는 @tanstack/ai-react-ui, @tanstack/ai-solid-ui, @tanstack/ai-vue-ui를 제거한다.
  2. 타입 검사를 실행하고 각 오류를 업그레이드 가이드를 참고해 수정한다.
  3. 0.x에서 저장한 데이터(채팅, 실행 기록, 파일)가 있다면 배포 전에 가이드의 저장 데이터 이전 단계를 따른다.

변경 가능성이 큰 항목은 다음과 같다.

  • body는 forwardedProps로, conversationId는 threadId로 바뀌었다. 코드 변환 도구가 두 이름을 바꾼다.
  • 브라우저와 서버 모두에서 threadId가 필수다. 어느 쪽도 ID를 자동으로 만들지 않는다. 브라우저에서는 경로나 데이터베이스에 있는 ID처럼 대화마다 안정적인 ID를 전달한다. 서버에서는 클라이언트가 보낸 ID를 전달한다.
diff
  // In the browser
- useChat({ connection })
+ useChat({ connection, threadId: chatId })

  // On the server
  const stream = chat({
    adapter: openaiText('gpt-6.1-sol'),
    messages: params.messages,
-   conversationId: params.forwardedProps.conversationId,
+   threadId: params.threadId,
  })

같은 변경은 ChatClient, useGenerateImage 같은 생성 훅, generateImage() 같은 생성 함수에도 적용된다. 코드 변환 도구는 사용할 ID를 알 수 없으므로 threadId를 추가하지 못한다.

  • addToolApprovalResponse()는 제거됐다. 대신 도구 승인 인터럽트를 해결해야 한다.
diff
- const { addToolApprovalResponse } = useChat({ connection, body: { userId } })
- addToolApprovalResponse({ id, approved: true })
+ const { interrupts } = useChat({
+   connection,
+   threadId: chatId,
+   forwardedProps: { userId },
+ })
+ const approval = interrupts.find((item) => item.kind === 'tool-approval')
+ if (approval?.kind === 'tool-approval') approval.resolveInterrupt(true)
  • ai-react-ui, ai-solid-ui, ai-vue-ui를 사용했다면 각각 @tanstack/ai-react/ui, @tanstack/ai-solid/ui, @tanstack/ai-vue/ui의 createChatHook으로 UI를 만든다.
  • TanStack AI 클라이언트에 데이터를 스트리밍하는 자체 서버를 운영한다면 data: [DONE] 전송을 중단하고 RUN_FINISHED 이벤트로 실행을 끝낸다.

타입 검사를 통과해도 저장된 대화·실행 기록·파일은 이전되지 않는다. 배포 전에 가이드의 저장 데이터 이전 절차를 따라야 한다.

실험 단계인 에이전트 하네스

chat()은 한 번의 요청에 응답하는 기능으로 채팅 상자에 적합하다. 코딩 에이전트, 고객 지원 봇, 미디어 스튜디오에는 작업 중에도 새 메시지를 받고, 다른 에이전트를 실행하며, 배포 후에도 이어지는 하나의 대화가 필요할 수 있다.

이를 위해 TanStack AI는 @tanstack/ai-harness를 만들었다. chat()과 같은 옵션으로 하네스를 한 번 정의하고 대화마다 세션을 연다.

ts
import { createHarnessHost, defineHarness } from '@tanstack/ai-harness'
import { openaiText } from '@tanstack/ai-openai'
import { memoryPersistence } from '@tanstack/ai-persistence'

const assistant = defineHarness({
  name: 'acme/assistant',
  adapter: openaiText('gpt-6.1-sol'),
  systemPrompts: ['You are a helpful travel agent.'],
})

const host = createHarnessHost({ persistence: memoryPersistence() })
const session = await host.open(assistant, { threadId: 'trip-1' })
const plan = session.send('Plan a three-day trip to Lisbon.')
plan.onEvent('TEXT_MESSAGE_CONTENT', ({ event }) => {
  process.stdout.write(event.delta)
})
await session.send('Keep it under 500 euros.', { mode: 'steer' })
await plan

이벤트는 표준 AG-UI 이벤트다. steer 방식은 실행 중인 턴에서 다음 모델 호출이 일어나기 전에 메시지를 합류시키며, 현재 턴이 이미 끝났다면 다음 턴을 시작한다. 후속 메시지는 현재 작업이 끝날 때까지 기다린다.

위 예시는 메모리 내 영속성을 사용한다. 재시작 후에도 복구하려면 데이터를 유지하는 저장소가 필요하다. 호스트가 바뀌어도 메모리 내 하위 에이전트 대기는 이어지지 않는 등 복구 한계가 남아 있다.

세션은 다음 기능을 제공한다.

  • 영속 세션: 모든 스레드에 세션 로그가 있다. 재시작 후에도 유지되는 저장소를 호스트에 지정하면 충돌이나 배포로 중단된 턴을 다음 호스트에서 이어간다. 한 번에 한 호스트만 스레드를 소유한다.
  • 재시작 후에도 유지되는 대기: 승인 요청, 질문, 로그인 요청은 실행을 멈추고 로그에서 답을 기다린다. 재시작 후에도 어느 서버에서든 답변을 처리할 수 있다.
  • 형식이 지정된 에이전트: 코드에서 에이전트를 순차 또는 병렬로 예산·시간 제한과 함께 실행하거나, 모델이 에이전트를 도구로 호출하게 할 수 있다.
  • 플러그인: 도구, 프롬프트, 미들웨어, 명령, 상태를 패키징해 어떤 하네스에도 불러올 수 있다.
  • 여러 사용자 지원: 접근 규칙, 팀이 공유하는 스레드, /connect를 통한 사용자별 제공업체 키를 지원한다.
  • 백그라운드 작업: 워커가 일정, 서버에서 들어오는 입력, 몇 시간 동안 대기하는 도구를 실행한다.

첫 번째 제공 플러그인에는 파일 도구, 위험한 호출에 대한 권한 제어, 스냅샷 등이 있다. 이를 하네스에 넣고 runCli에 전달하면 터미널에서 코딩 에이전트를 실행할 수 있다.

ts
import { homedir } from 'node:os'
import { join } from 'node:path'
import { defineHarness } from '@tanstack/ai-harness'
import {
  compact,
  permissions,
  todos,
  usage,
} from '@tanstack/ai-harness/plugins'
import { projectInstructions } from '@tanstack/ai-harness/plugins/node'
import { snapshots, workspaceTools } from '@tanstack/ai-harness/plugins/coding'
import { runCli } from '@tanstack/ai-harness-cli'
import { openaiText } from '@tanstack/ai-openai'

const root = process.cwd()
const coder = defineHarness({
  name: 'acme/coder',
  adapter: openaiText('gpt-6.1-sol'),
  systemPrompts: ['You are a careful coding agent. Read before you edit.'],
  plugins: () => [
    permissions({ root }),
    workspaceTools({ root }),
    snapshots({ root, dataDir: join(homedir(), '.acme-coder', 'snapshots') }),
    todos(),
    compact({ adapter: openaiText('gpt-6-luna') }),
    usage(),
    projectInstructions({ root }),
  ],
})
process.exitCode = await runCli(coder)

이 구성은 파일 도구, 위험한 호출의 승인 제어, 마지막 턴을 되돌리는 /undo, 할 일 목록, 긴 세션을 압축하는 /compact, 비용을 보는 /usage, 프로젝트 지침을 제공한다. 다만 permissions 플러그인은 샌드박스가 아니다. 도구는 호스트의 권한으로 실행된다.

다른 플러그인도 같은 방식으로 불러올 수 있다. 기술을 슬래시 명령으로 추가하고, 판정 모델이 목표 달성을 확인할 때까지 작업하는 goal(), 컴퓨터 사용, Code Mode, MCP 서버를 사용할 수 있다. 하네스는 코딩 작업을 Claude Code, Codex, Grok Build 또는 ACP 에이전트에 각자의 샌드박스에서 맡길 수도 있다.

하나의 하네스 정의는 터미널, 스크립트와 CI, 웹 앱, 편집기에서 사용할 수 있다.

shell
npx tsx coder.ts                             npx tsx coder.ts -p "Fix the failing test"   npx tsx coder.ts --serve                     npx tsx coder.ts --acp                       npx tsx coder.ts --mcp

--acp와 --mcp는 해당 기능을 사용할 때만 @tanstack/ai-acp와 @tanstack/ai-mcp를 불러온다. 웹 앱에서는 createHarnessHandler가 HTTP로 세션을 제공하고 handleHarnessSocket은 WebSocket으로 제공한다. 실행 경로는 표준 AG-UI를 사용하므로 useChat으로 하네스에 연결할 수 있다. 승인 처리와 페이지 새로고침 후 실행 중인 턴에 다시 합류하는 기능도 지원한다.

하네스는 TanStack AI에서 가장 새로 추가된 부분이라 API가 실험적이다. @tanstack/ai-harness와 @tanstack/ai-harness-cli는 0.x로 배포되며, @tanstack/ai-skills/harness, @tanstack/ai-acp/agent 등 다른 패키지의 하네스 진입점도 실험적이다. 이 API는 마이너 릴리스에서 바뀔 수 있다. 하네스는 안정 버전인 1.0 핵심 기능과 분리돼 있다.

TanStack은 API를 안정화하기 전에 사용자가 하네스를 시험해 볼 수 있도록 공개했다. 첫 하네스 만들기나 코딩 에이전트 만들기 안내를 참고할 수 있다.

업그레이드 후 활용

TanStack AI는 유지관리자 세 명으로 운영되며, 한 줄 수정부터 어댑터 전체 구현까지 143명이 코드에 기여했다. 이슈 제보, 재현 사례 작성, Discord 답변, 제작물 공유도 개발에 도움을 줬다고 밝혔다. OpenRouter는 초기부터 TanStack AI를 지원했다.

앞으로는 안정화된 핵심 API의 불편한 부분을 다듬고, 팀이 채팅 상자·이미지 생성·음성 에이전트·코딩 에이전트 집합 등 AI 기능을 출시하도록 지원할 계획이다. 하네스를 안정화하고 제공업체와 샌드박스를 늘리며 모델 연구소의 새 기능에도 대응할 예정이다.

시작하려면 다음 패키지를 설치한 뒤 빠른 시작을 따르면 된다. OpenAI를 쓰지 않는다면 마지막 패키지를 다른 제공업체 패키지로 바꾸고, React가 아닌 UI 프레임워크를 쓴다면 React 패키지도 해당 프레임워크용으로 바꾼다. 0.x에서 업그레이드하는 경우 업그레이드 가이드를 참고한다.

shell
pnpm add @tanstack/ai @tanstack/ai-react @tanstack/ai-openai

직접 만들거나 코딩 에이전트에게 TanStack AI를 이용해 만들도록 한 뒤 제작물을 공유할 수 있다.