개요
백그라운드에서 실행되는 코딩 에이전트로, PR, 리뷰, 이슈 해결 등의 작업을 자동으로 수행합니다. 다양한 AI 모델을 지원하며 Slack, GitHub, Linear와 통합됩니다. 조직 내부의 싱글 테넌트 배포를 위해 설계되었습니다.
README 미리보기
# Background Agents: Open-Inspect\n\nAn open-source background agents coding system inspired by\n[Ramp's Inspect](https://builders.ramp.com/post/why-we-built-our-background-agent).\n\n## Overview\n\nOpen-Inspect provides a hosted background coding agent that can:\n\n- Work on tasks in the background while you focus on other things\n- Access full development environments (Node.js, Python, git, browser automation, VS Code)\n- Connect from anywhere — web UI, Slack, GitHub PRs, Linear issues, or webhooks\n- Enable multiplayer sessions where multiple people can collaborate in real time\n- Create PRs with proper commit attribution to the prompting user\n- Run on a schedule — cron jobs, Sentry alerts, and webhook-triggered automations\n- Spawn parallel sub-tasks that work in separate sandboxes simultaneously\n- Use your choice of AI model — Anthropic Claude, OpenAI Codex (via ChatGPT subscription), or\n OpenCode Zen\n\n## Security Model (Single-Tenant Only)\n\n> **Important**: This system is designed for **single-tenant deployment only**, where all users are\n> trusted members of the same organization with access to the same repositories.\n\n### How It Works\n\nThe system uses a shared GitHub App installation for git operations (clone, fetch, push). The\ncontrol plane mints short-lived installation tokens server-side and brokers them to sandboxes\nthrough the git credential helper on demand. This means:\n\n- **All users share the same GitHub App credentials** - The GitHub App must be installed on your\n organization's repositories, and any user of the system can access any repo the App has access to\n- **No per-user repository access validation** - The system does not verify that a user has\n permission to access a specific repository before creating a session\n- **GitHub users' OAuth tokens are used for PR creation** - For GitHub logins, PRs are created using\n the user's GitHub OAuth token, ensuring proper attribution and that they can only create PRs on\n repos the
FAQ (5)
문제 해결Claude Opus 4.8/5.5에서 'temperature is deprecated' 또는 'tool_choice type tool not supported' 오류가 발생하는 HTTP 400 classifier 실패는 어떻게 해결하나요?
packages/slack-bot/src/classifier/index.ts 및 packages/linear-bot/src/classifier/index.ts에서 Slack 및 Linear 분류기 요청을 업데이트하세요:
1. temperature: 0을 제거하세요. Claude Opus 4.7+는 기본값이 아닌 temperature 값을 거부합니다.
2. Opus 5.5의 경우, tool_choice: { type: "tool", name: "classify_target" }과 같은 강제 tool choice를 tool_choice: { type: "auto" }로 교체하세요.
3. 프롬프트에서 모델이 classify_target 도구를 반드시 호출해야 한다고 지시하세요.
4. 도구 호출을 생략한 응답에 대해서는 기존의 도구 입력 검증과 target-picker 폴백을 유지하세요.
Opus 4.8은 temperature를 생략하면 강제 도구 사용이 정상적으로 동작하지만, Opus 5.5는 tool 및 any tool-choice 타입이 모두 지원되지 않으므로 auto가 필요합니다. 즉각적인 해결 방법으로, 영향을 받지 않는 기본 모델인 classification_model = "claude-haiku-4-5"로 설정하세요.
문제 해결Slack 또는 Linear에서 생성된 PR이 제 개인 자격 증명 대신 앱/봇 GitHub ID를 사용하는 이유는 무엇인가요?
이 문제는 Better Auth로의 웹 로그인 마이그레이션 이후 발생한 자격 증명 조회 버그로 인해 발생했습니다. Slack, Linear, GitHub 봇 세션은 여전히 레거시 user_scm_tokens 테이블에서 OAuth 토큰을 읽는 반면, 새로운 GitHub 토큰은 Better Auth의 user_identities.access_token 테이블에 저장됩니다. 사용자 토큰을 찾지 못하면 PR 생성이 GitHub App 설치 토큰으로 폴백되었습니다. 이 수정 사항은 라우트 승인 과정에서 설정된 정규 사용자와 그에 연결된 GitHub 계정을 사용하여 봇 서비스 프린시펄을 Better Auth의 신뢰할 수 있는 서버 API를 통해 라우팅하고, GitHub 프로필을 검증하며, user_scm_tokens는 마이그레이션 이전 자격 증명에 대한 폴백으로만 유지합니다. issue #1912에 대한 수정 사항이 포함된 컨트롤 플레인 릴리스로 업그레이드하거나 배포한 다음, 영향을 받은 사용자가 Better Auth에 연결된 GitHub 계정을 보유하고 있는지 확인하세요.
문제 해결이름을 변경한 세션 제목이 'Load more' 페이지의 사이드바에서 이전 이름으로 되돌아가는 이유는 무엇인가요?
이것은 open-inspect의 웹 UI에서 알려진 버그로, PR #2404에서 수정되었습니다(커밋 9eee5a4c02b418fec570581fd85d98e01dbee25e로 main에 머지됨). 근본 원인: useSessionRename이 세션당 하나의 공유 낙관적 제목을 유지했습니다. 열린 세션 페이지의 헤더가 확정된 이름 변경을 따라잡았을 때, 모든 구독자의 낙관적 제목이 지워졌습니다. 'Load more'를 통해 로드된 페이지의 사이드바 행은 React 상태에만 존재하며 다시 가져오지 않으므로, 이름 변경 전의 오래된 제목으로 되돌아갔습니다. 수정 방법: 해당 커밋이 포함된 빌드로 업데이트하세요 — 이 커밋은 useSidebarSessions에 제목 오버레이를 추가하며(읽기 오버레이와 동일한 형태), 이름 변경 결과로부터 작성되고 페이지가 언마운트되거나 다시 가져올 때 삭제됩니다. 다음 명령으로 확인하세요: npm test -w @open-inspect/web -- src/hooks/use-sidebar-title-reconciliation.test.tsx src/hooks/use-session-rename.test.tsx src/hooks/use-sidebar-sessions.test.tsx --maxWorkers=1 (74개의 테스트가 통과해야 합니다).
문제 해결Fable Modal 샌드박스가 이전 스냅샷에서 복원된 후 작업을 복구하려면 어떻게 해야 하나요?
Fable 5.1에서 supervisor.restored_from_snapshot는 세션이 더 오래된 snapshot_image_id를 복원했음을 의미합니다. 복원 경로는 git fetch만 실행하며 git checkout, reset, clean은 실행하지 않습니다. 데이터 손실은 주로 Modal의 2시간 하드 타임아웃이 스냅샷이 생성되기 전에 컨테이너를 종료시키거나, 열린 브라우저 탭이 비활성 스냅샷을 억제하거나, 실패한 스냅샷이 조용히 이전 이미지를 유지하기 때문에 발생합니다.
복구 단계:
1. 마지막 세션 diff 가져오기: GET /sessions/<session_id>/diff를 호출하거나 웹 UI에서 Diff 뷰를 엽니다. session_diff 저장소에는 턴 이후에 캡처된 마지막 추적 파일 및 미추적 파일이 포함되어 있으며, 파일당 512 KiB, 총 1.5 MiB의 제한이 있습니다. 누락된 파일이 있으면 해당 diff를 다시 적용하세요.
2. Cloudflare Worker 로그에서 sandbox.snapshot_saved 이벤트를 검색하고 image_id 값을 확인하세요. 더 새로운 이미지가 저장되었다가 나중에 교체된 경우, 가능하면 해당 이미지에서 수동으로 시작하거나 복원하세요.
3. 세션당 하나의 snapshot_image_id만 유지됩니다. 스냅샷 히스토리 테이블은 없으며, snapshot_saved WebSocket 이벤트는 영속화되지 않습니다.
재발을 방지하려면 긴 턴이나 2시간 샌드박스 제한 전에 Git에 커밋하고 푸시하고, 열린 브라우저 탭이 비활성 스냅샷을 생성한다고 가정하지 말고, Snapshot failed 로그 메시지를 조사하세요. 스냅샷 작업은 300초 후에 타임아웃됩니다. 영구적인 수정은 "Preserve sandbox state before provider expiry" 변경 사항으로, 하드 만료 전에 최소 5분, 기본 10분의 구성 가능한 버퍼를 사용하여 프로바이더 중립적인 최종 보존을 수행합니다.
문제 해결Modal 샌드박스가 무한 루프로 반복적으로 생성되어 예상치 못한 요금이 발생하는 것을 어떻게 막을 수 있나요?
컨트롤 플레인을 issue #1894에 대한 수정 사항이 포함된 릴리스로 업그레이드/배포하세요. 이제 connect 워치독에 의해 이미 실패 처리된 샌드박스의 fatal 보고를 무시하고, 서킷 브레이커가 부팅 실패 횟수를 계산합니다. 이를 통해 느리거나 실패하는 .openinspect/setup.sh가 매 부팅 주기마다 createSandbox를 트리거하는 것을 방지합니다. 즉각적인 해결 방법으로, 샌드박스 생성 실패 시 루프가 중단되도록 Modal 예산 상한/알림을 설정한 다음, setup.sh를 최적화하세요. 비용이 많이 드는 설치 작업을 사전 빌드된 이미지로 옮기거나 종속성을 캐시하여 connect 워치독이 만료되기 전에 부팅이 완료되도록 하세요. 로그에서 setup.complete가 setup.start 뒤에 빠르게 이어지고 exit_code: 0인지 확인하세요.