Page History
...
PART 2에서 ReAct 액터 플래닝을 설명했다면, PART 3는 그 설계가 실제 코드와 UI, 그리고 터미널 AI 협업 프로토콜로 어떻게 닫히는지 보여준다. 작성일: 2026-04-14. 대상: PART 1, PART 2를 읽은 개발자.
0. 들어가며
PART 2의 결론은 분명했다. 일반 LLM은 스스로 기다리지 못한다. 그래서 Thinking -> Acting -> Waiting -> Complete를 Akka Become()으로 감싼 ReActActor가 필요했다.
이번 3편은 그 다음 장면이다. 설계 문서에서 끝나지 않고, 실제 AgentWin AgentZero 코드베이스에 아래 흐름이 어떻게 연결되었는지 본다.
...
| Info |
|---|
이번 편의 핵심
|
1. 구현체 한눈에 보기
실제 구현은 Project/AgentZeroWpf 안의 다섯 축으로 닫힌다.
...
이 구조를 보면 PART 1의 질문, “Akka는 AI-Agent CLI와 어떻게 소통하는가?”가 이제 추상 답변이 아니라 코드 경로로 설명된다.
2. 귀멸의 형 전환 — ReActActor가 루프를 상태 머신으로 바꾸다
가장 큰 변화는 기존 RunFunctionCallLoopAsync의 동기 루프를 ReActActor로 분리한 점이다.
...
즉 ReAct는 단독 기능이 아니라, 로그와 메모리 위에 얹힌 실행 엔진으로 들어갔다.
3. Phase 2, Phase 3 — 설계가 실제 버튼으로 내려오는 순간
생성 순서대로 보면 구현의 첫 전환점은 두 개의 완료 보고서였다.
3.1 ReAct-Phase2-Complete.md
여기서 실제로 끝난 것은 다음이었다.
Actors/ReActActor.cs신설Actors/Messages.cs확장Actors/AgentBotActor.cs에 ReActActor 자식 생성Project/AgentTest/Actors/ReActActorTests.cs에 상태 전환 테스트 추가
즉 “설계”가 아니라, 테스트 가능한 액터가 먼저 생겼다.
3.2 ReAct-Phase3-Complete.md
그 다음은 UI 통합이다.
AgentBotWindow.xaml에ReAct체크박스 추가AgentBotWindow.xaml.cs에RunReActAsync()추가StreamAiResponseAsync()에서 기존FnCall루프 대신ReAct경로 분기SetReActCallbacks로ReActProgress와ReActResult를 UI에 직접 연결
이 시점부터 ReAct는 백엔드 실험이 아니라, 사용자가 실제로 눌러 쓰는 모드가 된다.
4. 너의 이름은 + 하울의 문 — 터미널 AI와 연결을 만드는 법
여기서부터가 PART 3의 진짜 구현 디테일이다. ReActActor가 아무리 잘 만들어져도, 터미널 안에서 도는 Claude Code 같은 AI가 결과를 다시 보내주지 못하면 협업은 닫히지 않는다.
4.1 이름을 알려줘야 라우팅된다
ReAct-YourName-Identity-Protocol.md에서 드러난 문제는 단순하지만 치명적이었다.
...
이 한 줄로 DONE의 첫 인자가 모델명이 아니라 라우팅 키가 된다.
4.2 /agent-zero가 스킬 로더가 된다
ReAct-SkillActivation-Prompt.md는 그 다음 단계를 설명한다. 터미널 AI는 bot-chat.ps1 자체를 모른다. 그래서 매 대화 앞에 /agent-zero를 붙여 스킬을 강제 로드한다.
...
이렇게 해야 터미널 AI가 .claude/skills/agent-zero/SKILL.md를 읽고, bot-chat.ps1 사용법을 학습하고, 응답 종료 후 DONE(...)을 보낸다. 전통적인 시스템으로 치면 SKILL.md가 문서형 IDL이고, /agent-zero는 그 계약을 활성화하는 스위치다.
4.3 DONE은 어디로 돌아오는가
| Code Block | ||
|---|---|---|
| ||
Terminal AI -> bot-chat.ps1 "DONE(Claude1, 리뷰 3건)" -> CliHandler -> MainWindow.HandleBotChat() -> TerminalDoneSignal -> StageActor -> AgentBotActor -> ReActActor |
즉 PART 1에서 설명한 액터 트리가, 이번에는 터미널 밖 프로세스와 다시 연결되는 복귀 통로까지 확보한 셈이다.
5. 결계사의 결계 — 도구 폭주를 어떻게 막았는가
실전에서는 다른 종류의 문제가 바로 터졌다. 모델이 영리해질수록 한 번에 너무 많은 도구를 호출한다.
...
이 부분이 중요한 이유는, 에이전트 시스템의 성능이 모델 지능만으로 결정되지 않기 때문이다. 도구를 많이 준 것보다, 그 도구를 어디까지 쓰게 할지 경계를 잘 친 것이 더 중요하다.
6. 주술회전의 영역 해제 — 멈추는 기술이 더 어렵다
ReAct-SequenceControl-ESC.md는 구현 후반부의 핵심 교훈을 담고 있다. 시스템은 잘 달리는 것보다, 잘 멈추는 것이 더 어렵다.
...
Waiting이 끝난 뒤 5초 늦게DONE이 오면- 그 메시지가
Thinking상태에서 드랍될 수 있다
이걸 해결한 장치가 두 가지다.
6.1 _pendingDone 큐잉
Thinking이나 Acting 중에 TerminalDoneSignal이 와도 버리지 않고 _pendingDone에 저장한다. 다음 Waiting 진입 시 즉시 소비해서 다시 Thinking으로 보낸다. 즉 늦게 도착한 DONE이 더 이상 허공으로 사라지지 않는다.
6.2 ESC 제어
사용자도 루프를 제어할 수 있어야 한다.
ESC1회:SkipWaitingESC2회:CancelReAct
이렇게 해서 ReAct는 “자동으로 잘 돌아가는 엔진”에서 끝나지 않고, 사용자가 제어권을 되찾을 수 있는 엔진이 됐다.
7. 유희왕의 카드 필드 — 상태를 눈으로 보이게 만들기
구현이 완성되려면 개발자만 이해해서는 안 된다. 사용자가 지금 어디에 걸려 있는지 보여야 한다.
...
특히 RunReActAsync()와 HandleReActProgress()의 조합은 중요하다. 액터가 내보낸 ReActProgress가 곧바로 UI 카드로 렌더링되기 때문에, ReAct는 로그로만 이해하는 시스템이 아니라 실시간으로 보이는 시스템이 된다.
8. ActorPlanning은 설계서가 아니라, 구현을 설명하는 압축본이 됐다
흥미로운 점은 ReAct-ActorPlanning.md가 처음 설계 문서처럼 보이지만, 실제 작성 시점은 여러 구현 이슈를 뚫은 뒤다. 그래서 이 문서는 PART 2의 계획서를 반복하는 게 아니라, 이미 구현된 내용들을 한 장의 설계도로 다시 압축한 문서가 된다.
...
즉 이번 구현은 위에서 아래로 한 번에 내려온 설계가 아니라, 실패 로그 -> 패치 -> 프로토콜 정립 -> UI 가시화로 다듬어진 결과물이다.
9. 실전 한 턴 요약 — 이제 ReAct는 이렇게 돈다
| Code Block | ||
|---|---|---|
| ||
User
-> AgentBotWindow.RunReActAsync
-> AgentBotActor.StartReAct
-> ReActActor.Thinking
-> stage_status / stage_send("/agent-zero ...")
-> Waiting
-> Claude1이 bot-chat.ps1 "DONE(Claude1, 리뷰 3건)" 호출
-> MainWindow.HandleBotChat
-> TerminalDoneSignal
-> ReActActor.Thinking
-> 최종 요약 응답 + 카드 UI 렌더링 |
가능하다. 다만 LLM 하나만 바꾸는 것이 아니라, 액터 상태 머신, 세션 메모리, 로그, 스킬 활성화, DONE 프로토콜, UI 가시성까지 함께 설계해야 한다.
10. 마무리
PART 1이 액터 트리와 통신 구조를 보여줬다면, PART 2는 ReAct 상태 머신의 필요성을 설명했다. 그리고 이번 PART 3는 그 설계가 실제 코드베이스에서 어떻게 살아 움직이는지 보여줬다.
...
ReActActor로 기다릴 수 있게 만들고/agent-zero와DONE(...)으로 다른 AI와 다시 연결하고- 제약, 큐잉, ESC, 카드 UI로 시스템을 사람이 다룰 수 있게 만든 것
결국 AgentWin의 AgentZero의 ReAct 구현은 “LLM이 스스로 똑똑해졌다”는 이야기가 아니라, LLM이 일할 수 있는 런타임을 어떻게 설계했는가에 대한 사례다. 그 점에서 Akka 액터 모델은 단순한 동시성 프레임워크가 아니라, 에이전트 런타임을 조직하는 뼈대로 작동했다.
...
참고 문서
Tech/DOC/Actor/improvement/ReAct-Phase2-Complete.mdTech/DOC/Actor/improvement/ReAct-Phase3-Complete.mdTech/DOC/Actor/improvement/ReAct-YourName-Identity-Protocol.mdTech/DOC/Actor/improvement/ReAct-ToolCall-Constraint-Prompting.mdTech/DOC/Actor/improvement/ReAct-SequenceControl-ESC.mdTech/DOC/Actor/improvement/ReAct-ActorPlanning.mdTech/DOC/Actor/improvement/ReAct-DONE-Handshake-Protocol.mdTech/DOC/Actor/improvement/ReAct-SkillActivation-Prompt.mdTech/DOC/Actor/improvement/ReAct-UI-CardSystem.mdTech/DOC/Actor/improvement/AiMode-DiagnosticLogging.mdTech/DOC/Actor/improvement/OnDevice-SessionMemory.md
젬마4 x 클로드코드 티키타카 장면
- 다음 파트는 이러한 복잡성 높은 장치를 만들게 도와준 하네스 연대기 예정
다양한 진영의 AKKA기술을 다루는 페북공간







