Tendril – 스스로 도구를 만들고 등록하는 Self-extending Agent
Tendril – a self-extending agent that builds and registers its own tools
TL;DR Highlight
Tendril은 요청받은 작업에 필요한 도구가 없으면 직접 코드를 작성해 등록하고 재사용하는 자기 확장형 AI 에이전트 패턴의 레퍼런스 구현체다. 매 세션마다 도구 레지스트리가 쌓여 점점 더 빠르고 효율적으로 작동한다.
Who Should Read
LLM 기반 에이전트를 개발 중인데 매 세션마다 같은 문제를 반복해서 풀거나 토큰을 낭비하는 상황에 처한 백엔드/풀스택 개발자. 에이전트가 도구를 언제, 어떻게 써야 하는지 설계 고민을 하고 있는 AI 애플리케이션 개발자.
Core Mechanics
- Tendril은 'Agent Capability Pattern'의 레퍼런스 구현체다. 에이전트가 요청을 받으면 먼저 기존 도구 레지스트리를 검색하고, 없으면 코드를 직접 작성해 등록한 뒤 실행한다. 이미 있는 도구면 재빌드 없이 바로 호출한다.
- 핵심 설계 제약은 '직접 코드 실행 금지'다. 에이전트는 반드시 도구를 등록해야만 실행할 수 있어서, 모든 작업이 자동으로 재사용 가능한 도구로 쌓인다. 이 구조 덕분에 레지스트리가 세션을 넘어 누적된다.
- 에이전트 루프의 핵심은 3개의 부트스트랩 도구(searchCapabilities, registerCapability, execute)뿐이다. 나머지는 에이전트가 스스로 만든다. AWS Strands TypeScript SDK와 Bedrock(Claude Sonnet)으로 구동된다.
- 도구 실행은 Deno 서브프로세스로 샌드박스 처리된다. 데스크탑 셸은 Tauri + React로 만들어져 있다.
- 로컬 오픈소스 모델 5개(Qwen3-8B, Gemma 4, Mistral Small 3.1, Devstral Small 2, Salesforce xLAM-2)로 이 self-extending 루프를 테스트했더니 전부 실패했다. 실패 패턴이 각각 달랐는데, 작성자가 별도 포스트로 정리할 예정이다.
- Tendril이 해결하려는 진짜 문제는 'WHEN 문제'다. 대부분의 에이전트 프레임워크는 도구가 무엇을 하는지(WHAT)와 어떻게 호출하는지(HOW)는 알려주지만, 언제 도구를 써야 하는지(WHEN)에 대한 구조화된 답이 없다. Tendril은 이 판단 로직을 시스템 프롬프트에 규칙으로 명시해 처리한다.
- 레지스트리 구조는 index.json 기반 CRUD로 단순하다. 소스 구조는 agent.ts(에이전트 설정), loop/(tools, prompt, registry, sandbox), transport/(protocol, stream, errors)로 나뉜다.
Evidence
- 레지스트리가 세션이 쌓일수록 노이즈로 가득 찰 것이라는 우려가 나왔다. 대부분의 도구가 특정 작업에 과도하게 특화되어 중복이 생기고 도구 API 간 일관성이 깨질 것이라는 지적이다.
- 실제 현업에서 같은 문제를 겪고 비슷한 해법을 썼다는 경험담이 나왔다. LLM 기반 툴을 운영하면서 '같은 문제를 반복 해결하는 데 토큰 낭비'가 초기 병목이었고, 'Saved Programs'라는 이름으로 유사 시스템을 만들었다고 한다. LLM이 문제를 풀기 전에 위키를 검색하고, 해당 프로그램을 찾으면 재사용하고 없으면 새로 만들어 저장 여부를 사용자에게 묻는 방식이다.
- 비슷한 도구 레지스트리를 먼저 만들었던 개발자가 '제대로 작동시키려면 네트워크 상의 reflection과 타입 시스템이 거의 필수'라는 의견을 공유했다. MCP/Skills 방식은 마크다운 덩어리와 비구조화 JSON이라 통합/발견/사용성이 악몽이며, 결국 언어를 가로지르는 분산 타입 시스템(gluon)을 직접 만들었다고 전했다.
- WHEN 문제를 규칙(if X then Y)으로 코딩하는 방식에 대한 비판이 있었다. 규칙은 금방 낡아버리지만, 현재 상황(무엇을 시도했고, 무엇이 수렴됐고, 작업이 어떤 상태인지)을 묘사해주면 모델이 스스로 판단한다는 경험을 공유했다. Tendril의 시스템 프롬프트가 아직 이 if-X-then-Y 패턴에 머물고 있다는 지적도 함께 나왔다.
- 레지스트리가 커질수록 복잡도 관리가 핵심 과제가 된다는 의견이 있었다. 구체적으로 ①레포가 커질수록 에이전트가 컨텍스트 오염 없이 전체를 이해하게 하는 법, ②시간이 지나도 메모리와 지식을 유지하는 법, ③진화하면서 성능이 퇴보하지 않는지 측정하는 법 세 가지가 난제라고 지적했다. 이에 대해 트리/계층 구조, 캐싱(재귀적 요약 포함)이 부분적으로 효과적이었다는 경험이 공유됐다.
How to Apply
- 매 세션마다 에이전트가 같은 API 호출이나 데이터 처리 코드를 반복 생성해 토큰 비용이 낭비되는 경우, Tendril의 searchCapabilities → registerCapability → execute 3단계 부트스트랩 패턴을 자신의 에이전트에 도입하면 동일 작업을 재빌드 없이 재사용할 수 있다.
- AWS Strands TypeScript SDK와 Bedrock(Claude Sonnet)을 이미 사용 중이라면, Tendril 레포의 tendril-agent/src/ 구조를 그대로 참고해 capability registry(index.json CRUD)와 Deno 샌드박스 실행 레이어를 붙여볼 수 있다.
- 로컬 오픈소스 모델(Qwen3-8B, Gemma 4 등)로 self-extending 에이전트를 구축하려는 경우, Tendril 작성자의 테스트에서 5개 모델 전부 실패했으므로 현재로서는 Claude Sonnet 수준의 강력한 모델이 필요하다는 점을 아키텍처 선택 전에 고려해야 한다.
- 세션 종료 후 에이전트가 학습한 내용을 다음 세션에 이어가고 싶다면, 댓글에서 언급된 '/learn 커맨드' 방식처럼 세션 끝에 에이전트가 무엇을 잘못했고 어떻게 고쳤는지 문서화하도록 명시적으로 지시하는 루틴을 추가하는 것이 효과적이다.
Code Example
snippet
// Tendril 에이전트 루프 예시 (README 기반)
// 첫 번째 요청: 도구 없음 → 도구 생성 후 실행
You: "fetch the top stories from Hacker News"
Tendril:
→ searchCapabilities("fetch url hacker news") // 레지스트리 검색 → 없음
→ registerCapability(fetch_url, code) // 도구 코드 작성 + 등록
→ execute("fetch_url", {url: "https://..."}) // 등록된 도구 실행
→ "Here are the top stories: ..."
// 두 번째 요청: 도구 재사용
You: "now fetch Lobsters and compare"
Tendril:
→ listCapabilities() // 레지스트리 검색 → fetch_url 발견!
→ execute("fetch_url", {url: "https://lobste.rs"}) // 재빌드 없이 바로 실행
// 디렉토리 구조
// tendril-agent/src/
// ├── agent.ts ← Strands 에이전트 + Bedrock 모델 설정
// ├── index.ts ← 오케스트레이터
// ├── loop/
// │ ├── tools.ts ← 3개 부트스트랩 도구
// │ ├── prompt.ts ← 시스템 프롬프트 (자율 행동 규칙)
// │ ├── registry.ts ← Capability 레지스트리 (index.json CRUD)
// │ └── sandbox.ts ← Deno 서브프로세스 샌드박스 실행
// └── transport/
// ├── protocol.ts ← ACP JSON-RPC over stdio
// ├── stream.ts ← SDK 이벤트 → 루프 단계 변환
// └── errors.ts ← 프로바이더 에러 분류Terminology
Agent Capability Pattern에이전트가 작업에 필요한 도구를 스스로 만들고 등록해 재사용하는 설계 패턴. 도구 목록이 고정되지 않고 사용할수록 늘어난다.
bootstrap tools에이전트가 처음 시작할 때 갖고 있는 최소한의 도구 세트. Tendril에서는 검색, 등록, 실행 3개만 있고 나머지는 에이전트가 직접 만든다.
Deno sandboxNode.js의 대안인 Deno 런타임을 서브프로세스로 격리해서 실행하는 방식. 에이전트가 만든 코드가 시스템에 직접 접근하지 못하도록 제한한다.
Strands Agents SDKAWS에서 만든 TypeScript 기반 AI 에이전트 구축 SDK. Bedrock 모델과 연동해 에이전트 루프와 도구 호출을 쉽게 구성할 수 있다.
capability registry에이전트가 만들어둔 도구들의 목록과 메타데이터를 저장하는 저장소. Tendril에서는 index.json 파일로 관리되며 세션 간에 유지된다.
self-extending agent스스로 새로운 기능(도구)을 작성하고 등록해 자신의 능력을 확장할 수 있는 에이전트. 사람이 도구를 미리 만들어줄 필요가 없다.