6장 행동 트리(Behavior Tree)를 활용한 자율 에이전트·로봇 제어 개념 정리
다시 보는 AI Agents in Action개요
행동 트리(Behavior Tree)는 로봇 제어와 게임 AI에서 널리 쓰이는 의사결정 구조로, 여러 개의 행동과 조건을 "트리 구조"로 배치해 어떤 상황에서 어떤 행동을 할지 결정하는 패턴이다. 각 노드는 실행 결과를 "성공(success)" 또는 "실패(failure)"로 반환하며, 이 단순한 규칙을 이용해 꽤 복잡한 행동을 안정적으로 설계할 수 있다.

게임의 NPC(Non‑Player Character)나 자율 로봇, 그리고 최근의 LLM 기반 자율 에이전트 시스템에서 행동 트리는 "무엇을 언제 할지"를 통제하는 상위 제어 장치로 활용된다. 행동 트리는 위에서 아래, 왼쪽에서 오른쪽 순서로 실행되며, Selector, Sequence, Condition, Action, Decorator, Parallel 같은 노드들을 조합해 안정적이고 확장 가능한 에이전틱(agentic) 시스템을 구성하는 데 적합하다.
행동 트리의 기본 개념
행동 트리는 "트리(tree)" 구조를 사용해 에이전트의 의사결정을 표현하는 모델로, 루트(root)에서 시작해 여러 자식 노드를 순차적으로 혹은 조건에 따라 실행한다. 일반적인 프로그래밍에서 if, switch, 반복문이 섞인 복잡한 로직을 작성하는 대신, 행동 트리는 이를 시각적인 노드와 간단한 규칙으로 구조화한다.
행동 트리의 가장 중요한 특징은 로직을 "불리언 값(true/false)"이 아니라 "성공/실패"로 다룬다는 점이다. 각 노드는 실행을 마친 뒤 반드시 성공 또는 실패를 반환하며, 부모 노드는 이 결과를 바탕으로 다음에 어떤 노드를 실행할지 결정한다. 이 덕분에 복잡한 조건식 없이도 흐름 제어를 단순하고 일관되게 유지할 수 있다.
행동 트리는 시간적으로 반복 실행되는 경우가 많다. 예를 들어, 게임 루프나 제어 주기마다 루트 노드에서 트리를 다시 평가하고, 조건과 행동을 재검사하여 최신 상태에 맞는 행동을 선택한다. 이렇게 반복적으로 실행되기 때문에 시스템 상태 변경에 잘 대응하면서도, 트리 구조 자체는 비교적 안정적으로 유지된다.
게임 AI와 로보틱스에서의 활용
게임 AI에서 행동 트리는 주로 NPC의 행동을 결정하는 데 사용된다. 예를 들어, "플레이어를 발견했는가?", "체력이 낮은가?", "엄폐물이 있는가?" 같은 조건을 Condition 노드로 표현하고, "도망간다", "엄폐 후 공격한다", "순찰한다" 같은 행동을 Action 노드로 정의하여, NPC가 상황에 맞게 행동을 선택하도록 만든다.
로보틱스에서는 행동 트리가 더 미시적인 수준에서 사용되는 경우가 많다. 예를 들어, "사과를 감지한다", "사과까지 이동한다", "집게를 열고 닫는다"와 같이 센서와 모터 제어에 가까운 단위 행동을 Action으로 표현하고, 이를 Sequence나 Selector로 엮어 "사과를 집어 들기" 같은 작업을 완성한다. 같은 패턴을 조금 더 큰 단위로 조합하면 "집 안을 청소하기" 같은 상위 행동도 표현할 수 있다.
최근의 LLM 기반 자율 에이전트 시스템에서도 행동 트리는 유용하다. 에이전트가 사용할 수 있는 여러 도구(검색, API 호출, 코드 실행 등)를 Action 노드로 만들고, 현재 목표와 환경 상태를 Condition 노드로 확인한 뒤, 행동 트리 구조에 따라 순서 있게 도구를 사용하도록 설계하면, "자율적으로" 보이지만 예측 가능하고 통제 가능한 에이전트가 된다.
행동 트리의 실행 방식: 위에서 아래, 왼쪽에서 오른쪽
행동 트리는 루트 노드에서 시작해 자식 노드를 탐색하며 실행된다. 기본 규칙은 간단하다. "위에서 아래로 내려가고, 같은 층에서는 왼쪽에서 오른쪽으로" 노드를 검사하고 실행한다. 어떤 노드를 실행할지, 언제 멈출지는 각 노드의 종류(Selector, Sequence 등)에 따라 달라진다.
각 노드가 실행되면 반드시 세 가지 중 하나의 상태를 반환한다고 볼 수 있다.
성공(Success): 노드의 목표를 정상적으로 수행함
실패(Failure): 노드가 목표를 수행하지 못했거나 조건이 충족되지 않음
(필요시) 진행 중(Running): 긴 시간이 필요한 행동이 아직 끝나지 않음 -- 일부 구현에서는 Running 상태를 추가로 사용
Selector나 Sequence 같은 Composite 노드는 자식 노드의 상태를 보고 다음 자식으로 넘어갈지, 부모에게 결과를 반환할지를 결정한다. 이때 "성공/실패"의 의미가 합성되어, 전체 트리의 거동을 만든다.
예를 들어, "사과가 있으면 사과를 먹고, 아니면 배를 먹는다"라는 트리는 대략 이렇게 작동한다. 먼저 "사과를 먹는 Sequence"를 실행해보고 실패하면(사과 없음), Selector는 다음 자식인 "배를 먹는 Sequence"를 실행한다. 만약 둘 다 실패하면 전체 트리는 "먹을 것이 없음"이라는 실패 상태로 종료된다. 이처럼 성공/실패 신호가 위아래로 전달되면서 제어 흐름이 만들어진다.
주요 노드 유형과 역할
행동 트리의 힘은 다양한 역할을 가진 노드들을 조합할 수 있다는 점에서 나온다. 일반적으로 다음 여섯 가지 유형이 기본으로 사용된다.
Selector (Fallback) 노드
Sequence 노드
Condition 노드
Action 노드
Decorator 노드
Parallel 노드
각 노드는 제어 흐름을 만드는 기본 단위이며, 이를 바탕으로 복잡한 의사결정 구조를 구성할 수 있다.
Selector (Fallback) 노드
Selector 노드는 "여러 후보 행동 중에서 하나라도 성공하면 된다"라는 논리를 표현하는 노드다. 흔히 Fallback 노드라고도 부른다. 이 노드는 왼쪽에서 오른쪽 순으로 자식 노드를 실행해 나가다가, 첫 번째로 성공한 자식에서 멈춘다.
동작 방식은 다음과 같이 요약할 수 있다.
첫 번째 자식 노드를 실행한다.
자식이 성공하면, Selector는 즉시 성공을 반환한다.
자식이 실패하면, 다음 자식으로 넘어간다.
모든 자식이 실패했다면, Selector는 실패를 반환한다.
Selector는 기본 전략, 예비 전략, 비상 전략을 순서대로 나열하는 데 유용하다. 예를 들어, "네트워크 API 호출 → 캐시 조회 → 로컬 기본값 사용"을 Selector 아래에 나열하면, 상위 시스템은 "데이터를 얻는 행동 하나"만 생각하면 되고, 실제로 어떤 경로가 사용될지는 Selector가 알아서 결정한다.
Sequence 노드
Sequence 노드는 "여러 행동을 정해진 순서대로 모두 성공시켜야 한다"라는 논리를 표현한다. 즉, AND 연쇄에 가깝다. 자식들을 차례대로 실행하면서 하나라도 실패하면 전체가 실패하고, 모든 자식이 성공해야 비로소 성공을 반환한다.
동작 방식은 다음과 같다.
첫 번째 자식부터 순서대로 실행한다.
자식이 실패하면, Sequence는 즉시 실패를 반환하고 나머지 자식은 실행하지 않는다.
모든 자식이 성공하면, Sequence는 성공을 반환한다.
Sequence는 "준비 → 이동 → 실행 → 마무리" 같은 일련의 절차를 안전하게 수행할 때 쓰인다. 예를 들어 로봇이 "목표 물체 인식 → 접근 경로 계획 → 이동 → 집기"를 순차적으로 수행할 때, 중간 단계가 하나라도 실패하면 전체 시퀀스를 실패로 처리하여 다음 전략(다른 물체 선택, 재탐색 등)으로 넘어가게 만들 수 있다.
Condition 노드
Condition 노드는 말 그대로 조건을 검사하는 노드다. 중요한 점은 일반적인 프로그래밍의 조건문처럼 true/false를 반환하는 것이 아니라, "성공/실패"로 표현된다는 것이다. 따라서 "조건이 참이면 성공, 거짓이면 실패"가 된다.
Condition 노드는 주로 Sequence나 Selector 앞에서 "이 행동을 시도할 자격이 있는가?"를 필터링하는 데 사용된다. 예를 들면 다음과 같다.
"체력이 30% 이하인가?"
"적이 시야 안에 있는가?"
"사과가 존재하는가?"
"인터넷 연결이 가능한가?"
이러한 조건을 통해, 트리 전체가 비정상적인 상황에서 쓸데없는 행동을 시도하지 않도록 막을 수 있다. Condition이 실패하면 그 다음 분기(Selector의 다음 자식)로 자연스럽게 넘어가므로, 복잡한 if‑else 구조 대신 "성공/실패 흐름"으로 제어를 단순하게 유지할 수 있다.
Action 노드
Action 노드는 실제로 무언가를 "하는" 노드다. 로봇에게는 모터를 움직이거나 센서를 읽어들이는 행동일 수 있고, 게임 AI에게는 이동, 공격, 대화 같은 행동일 수 있다. LLM 에이전트에게는 API를 호출하거나, 도구를 사용하거나, 문서를 생성하는 작업 등이 Action 노드에 해당한다.
Action 노드는 실행 후 상황에 따라 성공 또는 실패를 반환한다. 예를 들어, "사과를 잡는다"라는 Action은 그립이 잘 작동하고 사과를 제대로 잡았으면 성공, 미끄러져서 놓쳤다면 실패다. 이 결과는 상위 Sequence나 Selector에게 전달되어 이후 흐름을 결정하게 된다.
Action 노드는 시스템의 "기능"과 행동 트리의 "논리"를 연결하는 다리 역할을 한다. Action을 단순하고 명확하게 정의해 두면, 상위 트리에서는 "이 Action이 성공했는가, 실패했는가"만 신경 쓰면 되므로 설계와 유지보수가 쉬워진다.
Decorator 노드
Decorator 노드는 자식 노드 하나를 감싸서 "언제, 어떻게 실행할지"를 제어하는 노드다. 논리적으로는 if, 반복, 제한, 변환 같은 기능을 수행한다. 주된 역할은 특정 조건이나 정책에 따라 자식 노드의 실행을 허용하거나 차단하는 것이다.
예를 들어, 다음과 같은 Decorator들을 생각할 수 있다.
"조건이 만족될 때만 실행" (Condition을 감싸는 형태)
"최대 N번까지만 재시도"
"일정 시간 제한 내에 끝나지 않으면 실패 처리"
"자식이 실패해도 성공으로 바꾸기(무시)"
이런 Decorator를 사용하면 행동 트리에 "안전장치"를 추가할 수 있다. 자율 에이전트 제어에서는 이를 "제어 장벽(Control Barrier)"처럼 사용해, 에이전트가 바람직하지 않은 행동(예: 과도한 API 호출, 위험한 명령 실행 등)을 실행하지 못하도록 방지할 수 있다.
Parallel 노드
Parallel 노드는 여러 자식 노드를 동시에(또는 논리적으로 동시에) 실행하는 노드다. 로봇이나 게임 AI, 복합 에이전트 시스템에서는 센서 모니터링, 상태 보고, 메인 작업 등을 병렬로 수행해야 할 때가 많은데, 이때 Parallel 노드가 유용하다.
Parallel 노드는 보통 "성공/실패 판단 기준"을 설정할 수 있다. 예를 들면 다음과 같다.
"자식 중 최소 N개가 성공하면 성공으로 간주"
"하나라도 실패하면 전체 실패"
"모든 자식이 끝날 때까지 기다린 뒤, 통계적으로 판단"
예시로, 로봇이 "목표로 이동하는 행동"과 동시에 "장애물 감시 행동"을 병렬로 수행할 수 있다. 이동이 성공해도 장애물 감시에서 위협을 감지하면 전체를 실패로 처리해 긴급 회피로 전환하는 식의 전략이 가능해진다.
성공/실패 기반 제어 흐름의 장점
행동 트리는 불리언 값 대신 성공/실패를 사용하며, Selector·Sequence·Condition·Action·Decorator·Parallel 노드들이 이 값을 주고받으며 제어 흐름을 만든다. 이 방식에는 몇 가지 중요한 장점이 있다.
첫째, 제어 구조가 단순해진다. 모든 노드는 "실행한다 → 성공/실패 반환"이라는 동일한 인터페이스를 가지므로, 상위 노드는 "자식의 결과가 성공인지 실패인지만" 보면 된다. 이는 전통적인 if‑else, switch, 예외 처리 등이 뒤섞인 코드에 비해 이해하기 쉬운 구조를 제공한다.
둘째, 부분 실패를 자연스럽게 처리할 수 있다. 예를 들어 Sequence 중간이 실패하면 즉시 전체 시퀀스가 실패하고, Selector는 자동으로 다른 시도 경로로 넘어간다. 이 과정에서 별도의 오류 코드나 예외를 복잡하게 관리할 필요가 없다. "성공/실패"만으로도 충분한 회복 전략을 설계할 수 있다.
셋째, 재사용성과 확장성이 좋다. 특정 행동 패턴을 하나의 서브트리(하위 행동 트리)로 묶어두면, 그 서브트리를 다른 곳에서도 그대로 사용하면서, 성공/실패 결과만 상위에서 받아 활용하면 된다. 이렇게 하면 시스템이 커져도 전체 구조가 비선형적으로 복잡해지지 않고, 모듈 단위로 관리할 수 있다.
자율 에이전트/에이전틱 시스템 설계에서의 구조적 특징
자율 에이전트 시스템에서 행동 트리는 "계층적 제어 구조"를 매우 자연스럽게 표현한다. 최상위 루트에서는 큰 전략(예: "목표 수행 vs. 오류 복구 vs. 대기")을 선택하고, 하위에서는 개별 작업(검색, 계산, 계획, 실행)을 단계적으로 수행하는 식이다.
이 계층 구조 덕분에, 시스템 설계를 "상위에서 아래로" 단계적으로 전개할 수 있다. 먼저 상위 레벨에서 "어떤 상황 그룹이 있는지, 각 상황에서 어떤 전략이 필요한지"를 고안하고, 이후 각 전략을 더 세분화해 Sequence, Selector로 쪼개 나간다. 최하위 레벨에서는 실제 Action과 Condition만 채우면 되므로, 하드웨어 제어나 API 호출 같은 세부 구현과 상위 로직이 깔끔하게 분리된다.
또한 행동 트리는 "부분적인 자동화"와 "안전한 자율화" 사이의 균형을 잡는 데 도움이 된다. 구체적으로는 다음과 같은 특징이 있다.
특정 서브트리만 자율적으로 반복 실행하게 만들거나, 사람의 승인(Action/Decorator) 아래에서만 실행되게 만드는 것이 가능하다.
Decorator를 이용해 정책·가드레일을 삽입함으로써, 에이전트가 목표 달성을 위해 지나치게 위험하거나 비효율적인 행동을 선택하지 못하도록 억제할 수 있다.
Parallel와 Selector/Sequence를 결합해, 메인 작업과 안전 감시, 로그 기록, 모니터링을 동시에 수행하는 안전 설계가 가능하다.
이처럼 행동 트리는 에이전트가 스스로 행동을 계획하고 실행하되, 시스템 설계자가 전체 구조와 한계를 명확하게 통제할 수 있는 "프레임"을 제공한다. 특히 LLM 기반 에이전트처럼 내부 의사결정이 불투명한 시스템에서는, 바깥쪽에서 행동 트리로 "무엇을 할 수 있고, 무엇은 할 수 없는지"를 명시적으로 정의해 주는 것이 안정성과 예측 가능성을 높이는 핵심 수단이 된다.
마무리: 행동 트리를 바라보는 실용적인 관점
행동 트리는 복잡한 AI 제어 문제를 "성공/실패를 주고받는 노드들의 트리"로 재구성하는 방법이라고 볼 수 있다. Selector로 후보 행동을 나열하고, Sequence로 절차를 구성하며, Condition과 Decorator로 실행 시점과 안전 조건을 제어하고, Action과 Parallel로 실제 작업과 동시 실행을 구현하는 방식이다.
게임 AI·로보틱스·자율 에이전트에 공통으로 적용되는 핵심 아이디어는 다음과 같이 정리할 수 있다.
모든 노드는 "실행 → 성공/실패"라는 단순한 규칙을 따른다.
트리는 위에서 아래, 왼쪽에서 오른쪽으로 실행된다.
Selector와 Sequence는 성공/실패 결과를 조합해 제어 흐름을 만든다.
Condition·Action·Decorator·Parallel은 각각 조건 검사, 실제 행동, 정책/가드레일, 동시 실행을 담당한다.
전체 구조는 계층적이고 모듈식이어서, 복잡한 시스템도 단계적으로 설계·확장·수정할 수 있다.
이 관점을 바탕으로 자신이 설계하려는 에이전트나 로봇의 행동을 "어떤 노드를 어떤 순서로 배치하면 자연스럽게 표현될까?"라는 질문으로 바꿔 보면, 행동 트리를 훨씬 직관적으로 이해하고 활용할 수 있다.

