관리 메뉴

오늘도 공부

Grok Bot과 Kimi K3로 배우는 Graph & Loop Engineering 본문

AI

Grok Bot과 Kimi K3로 배우는 Graph & Loop Engineering

행복한 수지아빠 2026. 8. 27. 12:37
반응형

AI 에이전트 시스템의 문제는 모델 성능만으로 해결되지 않는다.

실제 운영 환경에서 더 자주 문제가 되는 것은 다음 세 가지다.

  • 작업이 실패했을 때 누가 다시 시작할 것인가
  • 여러 에이전트가 사용하는 공유 상태를 어디에 저장할 것인가
  • 실제 외부 시스템을 변경하기 전에 누가 승인할 것인가

에이전트를 여러 개 붙여 놓는다고 안정적인 시스템이 만들어지는 것은 아니다.

필요한 것은 에이전트 군집(Swarm) 자체가 아니라, 에이전트가 어떤 작업을 수행해야 하는지 판단하고 결과를 검증하며 다시 작업으로 되돌리는 제어 시스템(Control System) 이다.

이 글에서는 다음과 같은 구조를 사용한다.

Grok Bot
   │
   │ Outer Loop
   ▼
Coordinator
   │
   ├── Knowledge Graph
   ├── DAG
   ├── Context Pack
   ├── Policy / Approval
   └── Append Log
            │
            ▼
        Kimi Code
            │
            ▼
            K3
       Agent / Swarm

핵심 역할은 다음과 같다.

Grok Bot

전체 실행 흐름인 Outer Loop를 관리한다.

Kimi Code + K3

한 번의 제한된 작업 Round에서 분석, 코딩, 조사 같은 깊은 작업을 수행한다.

Knowledge Graph

출처를 가진 장기 지식을 저장한다.

DAG

어떤 작업을 어떤 순서로 실행할지 정의한다.

Context Pack

각 에이전트에게 전달되는 컨텍스트를 제한한다.

Policy Layer

도구와 외부 작업에 대한 권한을 통제한다.

Append Log

모든 상태 전환과 실행 이력을 기록한다.

이 구조를 이해하면 단순한 AI Agent를 넘어 장기간 반복해서 운영할 수 있는 Agent Harness를 설계할 수 있다.


1. Loop Engineering

"계속해"는 Loop가 아니다

LLM에게 다음과 같이 지시한다고 생각해 보자.

문제가 해결될 때까지 계속 작업해.

이것은 제대로 된 Loop가 아니다.

신뢰할 수 있는 Loop에는 최소한 네 가지 요소가 필요하다.

Owner
Worker
Verifier
Stop Rule

예를 들어 다음 구조다.

Coordinator
     │
     ▼
 Worker
     │
     ▼
Verifier
     │
 ┌───┴────┐
PASS    REVISE
 │         │
END        └──── Worker

Coordinator는 전체 작업을 소유한다.

Worker는 하나의 후보 결과를 만든다.

Verifier는 미리 정의된 Acceptance Test를 검사한다.

실패하면 전체 작업을 처음부터 다시 설명하지 않는다.

Verifier가 실패시킨 조건만 Worker에게 다시 전달한다.


2. 가장 단순한 3-Agent Loop

처음부터 수십 개의 Agent를 만들 필요는 없다.

다음 세 개부터 시작하는 것이 좋다.

Coordinator
Worker
Verifier

Coordinator의 기본 동작은 다음과 같다.

1. source event로부터 stable job_id 생성

2. Worker에게 candidate 생성 요청

3. Verifier가
   PASS
   REVISE
   BLOCKED
   중 하나를 반환

4. REVISE이면
   실패한 테스트만 Worker에게 전달

5. 최대 3 Round 실행

6. 동일한 결과가 반복되면 중단

7. 필요한 Source가 없거나 오래됐으면 중단

8. 외부 작업은 Draft 상태 유지

9. 실제 실행 전
   target + payload를 사용자에게 표시

10. 모든 handoff를 append log에 기록

여기에서 매우 중요한 개념이 하나 있다.

Round와 Retry는 다르다

API timeout이 발생했다고 새로운 Round가 되어서는 안 된다.

Round 1
   │
   ├─ attempt 1 → timeout
   ├─ attempt 2 → rate limit
   └─ attempt 3 → success

이것은 여전히 Round 1이다.

새로운 Round는 Verifier가 새로운 정보를 생성했을 때만 시작한다.

Round 1
Worker
 ↓
Verifier
 ↓
Failed Check

Round 2
Worker

3. Kimi K3를 Inner Worker로 사용하기

전체 시스템의 제어권을 Kimi에게 주는 방식보다는 Kimi가 한 번의 제한된 작업만 수행하도록 만드는 것이 핵심이다.

개념적으로 다음과 같다.

Grok Coordinator

     ↓ task.json

Kimi K3
"한 번만 작업"

     ↓ candidate.json

Grok Verifier

Kimi Worker는 다음 정도의 책임만 가진다.

입력 읽기
↓
분석
↓
필요한 경우 Sub-Agent 사용
↓
Candidate 생성
↓
종료

외부 시스템 변경은 하지 않는다.


4. Worker Output을 Contract로 만든다

Agent의 결과를 자연어만으로 전달하면 자동화하기 어렵다.

따라서 Output Contract를 정의한다.

예를 들어:

{
  "job_id": "demo-001",
  "round": 1,
  "status": "CANDIDATE",
  "summary": "...",
  "evidence": [],
  "failed_checks": [],
  "next_step": "...",
  "requires_human_approval": false
}

중요한 것은 결과를 받은 이후다.

Bridge가 반드시 다음 작업을 수행한다.

LLM Output
    ↓
JSON Parse
    ↓
Schema Validation
    ↓
Canonical JSON
    ↓
SHA-256
    ↓
candidate.json

LLM이 직접 fingerprint를 계산하게 하지 않는 것이 좋다.

시스템이 동일한 방식으로 계산해야 한다.


5. Output Fingerprint

Agent Loop에서 자주 발생하는 문제 중 하나가 같은 답을 조금씩 표현만 바꾸며 반복하는 현상이다.

이를 감지하기 위해 결과를 fingerprint한다.

예를 들어 다음 데이터가 있다.

{
  "status": "CANDIDATE",
  "summary": "...",
  "evidence": [],
  "failed_checks": []
}

이 semantic payload를 canonical JSON으로 만든다.

canonical JSON
      ↓
SHA-256
      ↓
output_fingerprint

그리고 이전 Round와 비교한다.

Round 1
fingerprint = abc123

Round 2
fingerprint = abc123

동일하다면:

NO_PROGRESS

로 중단한다.

이것이 무한 Loop를 막는 중요한 Stop Rule이다.


6. Idempotency

자동화 Agent가 가장 위험한 순간은 외부 작업을 수행할 때다.

예를 들어:

이메일 발송
결제
SNS 게시
파일 삭제
Production Deploy
계정 권한 변경

네트워크 timeout이 발생하면 Agent는 다음과 같은 상황을 알 수 없다.

요청 실패

인지

실제로는 성공했지만
응답만 받지 못함

인지 알 수 없다.

그래서 Idempotency Key가 필요하다.

Round용 Key:

job_id + round + input_sha256

실제 외부 작업용 Key:

job_id + ":commit"

예:

job_483:commit

7. External Effect의 안전한 실행

실제 외부 작업은 다음 순서로 처리한다.

Approval
   ↓
Claim idempotency key
   ↓
Execute
   ↓
Verify Live State
   ↓
Store Receipt
   ↓
Completion Marker

완료 여부를 먼저 기록하면 안 된다.

반드시 실제 시스템 상태를 확인한 다음 기록해야 한다.

예를 들어 이메일이라면:

send()
 ↓
provider receipt 확인
 ↓
message ID 저장
 ↓
completed

8. 자동 Loop Controller

전체 흐름을 의사 코드로 만들면 다음과 비슷하다.

job_id = stable_id(source_event)

if completion_marker exists:
    return DUPLICATE

effect = read_effect(job_id + ":commit")

if effect == CLAIMED:
    reconcile live state

for round in 1..3:

    write task.json

    run Kimi

    validate result

    fingerprint =
        sha256(canonical_payload)

    append event log

    verdict =
        Grok verifier(result)

    if verdict == PASS:

        if external effect 없음:
            complete
            stop

        else:
            request approval

            claim idempotency key

            execute

            verify live state

            save receipt

            complete

            stop

    if verdict == BLOCKED:
        stop

    if fingerprint ==
       previous_fingerprint:

        stop NO_PROGRESS

    send failed checks
    to next round

stop MAX_ROUNDS

이것이 Loop Engineering의 핵심이다.


9. Graph Engineering

여기서 중요한 구분이 있다.

Agent 시스템에서 흔히 "Graph"라고 부르는 것은 사실 두 종류다.

Knowledge Graph
Execution Graph

둘은 완전히 다른 역할을 한다.


10. Knowledge Graph

Knowledge Graph는 시스템이 장기간 기억해야 할 사실을 저장한다.

예:

Kimi Code
   │
   ├── supports → Agent
   │
   ├── supports → AgentSwarm
   │
   └── uses → K3

하지만 중요한 것은 관계 자체가 아니다.

각 Claim에 Source가 연결되어 있어야 한다.

Claim
   │
   └── source_id
          │
          ▼
       Source

예:

{
  "id": "claim:kimi-swarm",
  "kind": "claim",
  "label": "Kimi Code includes AgentSwarm",
  "source_ids": [
    "src:kimi-tools"
  ],
  "status": "verified",
  "rev": 1
}

11. Source Provenance

Source도 별도의 Entity로 관리한다.

{
  "id": "src:kimi-tools",
  "url": "...",
  "retrieved_at":
    "2026-08-26T00:00:00Z",
  "sha256": "<content-hash>"
}

이렇게 하면 단순히

"Agent가 그렇게 말했다"

가 아니라

Claim
 ↓
Source
 ↓
Source Hash

구조가 만들어진다.


12. Knowledge Graph 최소 Schema

실전에서는 다음 필드 정도면 충분하다.

id
kind
type
source_ids
status
rev
confidence
observed_at
valid_from
valid_to

status는 다음과 같이 운영할 수 있다.

proposed
verified
rejected
superseded

특히 LLM이 추론한 관계라면:

confidence

를 별도로 기록하는 것이 좋다.


13. 그래프는 처음부터 Neo4j일 필요가 없다

MVP에서는 오히려 JSONL이 편하다.

graphops/

├── kg/
│   ├── schema.json
│   ├── nodes.jsonl
│   ├── edges.jsonl
│   ├── sources.jsonl
│   ├── events.jsonl
│   ├── inbox/
│   └── snapshots/
│
├── dag/
│   └── pipeline.yaml
│
├── runs/
└── artifacts/

JSONL의 장점은 명확하다.

inspect
append
diff
hash
backup
Git

모두 쉽다.


14. Single Writer 원칙

여러 Agent가 동시에 Knowledge Graph를 수정하면 충돌하기 쉽다.

따라서 다음 구조가 좋다.

Research Agent ─┐
Analysis Agent ─┼─→ kg/inbox
Crawler Agent ──┘

                    ↓

            Knowledge Steward

                    ↓

             authoritative KG

Agent는 직접 Graph를 수정하지 않는다.

대신 Patch를 제출한다.

최종 반영은 Knowledge Steward 하나만 수행한다.

이것이 Single Writer Pattern이다.


15. Obsidian을 Human View로 사용할 수도 있다

JSONL을 Source of Truth로 유지하면서 사람이 보기 좋은 형태를 별도로 만들 수 있다.

예:

Knowledge Graph
      │
      ├─ nodes.jsonl
      ├─ edges.jsonl
      │
      └─ Markdown Generator
              ↓
          Obsidian Vault

한 Node를 하나의 Markdown 파일로 만든다.

---
id: product:kimi-code
kind: product
status: verified
---

# Kimi Code

## Relations

- [[Agent]]
- [[AgentSwarm]]
- [[K3]]

AI가 사용하는 데이터와 사람이 읽는 UI를 분리하는 것이다.


16. DAG는 Execution Graph다

Knowledge Graph와 DAG를 혼동하면 안 된다.

Knowledge Graph:

무엇을 알고 있는가?

DAG:

무엇을 먼저 실행해야 하는가?

예를 들어:

observe
   ↓
 plan
 ┌─┴─────┐
 ↓       ↓
research compare
 └───┬───┘
     ↓
   review
     ↓
    act

이를 YAML로 표현하면:

nodes:

  - id: observe
    needs: []

  - id: plan
    needs:
      - observe

  - id: research
    needs:
      - plan

  - id: compare
    needs:
      - plan

  - id: review
    needs:
      - research
      - compare

  - id: act
    needs:
      - review

17. Ready Frontier

DAG Scheduler는 현재 실행 가능한 Node를 계산한다.

예를 들어:

observe ✓
plan    ✓

research pending
compare  pending
review   pending

현재 Ready Frontier는:

research
compare

두 작업은 서로 의존하지 않으므로 동시에 실행할 수 있다.

       ┌→ Research Agent
Plan ──┤
       └→ Compare Agent

이럴 때 AgentSwarm을 활용한다.


18. AgentSwarm은 DAG 전체를 관리하면 안 된다

Swarm에게 다음과 같이 맡기면 위험하다.

"전체 프로젝트 알아서 끝내."

그 대신 Dispatcher가 Ready Node만 계산한다.

DAG Dispatcher
       ↓
Ready Frontier
       ↓
AgentSwarm

예:

ready_nodes = [
  research,
  compare,
  benchmark
]

각 Agent에게는 자신의 Node 정보만 전달한다.


19. Node State

각 실행 Node에는 상태가 필요하다.

pending
   ↓
running
   ↓
succeeded

실패하면:

running
   ↓
failed
   ↓
retry

부모 Node가 영구 실패하면 자식은:

blocked

가 된다.

예:

{
  "run_id": "2026-08-26-001",
  "nodes": {
    "research": {
      "status": "succeeded",
      "attempt": 1,
      "output_sha256": "..."
    },
    "review": {
      "status": "pending",
      "attempt": 0
    }
  }
}

20. Knowledge Graph + DAG 결합

둘을 합치면 다음 구조가 된다.

Knowledge Graph
      │
      ▼
Immutable Snapshot
      │
      ▼
     DAG
      │
      ▼
 Ready Frontier
      │
      ▼
Kimi Agents / Grok Bots
      │
      ▼
 Candidate Patch
      │
      ▼
 Knowledge Steward
      │
      ▼
Knowledge Graph

즉 Loop가 생긴다.

KNOW
 ↓
PLAN
 ↓
EXECUTE
 ↓
VERIFY
 ↓
LEARN
 ↓
KNOW

이것이 Graph + Loop Engineering이다.


21. Context Engineering

Agent가 실패하는 또 하나의 이유는 Context가 계속 커지는 것이다.

전체 대화 내역을 매번 전달하면 다음 문제가 발생한다.

Context 증가
 ↓
관련 없는 정보 증가
 ↓
Attention 분산
 ↓
Instruction 충돌
 ↓
Agent Drift

그래서 Context Pack을 따로 관리한다.

context/

├── mission.md
├── constraints.md
├── definitions.md
├── state.md
└── acceptance-tests.md

22. Context Pack의 역할

예를 들어:

mission.md

이 시스템이 해결하려는 문제

constraints.md

절대 하면 안 되는 작업

definitions.md

프로젝트 용어 정의

state.md

현재 상태

acceptance-tests.md

완료 판정 기준

Agent에게 과거 전체 대화를 주는 대신 필요한 Operational Context만 준다.


23. Handoff Envelope

Agent 사이의 작업도 자유로운 메시지보다는 Contract가 좋다.

예:

{
  "run_id": "run_01",

  "task": "...",

  "allowed_paths": [
    "/project/src"
  ],

  "allowed_tools": [
    "Read",
    "Grep"
  ],

  "prohibited_actions": [
    "delete",
    "publish"
  ],

  "acceptance_tests": [],

  "approval_boundary":
    "external_effect",

  "expected_artifact":
    "analysis.json",

  "next_owner":
    "verifier"
}

이것을 Handoff Envelope라고 생각하면 된다.


24. Harness Engineering

LLM은 Capability를 제공한다.

하지만 LLM 자체가 시스템의 통제 장치는 아니다.

예를 들어:

K3

는 Model이다.

Kimi Code

는 K3를 실행하는 Harness다.

그리고:

Grok Bot

은 또 다른 Runtime/Control Layer다.

따라서 다음처럼 이해하는 것이 좋다.

Model
   ↓
Inner Harness
   ↓
Outer Harness
   ↓
External Systems

25. Nested Harness

이번 구조에서는 다음과 같다.

Grok Bot
Outer Harness
      │
      ▼
Kimi Code
Inner Harness
      │
      ▼
K3

여기에는 중요한 문제가 있다.

Outer Harness가 Kimi Code 프로세스를 실행하도록 승인했다고 해서 그 안에서 발생하는 모든 Tool Call까지 승인한 것은 아니다.

이를 Nested Harness Gap이라고 볼 수 있다.


26. 이중 Policy Layer

따라서 권한 정책도 두 군데 필요하다.

Outer Policy
Grok Bot

+

Inner Policy
Kimi Code

Outer Policy:

Publish → approval
Delete → approval
Send → approval
Production change → approval
Purchase → approval

Inner Policy:

Read → allow
Grep → allow

Write → ask
Edit → ask
Bash → ask

rm -rf → deny
mail.send → deny

27. Least Privilege

Agent에게 필요한 권한만 주는 것이 중요하다.

예를 들어 Research Agent에게는:

Read
Search
Browser

정도만 준다.

다음 권한은 필요하지 않다.

Write
Delete
Send
Deploy
Payment

Worker Profile을 역할별로 나누는 이유다.


28. Read-only Agent부터 시작한다

처음 구축할 때는 다음 Agent 하나면 충분하다.

Read
Grep
Glob
Agent
AgentSwarm

제외:

Bash
Write
Edit
Write-capable MCP

이 Agent가 안정적으로 동작한 다음 하나씩 권한을 늘리는 것이 안전하다.


29. Append Log

Agent 시스템에서는 일반 Application Log보다 상태 전환 기록이 특히 중요하다.

예를 들어:

{
  "v": 1,
  "ts": "2026-08-26T12:00:00Z",
  "run_id": "run_01",
  "actor": "kimi",
  "event": "tool.request",
  "tool": "Bash",
  "decision": "ask",
  "status": "pending"
}

기록할 이벤트 예시는 다음과 같다.

handoff.created
tool.request
approval.result
tool.result
checkpoint
handoff.completed
recovery.started
recovery.completed

30. Hash Chain

Append Log를 조금 더 강하게 만들려면 이전 Record Hash를 포함할 수 있다.

Record 1
 hash=A

Record 2
 prev=A
 hash=B

Record 3
 prev=B
 hash=C

즉:

R1 → R2 → R3 → R4

중간 로그가 변경되면 이후 Hash Chain이 깨진다.

다만 이것만으로 동일한 OS 사용자가 로그를 수정하는 것을 완전히 막을 수 있는 것은 아니다.

중요한 시스템이라면 Chain Head를 외부 Immutable Storage에도 저장하는 구조를 고려할 수 있다.


31. 로그에 Secret을 넣으면 안 된다

다음 데이터는 Operational Log에서 제거한다.

API Token
Cookie
Password
OAuth Secret
Private Key
Raw credential

대신 필요한 경우 Hash를 기록한다.

{
  "args_sha256": "..."
}

32. 전체 시스템 구조

지금까지의 구조를 하나로 연결하면 다음과 같다.

                 ┌──────────────────┐
                 │     Human        │
                 │    Approval      │
                 └────────┬─────────┘
                          │
                 ┌────────▼─────────┐
                 │    Grok Bot      │
                 │ Outer Controller │
                 └────────┬─────────┘
                          │
        ┌─────────────────┼───────────────────┐
        │                 │                   │
        ▼                 ▼                   ▼
 Knowledge Graph      DAG Scheduler       Policy Gate
        │                 │
        │                 ▼
        │          Ready Frontier
        │                 │
        │                 ▼
        │           ┌───────────┐
        │           │ Kimi Code │
        │           └─────┬─────┘
        │                 │
        │                 ▼
        │                K3
        │          ┌──────┴──────┐
        │          │             │
        │        Agent        AgentSwarm
        │          │             │
        └──────────┴──────┬──────┘
                          │
                          ▼
                    Candidate Patch
                          │
                          ▼
                       Verify
                          │
                          ▼
                 Knowledge Steward
                          │
                          ▼
                  Knowledge Graph

33. 여기서 가장 중요한 것은 Swarm이 아니다

많은 Agent 프레임워크가 강조하는 것은 다음과 같다.

10 Agents
50 Agents
100 Agents
300 Agents

하지만 운영 시스템에서 더 중요한 것은 Agent 숫자가 아니다.

다음 구조다.

Task Contract
State
Verification
Return Path
Stop Condition
Approval Boundary
Evidence
Audit Log

Agent가 100개여도 이 구조가 없으면 시스템은 불안정해진다.

반대로 Agent가 세 개뿐이어도 이 구조가 있으면 상당히 강력한 자동화 시스템을 만들 수 있다.


34. 추천 구축 순서

처음부터 Knowledge Graph와 DAG와 Swarm을 모두 구축하는 것은 권장하지 않는다.

Stage 1 — Single Worker

Coordinator
 ↓
Worker
 ↓
Verifier

조건:

Read-only
3 Round Limit
Human Approval

Stage 2 — Output Contract

모든 Agent 결과를:

JSON Schema

로 만든다.

그리고:

validate
hash
persist

한다.


Stage 3 — Loop Controller

추가한다.

Retry
Stop Rule
Fingerprint
Idempotency

Stage 4 — DAG

독립적인 작업을 발견하면 DAG를 만든다.

research
compare
benchmark

같은 작업을 병렬 처리한다.


Stage 5 — AgentSwarm

Ready Frontier에 여러 Node가 있을 때만 Swarm을 사용한다.

Ready Frontier
     ↓
AgentSwarm

Swarm이 전체 시스템을 통제하게 하지 않는다.


Stage 6 — Knowledge Graph

다음 단계에서 장기 Memory를 추가한다.

조건은 하나다.

모든 Claim에는 Source가 있어야 한다.

Stage 7 — External Actions

마지막에 다음 기능을 추가한다.

Send
Publish
Deploy
Delete
Payment

그리고 반드시:

Human Approval
+
Idempotency
+
Live Verification

을 적용한다.


35. 실제 MVP 구조

처음 만든다면 이 정도면 충분하다.

agent-system/

├── AGENTS.md

├── context/
│   ├── mission.md
│   ├── constraints.md
│   ├── state.md
│   └── acceptance-tests.md

├── handoffs/
│   ├── inbox/
│   └── outbox/

├── runs/
│   └── <job_id>/
│       ├── task.json
│       ├── candidate.json
│       ├── verdict.json
│       └── events.jsonl

├── policy/
│   ├── tools.md
│   └── approvals.md

└── artifacts/

이 단계에서는 Knowledge Graph도 필요 없다.

DAG도 필요 없다.

Swarm도 필요 없다.

먼저 다음 Loop가 정확하게 동작하는지 확인한다.

Task
 ↓
Worker
 ↓
Candidate
 ↓
Verifier
 ↓
PASS / REVISE
 ↓
State

36. 다음 단계

이 구조가 안정되면:

Loop
 ↓
DAG
 ↓
Swarm
 ↓
Knowledge Graph

순으로 확장한다.

반대 방향으로 가면 시스템 복잡도가 빠르게 증가한다.


37. 핵심 원칙

이 전체 아키텍처를 다섯 문장으로 정리할 수 있다.

Models give capability.

모델은 시스템에게 능력을 준다.

Loops give persistence.

Loop는 작업이 실패해도 다시 진행할 수 있게 만든다.

Graphs give memory and order.

Knowledge Graph는 기억을, DAG는 실행 순서를 제공한다.

Context gives the correct frame.

Context Engineering은 Agent가 지금 필요한 정보만 보게 만든다.

Harnesses give control.

Harness는 Agent가 무엇을 할 수 있고 무엇을 해서는 안 되는지 통제한다.

결국 신뢰할 수 있는 AI Agent 시스템의 핵심은 더 강력한 모델이나 더 많은 Agent가 아니다.

Capability
     +
Loop
     +
Graph
     +
Context
     +
Harness
     +
Policy
     +
Evidence

이 구조가 갖춰졌을 때 비로소 AI Agent를 단순한 챗봇이 아니라 지속적으로 업무를 수행하는 운영 시스템으로 발전시킬 수 있다.

반응형