Junhoee commited on
Commit
eae04fe
ยท
verified ยท
1 Parent(s): d66a427

Upload 3 files

Browse files
docs/Google-ADK.md ADDED
@@ -0,0 +1,1127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Google ADK ํ•ต์‹ฌ ๊ฐœ๋… ์™„์ „ ๊ฐ€์ด๋“œ
2
+
3
+ ์ด ๋ฌธ์„œ๋Š” Google Agent Development Kit (ADK)์˜ ํ•ต์‹ฌ ๊ฐœ๋…๋“ค์„ ์ฒด๊ณ„์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
4
+ ์ƒ˜ํ”Œ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋œ ๋ชจ๋“  ์ค‘์š” ์š”์†Œ๋“ค์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
5
+
6
+ ---
7
+
8
+ ## ๐Ÿ“š ๋ชฉ์ฐจ
9
+
10
+ 1. [์ „์ฒด ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”](#1-์ „์ฒด-์•„ํ‚คํ…์ฒ˜-๊ฐœ์š”)
11
+ 2. [Session (์„ธ์…˜)](#2-session-์„ธ์…˜)
12
+ 3. [State (์ƒํƒœ)](#3-state-์ƒํƒœ)
13
+ 4. [Event (์ด๋ฒคํŠธ)](#4-event-์ด๋ฒคํŠธ)
14
+ 5. [Context (์ปจํ…์ŠคํŠธ)](#5-context-์ปจํ…์ŠคํŠธ)
15
+ 6. [Runner (๋Ÿฌ๋„ˆ)](#6-runner-๋Ÿฌ๋„ˆ)
16
+ 7. [Memory (๋ฉ”๋ชจ๋ฆฌ)](#7-memory-๋ฉ”๋ชจ๋ฆฌ)
17
+ 8. [Callbacks (์ฝœ๋ฐฑ)](#8-callbacks-์ฝœ๋ฐฑ)
18
+ 9. [Tools (๋„๊ตฌ)](#9-tools-๋„๊ตฌ)
19
+ 10. [ํ•ต์‹ฌ ๊ฐœ๋… ๊ฐ„์˜ ๊ด€๊ณ„](#10-ํ•ต์‹ฌ-๊ฐœ๋…-๊ฐ„์˜-๊ด€๊ณ„)
20
+
21
+ ---
22
+
23
+ ## 1. ์ „์ฒด ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์š”
24
+
25
+ ### ADK์˜ ํ•ต์‹ฌ ์ฒ ํ•™
26
+
27
+ ADK๋Š” **"์—์ด์ „ํŠธ ๊ฐœ๋ฐœ์„ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์ฒ˜๋Ÿผ"** ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.
28
+ ๋ณต์žกํ•œ AI ์—์ด์ „ํŠธ ์‹œ์Šคํ…œ์„ ๋ชจ๋“ˆํ™”ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
29
+
30
+ ### ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ ๋‹ค์ด์–ด๊ทธ๋žจ
31
+
32
+ ```
33
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
34
+ โ”‚ ์‚ฌ์šฉ์ž (User) โ”‚
35
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
36
+ โ”‚
37
+ โ–ผ
38
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
39
+ โ”‚ Runner (๋Ÿฌ๋„ˆ/์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ) โ”‚
40
+ โ”‚ - ์‹คํ–‰ ๋ฃจํ”„ ๊ด€๋ฆฌ โ”‚
41
+ โ”‚ - ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐ ๋ผ์šฐํŒ… โ”‚
42
+ โ”‚ - ์„œ๋น„์Šค ์กฐ์œจ โ”‚
43
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
44
+ โ”‚ โ”‚ โ”‚
45
+ โ–ผ โ–ผ โ–ผ
46
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
47
+ โ”‚ SessionService โ”‚ โ”‚ MemoryService โ”‚ โ”‚ ArtifactService โ”‚
48
+ โ”‚ (์„ธ์…˜ ๊ด€๋ฆฌ) โ”‚ โ”‚ (์žฅ๊ธฐ ๊ธฐ์–ต) โ”‚ โ”‚ (ํŒŒ์ผ/๋ฐ์ดํ„ฐ) โ”‚
49
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
50
+ โ”‚
51
+ โ–ผ
52
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
53
+ โ”‚ Session (์„ธ์…˜) โ”‚
54
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
55
+ โ”‚ โ”‚ State โ”‚ โ”‚ Events โ”‚ โ”‚ Metadata (ID, User) โ”‚ โ”‚
56
+ โ”‚ โ”‚ (์ƒํƒœ) โ”‚ โ”‚ (์ด๋ฒคํŠธ๋“ค) โ”‚ โ”‚ โ”‚ โ”‚
57
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
58
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
59
+ โ”‚
60
+ โ–ผ
61
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
62
+ โ”‚ Agent (์—์ด์ „ํŠธ) โ”‚
63
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
64
+ โ”‚ โ”‚ InvocationContext (ํ˜ธ์ถœ ์ปจํ…์ŠคํŠธ) โ”‚ โ”‚
65
+ โ”‚ โ”‚ - session, state, services ์ ‘๊ทผ โ”‚ โ”‚
66
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
67
+ โ”‚ โ”‚ โ”‚
68
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
69
+ โ”‚ โ–ผ โ–ผ โ–ผ โ”‚
70
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
71
+ โ”‚ โ”‚ Tools โ”‚ โ”‚ LLM โ”‚ โ”‚Callbacksโ”‚ โ”‚
72
+ โ”‚ โ”‚ (๋„๊ตฌ) โ”‚ โ”‚ (๋ชจ๋ธ) โ”‚ โ”‚ (์ฝœ๋ฐฑ) โ”‚ โ”‚
73
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
74
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 2. Session (์„ธ์…˜)
80
+
81
+ ### ๊ฐœ๋…
82
+
83
+ **Session**์€ ์‚ฌ์šฉ์ž์™€ ์—์ด์ „ํŠธ ๊ฐ„์˜ **๋‹จ์ผ ๋Œ€ํ™” ์Šค๋ ˆ๋“œ**๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
84
+ ์ „ํ™” ํ†ตํ™”์— ๋น„์œ ํ•˜๋ฉด, ํ•˜๋‚˜์˜ ํ†ตํ™”๊ฐ€ ํ•˜๋‚˜์˜ ์„ธ์…˜์ž…๋‹ˆ๋‹ค.
85
+
86
+ ### ์ฃผ์š” ์†์„ฑ
87
+
88
+ ```python
89
+ from google.adk.sessions import Session
90
+
91
+ # Session์˜ ์ฃผ์š” ์†์„ฑ
92
+ session.id # ์„ธ์…˜ ๊ณ ์œ  ID
93
+ session.app_name # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„
94
+ session.user_id # ์‚ฌ์šฉ์ž ID
95
+ session.state # ์ƒํƒœ ๋”•์…”๋„ˆ๋ฆฌ (State)
96
+ session.events # ์ด๋ฒคํŠธ ํžˆ์Šคํ† ๋ฆฌ ๋ฆฌ์ŠคํŠธ
97
+ session.last_update_time # ๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„
98
+ ```
99
+
100
+ ### SessionService
101
+
102
+ ์„ธ์…˜์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
103
+
104
+ ```python
105
+ from google.adk.sessions import InMemorySessionService
106
+
107
+ # ์„ธ์…˜ ์„œ๋น„์Šค ์ƒ์„ฑ
108
+ session_service = InMemorySessionService()
109
+
110
+ # ์ƒˆ ์„ธ์…˜ ์ƒ์„ฑ
111
+ session = await session_service.create_session(
112
+ app_name="my_app",
113
+ user_id="user_123",
114
+ state={"initial_key": "initial_value"} # ์ดˆ๊ธฐ ์ƒํƒœ ์„ค์ • ๊ฐ€๋Šฅ
115
+ )
116
+
117
+ # ๊ธฐ์กด ์„ธ์…˜ ์กฐํšŒ
118
+ session = await session_service.get_session(
119
+ app_name="my_app",
120
+ user_id="user_123",
121
+ session_id="session_abc"
122
+ )
123
+
124
+ # ์„ธ์…˜ ๋ชฉ๋ก ์กฐํšŒ
125
+ sessions = await session_service.list_sessions(
126
+ app_name="my_app",
127
+ user_id="user_123"
128
+ )
129
+
130
+ # ์„ธ์…˜ ์‚ญ์ œ
131
+ await session_service.delete_session(
132
+ app_name="my_app",
133
+ user_id="user_123",
134
+ session_id="session_abc"
135
+ )
136
+ ```
137
+
138
+ ### SessionService ๊ตฌํ˜„์ฒด ์ข…๋ฅ˜
139
+
140
+ | ๊ตฌํ˜„์ฒด | ์ €์žฅ ์œ„์น˜ | ์˜์†์„ฑ | ์šฉ๋„ |
141
+ | ------------------------ | ------------ | ---------------------- | ------------- |
142
+ | `InMemorySessionService` | ๋ฉ”๋ชจ๋ฆฌ | โŒ (์•ฑ ์žฌ์‹œ์ž‘ ์‹œ ์†Œ๋ฉธ) | ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ |
143
+ | `DatabaseSessionService` | SQL DB | โœ… | ํ”„๋กœ๋•์…˜ |
144
+ | `VertexAISessionService` | Google Cloud | โœ… | ํด๋ผ์šฐ๋“œ ๋ฐฐํฌ |
145
+
146
+ ### ์„ธ์…˜ ์ƒ๋ช…์ฃผ๊ธฐ
147
+
148
+ ```
149
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
150
+ โ”‚ CREATE โ”‚ โ”€โ”€โ–ถ โ”‚ UPDATE โ”‚ โ”€โ”€โ–ถ โ”‚ DELETE โ”‚
151
+ โ”‚ (์ƒ์„ฑ) โ”‚ โ”‚ (์ด๋ฒคํŠธ ์ถ”๊ฐ€)โ”‚ โ”‚ (์ข…๋ฃŒ) โ”‚
152
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
153
+ โ”‚
154
+ โ–ผ
155
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
156
+ โ”‚ State โ”‚
157
+ โ”‚ ๋ณ€๊ฒฝ โ”‚
158
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 3. State (์ƒํƒœ)
164
+
165
+ ### ๊ฐœ๋…
166
+
167
+ **State**๋Š” ์„ธ์…˜ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” **ํ‚ค-๊ฐ’ ์ €์žฅ์†Œ**์ž…๋‹ˆ๋‹ค.
168
+ ์—์ด์ „ํŠธ์˜ "๋ฉ”๋ชจ์žฅ" ์—ญํ• ์„ ํ•˜๋ฉฐ, ๋Œ€ํ™” ์ค‘ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค.
169
+
170
+ ### State์˜ ๋ฒ”์œ„ (Prefix)
171
+
172
+ ADK์—์„œ State๋Š” **prefix**๋กœ ๋ฒ”์œ„๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค:
173
+
174
+ | Prefix | ๋ฒ”์œ„ | ์„ค๋ช… |
175
+ | ------- | ------------ | --------------------------------------------- |
176
+ | (์—†์Œ) | ์„ธ์…˜ ์ „์ฒด | ๊ธฐ๋ณธ๊ฐ’, ์„ธ์…˜ ๋™์•ˆ ์œ ์ง€ |
177
+ | `app:` | ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ | ๊ฐ™์€ ์•ฑ์˜ ๋ชจ๋“  ์„ธ์…˜์—์„œ ๊ณต์œ  |
178
+ | `user:` | ์‚ฌ์šฉ์ž | ๊ฐ™์€ ์‚ฌ์šฉ์ž์˜ ๋ชจ๋“  ์„ธ์…˜์—์„œ ๊ณต์œ  |
179
+ | `temp:` | ํ˜„์žฌ ํ˜ธ์ถœ | ํ˜„์žฌ invocation์—์„œ๋งŒ ์œ ์ง€, ํ˜ธ์ถœ ์ข…๋ฃŒ ์‹œ ์‚ญ์ œ |
180
+
181
+ ```python
182
+ # State ์‚ฌ์šฉ ์˜ˆ์‹œ
183
+ ctx.session.state["user_name"] = "ํ™๊ธธ๋™" # ์„ธ์…˜ ๋ฒ”์œ„
184
+ ctx.session.state["app:settings"] = {"theme": "dark"} # ์•ฑ ์ „์ฒด ๊ณต์œ 
185
+ ctx.session.state["user:preferences"] = {"lang": "ko"} # ์‚ฌ์šฉ์ž ๊ณต์œ 
186
+ ctx.session.state["temp:current_step"] = 3 # ํ˜„์žฌ ํ˜ธ์ถœ๋งŒ
187
+ ```
188
+
189
+ ### State ์ฝ๊ธฐ/์“ฐ๊ธฐ
190
+
191
+ #### 1. output_key๋ฅผ ํ†ตํ•œ ์ž๋™ ์ €์žฅ (LlmAgent)
192
+
193
+ ```python
194
+ from google.adk.agents import LlmAgent
195
+
196
+ # ์—์ด์ „ํŠธ ์‘๋‹ต์ด ์ž๋™์œผ๋กœ state['analysis_result']์— ์ €์žฅ๋จ
197
+ agent = LlmAgent(
198
+ name="Analyzer",
199
+ instruction="๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜์„ธ์š”.",
200
+ output_key="analysis_result" # โ† ์ž๋™ ์ €์žฅ
201
+ )
202
+ ```
203
+
204
+ #### 2. Instruction ํ…œํ”Œ๋ฆฟ์—์„œ ์ฝ๊ธฐ
205
+
206
+ ```python
207
+ agent = LlmAgent(
208
+ name="Reporter",
209
+ instruction="""
210
+ ์ด์ „ ๋ถ„์„ ๊ฒฐ๊ณผ: {analysis_result}
211
+ ์œ„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ณด๊ณ ์„œ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
212
+ """ # โ† {key} ํ˜•์‹์œผ๋กœ ์ž๋™ ์ฃผ์ž…
213
+ )
214
+ ```
215
+
216
+ #### 3. Tool/Callback์—์„œ ์ง์ ‘ ์ ‘๊ทผ
217
+
218
+ ```python
219
+ from google.adk.tools import ToolContext
220
+
221
+ def my_tool(context: ToolContext, query: str) -> dict:
222
+ # ์ฝ๊ธฐ
223
+ user_name = context.state.get("user_name", "Unknown")
224
+
225
+ # ์“ฐ๊ธฐ (์ž๋™์œผ๋กœ state_delta์— ์ถ”์ ๋จ)
226
+ context.state["last_query"] = query
227
+ context.state["query_count"] = context.state.get("query_count", 0) + 1
228
+
229
+ return {"result": f"Hello {user_name}, processed: {query}"}
230
+ ```
231
+
232
+ ### โš ๏ธ State ์ˆ˜์ • ์‹œ ์ฃผ์˜์‚ฌํ•ญ
233
+
234
+ ```python
235
+ # โŒ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•: ์„ธ์…˜ ๊ฐ์ฒด ์ง์ ‘ ์ˆ˜์ •
236
+ session = await session_service.get_session(...)
237
+ session.state["key"] = "value" # ์ถ”์ ๋˜์ง€ ์•Š์Œ!
238
+
239
+ # โœ… ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•: Context๋ฅผ ํ†ตํ•ด ์ˆ˜์ •
240
+ def my_callback(context: CallbackContext):
241
+ context.state["key"] = "value" # ์ž๋™ ์ถ”์ ๋จ
242
+ ```
243
+
244
+ ---
245
+
246
+ ## 4. Event (์ด๋ฒคํŠธ)
247
+
248
+ ### ๊ฐœ๋…
249
+
250
+ **Event**๋Š” ์„ธ์…˜ ๋‚ด์—์„œ ๋ฐœ์ƒํ•˜๋Š” **๋ชจ๋“  ํ™œ๋™์˜ ๊ธฐ๋ก ๋‹จ์œ„**์ž…๋‹ˆ๋‹ค.
251
+ ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€, ์—์ด์ „ํŠธ ์‘๋‹ต, ๋„๊ตฌ ํ˜ธ์ถœ, ์ƒํƒœ ๋ณ€๊ฒฝ ๋“ฑ ๋ชจ๋“  ๊ฒƒ์ด ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.
252
+
253
+ ### Event ๊ตฌ์กฐ
254
+
255
+ ```python
256
+ from google.adk.events import Event, EventActions
257
+
258
+ event = Event(
259
+ # ์‹๋ณ„ ์ •๋ณด
260
+ id="event_123", # ๊ณ ์œ  ID
261
+ invocation_id="inv_456", # ์†Œ์† invocation ID
262
+ author="MyAgent", # ์ƒ์„ฑ์ž (์—์ด์ „ํŠธ๋ช…)
263
+
264
+ # ๋‚ด์šฉ
265
+ content=types.Content( # ์‹ค์ œ ๋ฉ”์‹œ์ง€/๋ฐ์ดํ„ฐ
266
+ parts=[types.Part(text="์•ˆ๋…•ํ•˜์„ธ์š”!")]
267
+ ),
268
+
269
+ # ์•ก์…˜/๋ณ€๊ฒฝ์‚ฌํ•ญ
270
+ actions=EventActions(
271
+ state_delta={"key": "value"}, # ์ƒํƒœ ๋ณ€๊ฒฝ
272
+ artifact_delta={}, # ์•„ํ‹ฐํŒฉํŠธ ๋ณ€๊ฒฝ
273
+ escalate=False, # ๋ฃจํ”„ ์ข…๋ฃŒ ์‹ ํ˜ธ
274
+ transfer_to_agent="OtherAgent", # ์—์ด์ „ํŠธ ์ „ํ™˜
275
+ ),
276
+
277
+ # ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
278
+ timestamp=1234567890.0,
279
+ partial=False, # ์ŠคํŠธ๋ฆฌ๋ฐ ์ค‘๊ฐ„ ๊ฒฐ๊ณผ ์—ฌ๋ถ€
280
+ )
281
+ ```
282
+
283
+ ### Event ์œ ํ˜•
284
+
285
+ | ์œ ํ˜• | ์„ค๋ช… | ์‹๋ณ„ ๋ฐฉ๋ฒ• |
286
+ | ------------- | -------------------- | -------------------------------- |
287
+ | ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€ | ์‚ฌ์šฉ์ž ์ž…๋ ฅ | `event.content.role == "user"` |
288
+ | ํ…์ŠคํŠธ ์‘๋‹ต | ์—์ด์ „ํŠธ ํ…์ŠคํŠธ ์‘๋‹ต | `event.content.parts[0].text` |
289
+ | ๋„๊ตฌ ํ˜ธ์ถœ | LLM์ด ๋„๊ตฌ ํ˜ธ์ถœ ์š”์ฒญ | `event.get_function_calls()` |
290
+ | ๋„๊ตฌ ๊ฒฐ๊ณผ | ๋„๊ตฌ ์‹คํ–‰ ๊ฒฐ๊ณผ | `event.get_function_responses()` |
291
+ | ์ƒํƒœ ๋ณ€๊ฒฝ | State ์—…๋ฐ์ดํŠธ | `event.actions.state_delta` |
292
+ | ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒญํฌ | ๋ถ€๋ถ„ ์‘๋‹ต | `event.partial == True` |
293
+
294
+ ### EventActions
295
+
296
+ ์ด๋ฒคํŠธ์— ์—ฐ๊ฒฐ๋œ **๋ถ€์ˆ˜ ํšจ๊ณผ(side effects)**๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค:
297
+
298
+ ```python
299
+ from google.adk.events import EventActions
300
+
301
+ actions = EventActions(
302
+ # ์ƒํƒœ ๋ณ€๊ฒฝ
303
+ state_delta={"new_key": "new_value"},
304
+
305
+ # ๋ฃจํ”„ ์ข…๋ฃŒ ์‹ ํ˜ธ (LoopAgent์—์„œ ์‚ฌ์šฉ)
306
+ escalate=True,
307
+
308
+ # ์—์ด์ „ํŠธ ์ „ํ™˜ (LLM Transfer)
309
+ transfer_to_agent="TargetAgentName",
310
+
311
+ # ์•„ํ‹ฐํŒฉํŠธ(ํŒŒ์ผ) ๋ณ€๊ฒฝ
312
+ artifact_delta={"file.txt": "content"},
313
+ )
314
+ ```
315
+
316
+ ### Event ์ฒ˜๋ฆฌ ํ๋ฆ„
317
+
318
+ ```
319
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
320
+ โ”‚ Event ์ƒ์„ฑ ๋ฐ ์ฒ˜๋ฆฌ ํ๋ฆ„ โ”‚
321
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
322
+
323
+ 1. Event ์ƒ์„ฑ
324
+ Agent/Tool/Callback โ†’ yield Event(...)
325
+
326
+ 2. Runner ์ˆ˜์‹ 
327
+ Runner๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์Œ
328
+
329
+ 3. SessionService ์ฒ˜๋ฆฌ
330
+ - state_delta๋ฅผ session.state์— ๋ณ‘ํ•ฉ
331
+ - artifact_delta ์ฒ˜๋ฆฌ
332
+ - events ํžˆ์Šคํ† ๋ฆฌ์— ์ถ”๊ฐ€
333
+
334
+ 4. ํด๋ผ์ด์–ธํŠธ ์ „๋‹ฌ
335
+ - UI/API๋กœ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ
336
+ ```
337
+
338
+ ---
339
+
340
+ ## 5. Context (์ปจํ…์ŠคํŠธ)
341
+
342
+ ### ๊ฐœ๋…
343
+
344
+ **Context**๋Š” ํ˜„์žฌ ์‹คํ–‰ ์ƒํ™ฉ์— ๋Œ€ํ•œ **๋ชจ๋“  ์ •๋ณด๋ฅผ ๋‹ด์€ ์ปจํ…Œ์ด๋„ˆ**์ž…๋‹ˆ๋‹ค.
345
+ ์—์ด์ „ํŠธ, ๋„๊ตฌ, ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
346
+
347
+ ### Context ์œ ํ˜•
348
+
349
+ #### 1. InvocationContext (ํ˜ธ์ถœ ์ปจํ…์ŠคํŠธ)
350
+
351
+ ๊ฐ€์žฅ ์ƒ์œ„ ๋ ˆ๋ฒจ์˜ ์ปจํ…์ŠคํŠธ๋กœ, ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ์š”์ฒญ ์ฒ˜๋ฆฌ ์ „์ฒด๋ฅผ ๊ด€์žฅํ•ฉ๋‹ˆ๋‹ค.
352
+
353
+ ```python
354
+ from google.adk.agents import BaseAgent
355
+ from google.adk.agents.invocation_context import InvocationContext
356
+
357
+ class MyAgent(BaseAgent):
358
+ async def _run_async_impl(self, ctx: InvocationContext):
359
+ # ์„ธ์…˜ ์ •๋ณด ์ ‘๊ทผ
360
+ session_id = ctx.session.id
361
+ user_id = ctx.session.user_id
362
+
363
+ # ์ƒํƒœ ์ ‘๊ทผ
364
+ state_value = ctx.session.state.get("key")
365
+
366
+ # ์„œ๋น„์Šค ์ ‘๊ทผ
367
+ memory_service = ctx.memory_service
368
+ artifact_service = ctx.artifact_service
369
+
370
+ # ํ˜„์žฌ ์—์ด์ „ํŠธ ์ •๋ณด
371
+ agent_name = ctx.agent.name
372
+
373
+ # ํ˜ธ์ถœ ์ œ์–ด
374
+ ctx.end_invocation = True # ํ˜ธ์ถœ ์ข…๋ฃŒ ์‹ ํ˜ธ
375
+
376
+ yield Event(author=self.name, content=...)
377
+ ```
378
+
379
+ #### 2. CallbackContext (์ฝœ๋ฐฑ ์ปจํ…์ŠคํŠธ)
380
+
381
+ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, InvocationContext์˜ ์„œ๋ธŒ์…‹์ž…๋‹ˆ๋‹ค.
382
+
383
+ ```python
384
+ from google.adk.agents.callback_context import CallbackContext
385
+
386
+ def my_before_agent_callback(ctx: CallbackContext):
387
+ # ์—์ด์ „ํŠธ ์ •๋ณด
388
+ agent_name = ctx.agent_name
389
+ invocation_id = ctx.invocation_id
390
+
391
+ # ์ƒํƒœ ์ฝ๊ธฐ/์“ฐ๊ธฐ
392
+ ctx.state["processed"] = True
393
+
394
+ # ์‚ฌ์šฉ์ž ์ž…๋ ฅ ํ™•์ธ
395
+ user_content = ctx.user_content
396
+
397
+ return None # ๊ณ„์† ์ง„ํ–‰ (๋˜๋Š” Content ๋ฐ˜ํ™˜ ์‹œ ์—์ด์ „ํŠธ ๊ฑด๋„ˆ๋œ€)
398
+ ```
399
+
400
+ #### 3. ToolContext (๋„๊ตฌ ์ปจํ…์ŠคํŠธ)
401
+
402
+ ๋„๊ตฌ(Tool) ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋„๊ตฌ ์‹คํ–‰์— ํ•„์š”ํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
403
+
404
+ ```python
405
+ from google.adk.tools import ToolContext
406
+
407
+ def my_tool(context: ToolContext, query: str) -> dict:
408
+ # ์ƒํƒœ ์ ‘๊ทผ (CallbackContext์™€ ๋™์ผ)
409
+ context.state["last_query"] = query
410
+
411
+ # ๋„๊ตฌ ์ „์šฉ ๊ธฐ๋Šฅ
412
+ function_call_id = context.function_call_id # ํ˜„์žฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ ID
413
+
414
+ # ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
415
+ results = await context.search_memory("๊ฒ€์ƒ‰์–ด")
416
+
417
+ # ์•„ํ‹ฐํŒฉํŠธ ๋ชฉ๋ก
418
+ artifacts = context.list_artifacts()
419
+
420
+ # ์ธ์ฆ ์š”์ฒญ (OAuth ๋“ฑ)
421
+ credential = await context.get_auth_response(auth_config)
422
+
423
+ return {"result": "success"}
424
+ ```
425
+
426
+ ### Context ๊ณ„์ธต ๊ตฌ์กฐ
427
+
428
+ ```
429
+ InvocationContext (์ตœ์ƒ์œ„)
430
+ โ”œโ”€โ”€ session
431
+ โ”‚ โ”œโ”€โ”€ state
432
+ โ”‚ โ””โ”€โ”€ events
433
+ โ”œโ”€โ”€ agent (ํ˜„์žฌ ์—์ด์ „ํŠธ)
434
+ โ”œโ”€โ”€ services (memory, artifact, session)
435
+ โ””โ”€โ”€ invocation_id
436
+
437
+ โ–ผ ํŒŒ์ƒ
438
+
439
+ CallbackContext (์ฝœ๋ฐฑ์šฉ)
440
+ โ”œโ”€โ”€ state (์ฝ๊ธฐ/์“ฐ๊ธฐ)
441
+ โ”œโ”€โ”€ agent_name
442
+ โ”œโ”€โ”€ user_content
443
+ โ””โ”€โ”€ invocation_id
444
+
445
+ โ–ผ ํ™•์žฅ
446
+
447
+ ToolContext (๋„๊ตฌ์šฉ)
448
+ โ”œโ”€โ”€ (CallbackContext์˜ ๋ชจ๋“  ๊ฒƒ)
449
+ โ”œโ”€โ”€ function_call_id
450
+ โ”œโ”€โ”€ search_memory()
451
+ โ”œโ”€โ”€ list_artifacts()
452
+ โ””โ”€โ”€ request_credential()
453
+ ```
454
+
455
+ ---
456
+
457
+ ## 6. Runner (๋Ÿฌ๋„ˆ)
458
+
459
+ ### ๊ฐœ๋…
460
+
461
+ **Runner**๋Š” ์—์ด์ „ํŠธ ์‹คํ–‰์˜ **์ค‘์•™ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ**์ž…๋‹ˆ๋‹ค.
462
+ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ฐ›์•„ ์—์ด์ „ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์„œ๋น„์Šค๋“ค์„ ์กฐ์œจํ•ฉ๋‹ˆ๋‹ค.
463
+
464
+ ### ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•
465
+
466
+ ```python
467
+ from google.adk.runners import InMemoryRunner, Runner
468
+ from google.adk.sessions import InMemorySessionService
469
+
470
+ # ๋ฐฉ๋ฒ• 1: InMemoryRunner (๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ์šฉ)
471
+ runner = InMemoryRunner(
472
+ agent=my_agent,
473
+ app_name="my_app"
474
+ )
475
+
476
+ # ๋ฐฉ๋ฒ• 2: Runner (์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•„์š” ์‹œ)
477
+ session_service = InMemorySessionService()
478
+ runner = Runner(
479
+ agent=my_agent,
480
+ app_name="my_app",
481
+ session_service=session_service,
482
+ # memory_service=my_memory_service, # ์˜ต์…˜
483
+ # artifact_service=my_artifact_service, # ์˜ต์…˜
484
+ )
485
+ ```
486
+
487
+ ### ์—์ด์ „ํŠธ ์‹คํ–‰
488
+
489
+ ```python
490
+ # ๋น„๋™๊ธฐ ์‹คํ–‰ (์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•)
491
+ async for event in runner.run_async(
492
+ user_id="user_123",
493
+ session_id="session_456", # ์ƒˆ ์„ธ์…˜์ด๋ฉด ์ž๋™ ์ƒ์„ฑ
494
+ new_message="์•ˆ๋…•ํ•˜์„ธ์š”!"
495
+ ):
496
+ if event.content and event.content.parts:
497
+ for part in event.content.parts:
498
+ if hasattr(part, 'text') and part.text:
499
+ print(f"[{event.author}]: {part.text}")
500
+
501
+ # ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ (์Œ์„ฑ/์˜์ƒ)
502
+ async for event in runner.run_live(...):
503
+ ...
504
+ ```
505
+
506
+ ### Runner ์‹คํ–‰ ํ๋ฆ„
507
+
508
+ ```
509
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
510
+ โ”‚ Runner.run_async() ํ๋ฆ„ โ”‚
511
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
512
+
513
+ 1. ์„ธ์…˜ ์ค€๋น„
514
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
515
+ โ”‚ get/create โ”‚ โ† ์„ธ์…˜ ์กฐํšŒ ๋˜๋Š” ์ƒ์„ฑ
516
+ โ”‚ Session โ”‚
517
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
518
+ โ”‚
519
+ โ–ผ
520
+ 2. ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€๋ฅผ ์ด๋ฒคํŠธ๋กœ ์ถ”๊ฐ€
521
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
522
+ โ”‚ append_event โ”‚ โ† ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์„ธ์…˜ ํžˆ์Šคํ† ๋ฆฌ์— ์ถ”๊ฐ€
523
+ โ”‚ (user message) โ”‚
524
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
525
+ โ”‚
526
+ โ–ผ
527
+ 3. InvocationContext ์ƒ์„ฑ
528
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
529
+ โ”‚ Create โ”‚ โ† ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด ์ค€๋น„
530
+ โ”‚ InvocationContextโ”‚
531
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
532
+ ๏ฟฝ๏ฟฝ
533
+ โ–ผ
534
+ 4. ์—์ด์ „ํŠธ ์‹คํ–‰ ๋ฃจํ”„
535
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
536
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
537
+ โ”‚ โ”‚ Agent.run() โ”‚ โ† ์—์ด์ „ํŠธ ์‹คํ–‰ โ”‚
538
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
539
+ โ”‚ โ”‚ โ”‚
540
+ โ”‚ โ–ผ โ”‚
541
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
542
+ โ”‚ โ”‚ yield Event โ”‚ โ† ์ด๋ฒคํŠธ ์ƒ์„ฑ โ”‚
543
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
544
+ โ”‚ โ”‚ โ”‚
545
+ โ”‚ โ–ผ โ”‚
546
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
547
+ โ”‚ โ”‚ Process Event โ”‚ โ† ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ โ”‚
548
+ โ”‚ โ”‚ - state_delta โ”‚ (์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋“ฑ) โ”‚
549
+ โ”‚ โ”‚ - append to โ”‚ โ”‚
550
+ โ”‚ โ”‚ session โ”‚ โ”‚
551
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
552
+ โ”‚ โ”‚ โ”‚
553
+ โ”‚ โ–ผ โ”‚
554
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
555
+ โ”‚ โ”‚ yield to caller โ”‚ โ† ํ˜ธ์ถœ์ž์—๊ฒŒ ์ „๋‹ฌ โ”‚
556
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
557
+ โ”‚ โ”‚ โ”‚
558
+ โ”‚ โ–ผ โ”‚
559
+ โ”‚ [๋” ๋งŽ์€ ์ด๋ฒคํŠธ?] โ”€โ”€Yesโ”€โ”€โ–ถ (๋ฐ˜๋ณต) โ”‚
560
+ โ”‚ โ”‚ โ”‚
561
+ โ”‚ No โ”‚
562
+ โ”‚ โ”‚ โ”‚
563
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
564
+ โ”‚
565
+ โ–ผ
566
+ 5. ์‹คํ–‰ ์™„๋ฃŒ
567
+ ```
568
+
569
+ ### Invocation vs Agent Call vs Step
570
+
571
+ ```
572
+ Invocation (ํ˜ธ์ถœ)
573
+ โ”‚ ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€ โ†’ ์ตœ์ข… ์‘๋‹ต๊นŒ์ง€์˜ ์ „์ฒด ์‚ฌ์ดํด
574
+ โ”‚
575
+ โ”œโ”€โ”€ Agent Call 1 (์—์ด์ „ํŠธ ํ˜ธ์ถœ)
576
+ โ”‚ โ”‚ ํ•˜๋‚˜์˜ ์—์ด์ „ํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋‹จ์œ„
577
+ โ”‚ โ”‚
578
+ โ”‚ โ”œโ”€โ”€ Step 1 (์Šคํ…)
579
+ โ”‚ โ”‚ โ””โ”€โ”€ LLM ํ˜ธ์ถœ 1ํšŒ + ๋„๊ตฌ ์‹คํ–‰
580
+ โ”‚ โ”‚
581
+ โ”‚ โ”œโ”€โ”€ Step 2
582
+ โ”‚ โ”‚ โ””โ”€โ”€ LLM ํ˜ธ์ถœ 1ํšŒ + ๋„๊ตฌ ์‹คํ–‰
583
+ โ”‚ โ”‚
584
+ โ”‚ โ””โ”€โ”€ (transfer_to_agent ๋ฐœ์ƒ)
585
+ โ”‚
586
+ โ”œโ”€โ”€ Agent Call 2 (๋‹ค๋ฅธ ์—์ด์ „ํŠธ๋กœ ์ „ํ™˜)
587
+ โ”‚ โ”‚
588
+ โ”‚ โ”œโ”€โ”€ Step 1
589
+ โ”‚ โ”‚ โ””โ”€โ”€ LLM ํ˜ธ์ถœ + ์ตœ์ข… ์‘๋‹ต
590
+ โ”‚ โ”‚
591
+ โ”‚ โ””โ”€โ”€ (์™„๋ฃŒ)
592
+ โ”‚
593
+ โ””โ”€โ”€ Invocation ์ข…๋ฃŒ
594
+ ```
595
+
596
+ ---
597
+
598
+ ## 7. Memory (๋ฉ”๋ชจ๋ฆฌ)
599
+
600
+ ### ๊ฐœ๋…
601
+
602
+ **Memory**๋Š” **์žฅ๊ธฐ ๊ธฐ์–ต ์ €์žฅ์†Œ**์ž…๋‹ˆ๋‹ค.
603
+ ์„ธ์…˜์ด ์ข…๋ฃŒ๋œ ํ›„์—๋„ ์œ ์ง€๋˜๋ฉฐ, ์—ฌ๋Ÿฌ ์„ธ์…˜์— ๊ฑธ์ณ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
604
+
605
+ ### Session State vs Memory ๋น„๊ต
606
+
607
+ | ํŠน์„ฑ | Session State | Memory |
608
+ | --------- | ------------------------ | --------------- |
609
+ | ๋ฒ”์œ„ | ํ˜„์žฌ ์„ธ์…˜ ๋‚ด | ์—ฌ๋Ÿฌ ์„ธ์…˜ ๊ฑธ์ณ |
610
+ | ์ˆ˜๋ช… | ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ (๋ณดํ†ต) ์‚ญ์ œ | ์˜๊ตฌ ์ €์žฅ |
611
+ | ์ ‘๊ทผ ๋ฐฉ์‹ | Key-Value ์ง์ ‘ ์ ‘๊ทผ | ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ |
612
+ | ์šฉ๋„ | ๋Œ€ํ™” ์ค‘ ์ž„์‹œ ๋ฐ์ดํ„ฐ | ๊ณผ๊ฑฐ ์ •๋ณด ์ฐธ์กฐ |
613
+ | ๋น„์œ  | ๋Œ€ํ™” ์ค‘ ๋ฉ”๋ชจ์žฅ | ๋„์„œ๊ด€ ์•„์นด์ด๋ธŒ |
614
+
615
+ ### MemoryService ์‚ฌ์šฉ
616
+
617
+ ```python
618
+ from google.adk.memory import InMemoryMemoryService
619
+
620
+ # ๋ฉ”๋ชจ๋ฆฌ ์„œ๋น„์Šค ์ƒ์„ฑ
621
+ memory_service = InMemoryMemoryService()
622
+
623
+ # ์„ธ์…˜์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ (๋Œ€ํ™” ์ข…๋ฃŒ ํ›„)
624
+ await memory_service.add_session_to_memory(session)
625
+
626
+ # ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
627
+ results = await memory_service.search_memory(
628
+ app_name="my_app",
629
+ user_id="user_123",
630
+ query="์ด์ „์— ์ถ”์ฒœ๋ฐ›์€ ์Œ์‹์ "
631
+ )
632
+
633
+ for result in results.memories:
634
+ print(result.content)
635
+ ```
636
+
637
+ ### MemoryService ๊ตฌํ˜„์ฒด
638
+
639
+ | ๊ตฌํ˜„์ฒด | ์ €์žฅ ๋ฐฉ์‹ | ๊ฒ€์ƒ‰ ๋ฐฉ์‹ | ์šฉ๋„ |
640
+ | --------------------------- | --------- | ----------- | ----------- |
641
+ | `InMemoryMemoryService` | ๋ฉ”๋ชจ๋ฆฌ | ํ‚ค์›Œ๋“œ ๋งค์นญ | ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ |
642
+ | `VertexAIMemoryBankService` | Vertex AI | ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ | ํ”„๋กœ๋•์…˜ |
643
+
644
+ ### ๋ฉ”๋ชจ๋ฆฌ ์›Œํฌํ”Œ๋กœ์šฐ
645
+
646
+ ```
647
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
648
+ โ”‚ Memory ์›Œํฌํ”Œ๋กœ์šฐ โ”‚
649
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€๏ฟฝ๏ฟฝ๏ฟฝโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
650
+
651
+ 1. ์„ธ์…˜ ๋Œ€ํ™” ์ง„ํ–‰
652
+ User โ†” Agent (Session์— Events ์ถ•์ )
653
+
654
+ 2. ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ
655
+ memory_service.add_session_to_memory(session)
656
+ โ””โ”€โ”€ ์„ธ์…˜์˜ ์ฃผ์š” ์ •๋ณด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ
657
+
658
+ 3. ์ดํ›„ ์„ธ์…˜์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
659
+ results = memory_service.search_memory(query)
660
+ โ””โ”€โ”€ ๊ณผ๊ฑฐ ๋Œ€ํ™”์—์„œ ๊ด€๋ จ ์ •๋ณด ๊ฒ€์ƒ‰
661
+
662
+ 4. ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ํ˜„์žฌ ๋Œ€ํ™”์— ํ™œ์šฉ
663
+ Agent๊ฐ€ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์‘๋‹ต
664
+ ```
665
+
666
+ ### ์—์ด์ „ํŠธ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ
667
+
668
+ ```python
669
+ from google.adk.tools import preload_memory_tool
670
+
671
+ # ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰ ๋„๊ตฌ ์ถ”๊ฐ€
672
+ agent = LlmAgent(
673
+ name="MemoryAgent",
674
+ instruction="์‚ฌ์šฉ์ž์˜ ๊ณผ๊ฑฐ ๋Œ€ํ™”๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๋‹ต๋ณ€ํ•˜์„ธ์š”.",
675
+ tools=[preload_memory_tool.PreloadMemoryTool()]
676
+ )
677
+
678
+ # ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ ์ž๋™ ์ €์žฅ ์ฝœ๋ฐฑ
679
+ async def auto_save_to_memory(callback_context):
680
+ await callback_context._invocation_context.memory_service.add_session_to_memory(
681
+ callback_context._invocation_context.session
682
+ )
683
+
684
+ agent = LlmAgent(
685
+ name="AutoSaveAgent",
686
+ after_agent_callback=auto_save_to_memory
687
+ )
688
+ ```
689
+
690
+ ---
691
+
692
+ ## 8. Callbacks (์ฝœ๋ฐฑ)
693
+
694
+ ### ๊ฐœ๋…
695
+
696
+ **Callback**์€ ์—์ด์ „ํŠธ ์‹คํ–‰ ์ค‘ **ํŠน์ • ์‹œ์ ์— ๊ฐœ์ž…**ํ•  ์ˆ˜ ์žˆ๋Š” ํ›…(hook)์ž…๋‹ˆ๋‹ค.
697
+ ๊ฐ€๋“œ๋ ˆ์ผ, ๋กœ๊น…, ์ˆ˜์ • ๋“ฑ ๋‹ค์–‘ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
698
+
699
+ ### ์ฝœ๋ฐฑ ์ข…๋ฅ˜ ๋ฐ ์‹คํ–‰ ์‹œ์ 
700
+
701
+ ```
702
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
703
+ โ”‚ ์ฝœ๋ฐฑ ์‹คํ–‰ ์‹œ์  โ”‚
704
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
705
+
706
+ ์‚ฌ์šฉ์ž ์ž…๋ ฅ
707
+ โ”‚
708
+ โ–ผ
709
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
710
+ โ”‚ before_agent_callback โ”‚ โ† ์—์ด์ „ํŠธ ์‹คํ–‰ ์ „
711
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
712
+ โ”‚
713
+ โ–ผ
714
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
715
+ โ”‚ before_model_callback โ”‚ โ† LLM ํ˜ธ์ถœ ์ „
716
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
717
+ โ”‚
718
+ โ–ผ
719
+ [LLM ํ˜ธ์ถœ]
720
+ โ”‚
721
+ โ–ผ
722
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
723
+ โ”‚ after_model_callback โ”‚ โ† LLM ์‘๋‹ต ํ›„
724
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
725
+ โ”‚
726
+ โ–ผ
727
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
728
+ โ”‚ before_tool_callback โ”‚ โ† ๋„๊ตฌ ์‹คํ–‰ ์ „
729
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
730
+ โ”‚
731
+ โ–ผ
732
+ [๋„๊ตฌ ์‹คํ–‰]
733
+ โ”‚
734
+ โ–ผ
735
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
736
+ โ”‚ after_tool_callback โ”‚ โ† ๋„๊ตฌ ์‹คํ–‰ ํ›„
737
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
738
+ โ”‚
739
+ โ–ผ
740
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
741
+ โ”‚ after_agent_callback โ”‚ โ† ์—์ด์ „ํŠธ ์‹คํ–‰ ํ›„
742
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
743
+ โ”‚
744
+ โ–ผ
745
+ ์ตœ์ข… ์‘๋‹ต
746
+ ```
747
+
748
+ ### ์ฝœ๋ฐฑ ์ •์˜ ๋ฐ ์‚ฌ์šฉ
749
+
750
+ #### before_agent_callback
751
+
752
+ ```python
753
+ from google.adk.agents import LlmAgent
754
+ from google.adk.agents.callback_context import CallbackContext
755
+ from google.genai import types
756
+
757
+ def check_access(ctx: CallbackContext) -> types.Content | None:
758
+ """์—์ด์ „ํŠธ ์‹คํ–‰ ์ „ ์ ‘๊ทผ ์ œ์–ด"""
759
+ user_id = ctx.session.user_id
760
+
761
+ # ์ฐจ๋‹จํ•  ์‚ฌ์šฉ์ž ์ฒดํฌ
762
+ if user_id in BLOCKED_USERS:
763
+ # Content ๋ฐ˜ํ™˜ ์‹œ ์—์ด์ „ํŠธ ์‹คํ–‰ ๊ฑด๋„ˆ๋œ€
764
+ return types.Content(
765
+ parts=[types.Part(text="์ ‘๊ทผ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")]
766
+ )
767
+
768
+ # None ๋ฐ˜ํ™˜ ์‹œ ์ •์ƒ ์ง„ํ–‰
769
+ return None
770
+
771
+ agent = LlmAgent(
772
+ name="SecureAgent",
773
+ before_agent_callback=check_access
774
+ )
775
+ ```
776
+
777
+ #### before_model_callback (๊ฐ€๋“œ๋ ˆ์ผ)
778
+
779
+ ```python
780
+ from google.adk.models import LlmRequest, LlmResponse
781
+
782
+ def content_guardrail(ctx: CallbackContext, request: LlmRequest) -> LlmResponse | None:
783
+ """LLM ํ˜ธ์ถœ ์ „ ์ž…๋ ฅ ๊ฒ€์‚ฌ"""
784
+ user_text = ctx.user_content.parts[0].text
785
+
786
+ # ๊ธˆ์ง€์–ด ์ฒดํฌ
787
+ if any(word in user_text for word in FORBIDDEN_WORDS):
788
+ return LlmResponse(
789
+ content=types.Content(
790
+ parts=[types.Part(text="๋ถ€์ ์ ˆํ•œ ๋‚ด์šฉ์ด ๊ฐ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")]
791
+ )
792
+ )
793
+
794
+ # ํ”„๋กฌํ”„ํŠธ ์ˆ˜์ •
795
+ # request.contents๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์‹œ์Šคํ…œ ์ง€์‹œ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
796
+
797
+ return None # ์ •์ƒ ์ง„ํ–‰
798
+
799
+ agent = LlmAgent(
800
+ name="GuardedAgent",
801
+ before_model_callback=content_guardrail
802
+ )
803
+ ```
804
+
805
+ #### after_model_callback
806
+
807
+ ```python
808
+ def post_process_response(ctx: CallbackContext, response: LlmResponse) -> LlmResponse | None:
809
+ """LLM ์‘๋‹ต ํ›„์ฒ˜๋ฆฌ"""
810
+ # ์‘๋‹ต ๋กœ๊น…
811
+ print(f"LLM Response: {response.content}")
812
+
813
+ # ์‘๋‹ต ์ˆ˜์ • (ํ•„์š”์‹œ)
814
+ # return modified_response
815
+
816
+ return None # ์›๋ณธ ์‘๋‹ต ์œ ์ง€
817
+
818
+ agent = LlmAgent(
819
+ name="LoggingAgent",
820
+ after_model_callback=post_process_response
821
+ )
822
+ ```
823
+
824
+ #### before_tool_callback / after_tool_callback
825
+
826
+ ```python
827
+ def tool_guardrail(ctx: ToolContext, tool_name: str, args: dict) -> dict | None:
828
+ """๋„๊ตฌ ์‹คํ–‰ ์ „ ๊ฒ€์‚ฌ"""
829
+ if tool_name == "delete_file" and not ctx.state.get("admin"):
830
+ return {"error": "๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค."} # ๋„๊ตฌ ์‹คํ–‰ ๊ฑด๋„ˆ๋œ€
831
+ return None
832
+
833
+ def log_tool_result(ctx: ToolContext, tool_name: str, result: dict) -> dict | None:
834
+ """๋„๊ตฌ ์‹คํ–‰ ํ›„ ๋กœ๊น…"""
835
+ print(f"Tool {tool_name} returned: {result}")
836
+ return None # ๊ฒฐ๊ณผ ์œ ์ง€
837
+
838
+ agent = LlmAgent(
839
+ name="ToolAuditAgent",
840
+ before_tool_callback=tool_guardrail,
841
+ after_tool_callback=log_tool_result
842
+ )
843
+ ```
844
+
845
+ ### ์ฝœ๋ฐฑ ๋ฐ˜ํ™˜๊ฐ’์˜ ์˜๋ฏธ
846
+
847
+ | ์ฝœ๋ฐฑ | ๋ฐ˜ํ™˜๊ฐ’ | ํšจ๊ณผ |
848
+ | ------------ | ------------- | ------------------------------------ |
849
+ | before_agent | `None` | ์—์ด์ „ํŠธ ์ •์ƒ ์‹คํ–‰ |
850
+ | before_agent | `Content` | ์—์ด์ „ํŠธ ๊ฑด๋„ˆ๋œ€, ๋ฐ˜ํ™˜๋œ Content ์‚ฌ์šฉ |
851
+ | before_model | `None` | LLM ์ •์ƒ ํ˜ธ์ถœ |
852
+ | before_model | `LlmResponse` | LLM ํ˜ธ์ถœ ๊ฑด๋„ˆ๋œ€, ๋ฐ˜ํ™˜๋œ ์‘๋‹ต ์‚ฌ์šฉ |
853
+ | before_tool | `None` | ๋„๊ตฌ ์ •์ƒ ์‹คํ–‰ |
854
+ | before_tool | `dict` | ๋„๊ตฌ ์‹คํ–‰ ๊ฑด๋„ˆ๋œ€, ๋ฐ˜ํ™˜๋œ ๊ฒฐ๊ณผ ์‚ฌ์šฉ |
855
+
856
+ ---
857
+
858
+ ## 9. Tools (๋„๊ตฌ)
859
+
860
+ ### ๊ฐœ๋…
861
+
862
+ **Tool**์€ ์—์ด์ „ํŠธ์—๊ฒŒ **์™ธ๋ถ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณต**ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
863
+ API ํ˜ธ์ถœ, ๊ณ„์‚ฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐํšŒ ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
864
+
865
+ ### Tool ์œ ํ˜•
866
+
867
+ #### 1. FunctionTool (ํ•จ์ˆ˜ ๋„๊ตฌ)
868
+
869
+ Python ํ•จ์ˆ˜๋ฅผ ๋„๊ตฌ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
870
+
871
+ ```python
872
+ from google.adk.tools import FunctionTool
873
+
874
+ def get_weather(city: str, unit: str = "celsius") -> dict:
875
+ """
876
+ ํŠน์ • ๋„์‹œ์˜ ๋‚ ์”จ๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
877
+
878
+ Args:
879
+ city: ์กฐํšŒํ•  ๋„์‹œ ์ด๋ฆ„
880
+ unit: ์˜จ๋„ ๋‹จ์œ„ (celsius ๋˜๋Š” fahrenheit)
881
+
882
+ Returns:
883
+ ๋‚ ์”จ ์ •๋ณด ๋”•์…”๋„ˆ๋ฆฌ
884
+ """
885
+ # ์‹ค์ œ API ํ˜ธ์ถœ ๋˜๋Š” ์‹œ๋ฎฌ๋ ˆ์ด์…˜
886
+ return {"city": city, "temp": 20, "unit": unit}
887
+
888
+ # ํ•จ์ˆ˜๋ฅผ ๋„๊ตฌ๋กœ ๋ณ€ํ™˜
889
+ weather_tool = FunctionTool(func=get_weather)
890
+
891
+ # ์—์ด์ „ํŠธ์— ๋„๊ตฌ ์ถ”๊ฐ€
892
+ agent = LlmAgent(
893
+ name="WeatherAgent",
894
+ tools=[weather_tool]
895
+ )
896
+ ```
897
+
898
+ #### 2. AgentTool (์—์ด์ „ํŠธ๋ฅผ ๋„๊ตฌ๋กœ)
899
+
900
+ ๋‹ค๋ฅธ ์—์ด์ „ํŠธ๋ฅผ ๋„๊ตฌ์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
901
+
902
+ ```python
903
+ from google.adk.tools import agent_tool
904
+
905
+ # ์ „๋ฌธ ์—์ด์ „ํŠธ ์ •์˜
906
+ translator = LlmAgent(
907
+ name="Translator",
908
+ description="ํ…์ŠคํŠธ๋ฅผ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๋‹ค."
909
+ )
910
+
911
+ # ์—์ด์ „ํŠธ๋ฅผ ๋„๊ตฌ๋กœ ๋ž˜ํ•‘
912
+ translator_tool = agent_tool.AgentTool(agent=translator)
913
+
914
+ # ๋‹ค๋ฅธ ์—์ด์ „ํŠธ์—์„œ ๋„๊ตฌ๋กœ ์‚ฌ์šฉ
915
+ main_agent = LlmAgent(
916
+ name="MainAgent",
917
+ tools=[translator_tool]
918
+ )
919
+ ```
920
+
921
+ ### ToolContext ํ™œ์šฉ
922
+
923
+ ๋„๊ตฌ ํ•จ์ˆ˜ ๋‚ด์—์„œ Context์— ์ ‘๊ทผํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
924
+
925
+ ```python
926
+ from google.adk.tools import ToolContext
927
+
928
+ def advanced_tool(context: ToolContext, query: str) -> dict:
929
+ # 1. ์ƒํƒœ ์ฝ๊ธฐ/์“ฐ๊ธฐ
930
+ context.state["last_query"] = query
931
+ previous = context.state.get("history", [])
932
+
933
+ # 2. ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
934
+ memory_results = await context.search_memory(query)
935
+
936
+ # 3. ์•„ํ‹ฐํŒฉํŠธ ๋ชฉ๋ก ์กฐํšŒ
937
+ artifacts = context.list_artifacts()
938
+
939
+ # 4. ์ธ์ฆ ์ฒ˜๋ฆฌ
940
+ if needs_auth:
941
+ cred = await context.get_auth_response(oauth_config)
942
+
943
+ return {"result": "processed"}
944
+ ```
945
+
946
+ ### ๋„๊ตฌ ์‹คํ–‰ ํ๋ฆ„
947
+
948
+ ```
949
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
950
+ โ”‚ ๋„๊ตฌ ์‹คํ–‰ ํ๋ฆ„ โ”‚
951
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
952
+
953
+ 1. LLM์ด ๋„๊ตฌ ํ˜ธ์ถœ ๊ฒฐ์ •
954
+ LLM Response: FunctionCall(name="get_weather", args={"city": "์„œ์šธ"})
955
+
956
+ 2. ADK๊ฐ€ ๋„๊ตฌ ์ฐพ๊ธฐ
957
+ tools ๋ชฉ๋ก์—์„œ "get_weather" ์ฐพ์Œ
958
+
959
+ 3. before_tool_callback ์‹คํ–‰ (์žˆ์œผ๋ฉด)
960
+ ๊ฐ€๋“œ๋ ˆ์ผ, ๋กœ๊น… ๋“ฑ
961
+
962
+ 4. ๋„๊ตฌ ํ•จ์ˆ˜ ์‹คํ–‰
963
+ result = get_weather(city="์„œ์šธ")
964
+
965
+ 5. after_tool_callback ์‹คํ–‰ (์žˆ์œผ๋ฉด)
966
+ ๊ฒฐ๊ณผ ํ›„์ฒ˜๋ฆฌ, ๋กœ๊น… ๋“ฑ
967
+
968
+ 6. FunctionResponse ์ด๋ฒคํŠธ ์ƒ์„ฑ
969
+ Event(content=FunctionResponse(name="get_weather", response=result))
970
+
971
+ 7. LLM์—๊ฒŒ ๊ฒฐ๊ณผ ์ „๋‹ฌ
972
+ LLM์ด ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ  ๋‹ค์Œ ์‘๋‹ต ์ƒ์„ฑ
973
+ ```
974
+
975
+ ---
976
+
977
+ ## 10. ํ•ต์‹ฌ ๊ฐœ๋… ๊ฐ„์˜ ๊ด€๊ณ„
978
+
979
+ ### ์ „์ฒด ๊ด€๊ณ„๋„
980
+
981
+ ```
982
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€๏ฟฝ๏ฟฝ๏ฟฝโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
983
+ โ”‚ ADK ํ•ต์‹ฌ ๊ฐœ๋… ๊ด€๊ณ„๋„ โ”‚
984
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
985
+
986
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
987
+ โ”‚ Runner โ”‚
988
+ โ”‚ (์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ) โ”‚
989
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
990
+ โ”‚
991
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
992
+ โ–ผ โ–ผ โ–ผ
993
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
994
+ โ”‚ SessionSvc โ”‚ โ”‚ MemorySvc โ”‚ โ”‚ ArtifactSvc โ”‚
995
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
996
+ โ”‚ โ”‚
997
+ โ–ผ โ”‚
998
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
999
+ โ”‚ Session โ”‚ โ”‚
1000
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚
1001
+ โ”‚ โ”‚ State โ”‚โ—€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€ ์—์ด์ „ํŠธ๊ฐ€ ์ฝ๊ณ /์”€
1002
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚
1003
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚
1004
+ โ”‚ โ”‚ Events โ”‚ โ”‚ โ”‚
1005
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚
1006
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
1007
+ โ”‚ โ”‚
1008
+ โ–ผ โ–ผ
1009
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1010
+ โ”‚ InvocationContext โ”‚
1011
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
1012
+ โ”‚ โ”‚ session, state, services, agent โ”‚ โ”‚
1013
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
1014
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
1015
+ โ”‚
1016
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1017
+ โ–ผ โ–ผ โ–ผ
1018
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1019
+ โ”‚ Callbacks โ”‚ โ”‚ Agent โ”‚ โ”‚ Tools โ”‚
1020
+ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
1021
+ โ”‚ Callback โ”‚ โ”‚ โ”‚ โ”‚ Tool โ”‚
1022
+ โ”‚ Context โ”‚ โ”‚ โ”‚ โ”‚ Context โ”‚
1023
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
1024
+ โ”‚ โ”‚ โ”‚
1025
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
1026
+ โ–ผ
1027
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1028
+ โ”‚ Event โ”‚
1029
+ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
1030
+ โ”‚ โ”‚Actionsโ”‚ โ”€โ”€โ–ถ state_delta
1031
+ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ escalate
1032
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ transfer
1033
+ ```
1034
+
1035
+ ### ๋ฐ์ดํ„ฐ ํ๋ฆ„ ์š”์•ฝ
1036
+
1037
+ ```
1038
+ 1. ์‚ฌ์šฉ์ž ์ž…๋ ฅ
1039
+ โ””โ”€โ”€โ–ถ Runner.run_async(message)
1040
+
1041
+ 2. ์„ธ์…˜ ์ค€๋น„
1042
+ โ””โ”€โ”€โ–ถ SessionService.get_session() โ†’ Session
1043
+
1044
+ 3. ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ
1045
+ โ””โ”€โ”€โ–ถ InvocationContext(session, services, ...)
1046
+
1047
+ 4. ์ฝœ๋ฐฑ ์‹คํ–‰
1048
+ โ””โ”€โ”€โ–ถ before_agent_callback(CallbackContext)
1049
+
1050
+ 5. ์—์ด์ „ํŠธ ์‹คํ–‰
1051
+ โ””โ”€โ”€โ–ถ Agent.run(InvocationContext)
1052
+ โ”‚
1053
+ โ”œโ”€โ”€โ–ถ before_model_callback
1054
+ โ”œโ”€โ”€โ–ถ LLM ํ˜ธ์ถœ
1055
+ โ”œโ”€โ”€โ–ถ after_model_callback
1056
+ โ”‚
1057
+ โ”œโ”€โ”€โ–ถ [๋„๊ตฌ ํ˜ธ์ถœ ์‹œ]
1058
+ โ”‚ โ”œโ”€โ”€โ–ถ before_tool_callback
1059
+ โ”‚ โ”œโ”€โ”€โ–ถ Tool ์‹คํ–‰(ToolContext)
1060
+ โ”‚ โ””โ”€โ”€โ–ถ after_tool_callback
1061
+ โ”‚
1062
+ โ””โ”€โ”€โ–ถ yield Event
1063
+
1064
+ 6. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
1065
+ โ””โ”€โ”€โ–ถ SessionService.append_event(event)
1066
+ โ””โ”€โ”€โ–ถ state_delta ์ ์šฉ
1067
+ โ””โ”€โ”€โ–ถ events ํžˆ์Šคํ† ๋ฆฌ ์ถ”๊ฐ€
1068
+
1069
+ 7. ์ฝœ๋ฐฑ ์‹คํ–‰
1070
+ โ””โ”€โ”€โ–ถ after_agent_callback(CallbackContext)
1071
+
1072
+ 8. ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
1073
+ โ””โ”€โ”€โ–ถ yield event to caller
1074
+ ```
1075
+
1076
+ ### ํ•ต์‹ฌ ํฌ์ธํŠธ ์ •๋ฆฌ
1077
+
1078
+ | ๊ฐœ๋… | ์—ญํ•  | ๋น„์œ  |
1079
+ | ------------ | -------------- | ------------------- |
1080
+ | **Session** | ๋Œ€ํ™” ์ปจํ…Œ์ด๋„ˆ | ์ „ํ™” ํ†ตํ™” ํ•œ ๊ฑด |
1081
+ | **State** | ๋Œ€ํ™” ์ค‘ ๋ฉ”๋ชจ | ๋ฉ”๋ชจ์žฅ/์Šคํฌ๋ž˜์น˜ํŒจ๋“œ |
1082
+ | **Event** | ํ™œ๋™ ๊ธฐ๋ก ๋‹จ์œ„ | ๋Œ€ํ™” ๊ธฐ๋ก์˜ ํ•œ ์ค„ |
1083
+ | **Context** | ์‹คํ–‰ ์ •๋ณด ๋ฌถ์Œ | ์—…๋ฌด ๋ฌธ๋งฅ/๋ฐฐ๊ฒฝ ์ •๋ณด |
1084
+ | **Runner** | ์‹คํ–‰ ์กฐ์œจ์ž | ์ง€ํœ˜์ž |
1085
+ | **Memory** | ์žฅ๊ธฐ ๊ธฐ์–ต | ๋„์„œ๊ด€ ์•„์นด์ด๋ธŒ |
1086
+ | **Callback** | ์‹คํ–‰ ์ค‘ ๊ฐœ์ž…์  | ์ฒดํฌํฌ์ธํŠธ/๊ด€๋ฌธ |
1087
+ | **Tool** | ์™ธ๋ถ€ ๊ธฐ๋Šฅ | ๋„๊ตฌ ์ƒ์ž |
1088
+
1089
+ ---
1090
+
1091
+ ## ๋ถ€๋ก: ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ (FAQ)
1092
+
1093
+ ### Q1: State์™€ Memory์˜ ์ฐจ์ด๋Š”?
1094
+
1095
+ - **State**: ํ˜„์žฌ ์„ธ์…˜ ๋‚ด์—์„œ๋งŒ ์œ ํšจ, ํ‚ค-๊ฐ’ ์ง์ ‘ ์ ‘๊ทผ
1096
+ - **Memory**: ์—ฌ๋Ÿฌ ์„ธ์…˜์— ๊ฑธ์ณ ์œ ์ง€, ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ๋กœ ์ ‘๊ทผ
1097
+
1098
+ ### Q2: output_key๊ฐ€ ์—†์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?
1099
+
1100
+ ์—์ด์ „ํŠธ์˜ ์‘๋‹ต์ด state์— ์ž๋™ ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
1101
+ ๋‹ค์Œ ์—์ด์ „ํŠธ์—์„œ ์ด์ „ ์‘๋‹ต์„ ์ฐธ์กฐํ•˜๋ ค๋ฉด output_key๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜,
1102
+ ์ง์ ‘ ์ฝœ๋ฐฑ/๋„๊ตฌ์—์„œ state๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
1103
+
1104
+ ### Q3: InMemorySessionService๋Š” ํ”„๋กœ๋•์…˜์—์„œ ์“ธ ์ˆ˜ ์žˆ๋‚˜์š”?
1105
+
1106
+ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ฑ ์žฌ์‹œ์ž‘ ์‹œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋ฉ๋‹ˆ๋‹ค.
1107
+ ํ”„๋กœ๋•์…˜์—์„œ๋Š” Database-backed ๋˜๋Š” Cloud-based ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
1108
+
1109
+ ### Q4: ์ฝœ๋ฐฑ์—์„œ Content๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋‚˜์š”?
1110
+
1111
+ before_agent_callback์—์„œ Content๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์—์ด์ „ํŠธ ์‹คํ–‰์ด ๊ฑด๋„ˆ๋›ฐ์–ด์ง€๊ณ ,
1112
+ ๋ฐ˜ํ™˜๋œ Content๊ฐ€ ์—์ด์ „ํŠธ์˜ ์‘๋‹ต์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
1113
+ ์ด๋ฅผ ํ†ตํ•ด ์กฐ๊ฑด๋ถ€ ๋‹จ์ถ•(short-circuit)์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1114
+
1115
+ ### Q5: LoopAgent์˜ escalate๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋‚˜์š”?
1116
+
1117
+ sub_agent๊ฐ€ Event๋ฅผ ์ƒ์„ฑํ•  ๋•Œ `actions=EventActions(escalate=True)`๋ฅผ ์„ค์ •ํ•˜๋ฉด,
1118
+ LoopAgent๊ฐ€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ฆ‰์‹œ ๋ฃจํ”„๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
1119
+ max_iterations์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์กฐ๊ฑด๋ถ€๋กœ ์ข…๋ฃŒํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
1120
+
1121
+ ---
1122
+
1123
+ ## ์ฐธ๊ณ  ์ž๋ฃŒ
1124
+
1125
+ - [ADK ๊ณต์‹ ๋ฌธ์„œ](https://google.github.io/adk-docs/)
1126
+ - [ADK GitHub (Python)](https://github.com/google/adk-python)
1127
+ - [Vertex AI Agent Engine](https://cloud.google.com/vertex-ai/docs/agents)
docs/agent-architecture.md ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Agent Architecture
2
+
3
+ ## ๊ฐœ์š”
4
+
5
+ ํ˜„์žฌ ๋ฉ”๊ตฌ๋ฐ ์ฑ—๋ด‡์€ ์•„๋ž˜ ํ๋ฆ„์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
6
+
7
+ 1. `bootstrap.py`์—์„œ ํ™˜๊ฒฝ๋ณ€์ˆ˜์™€ ๋Ÿฐํƒ€์ž„ ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ๋ฅผ ์ค€๋น„
8
+ 2. `retrieval.py`์—์„œ FAISS ์ธ๋ฑ์Šค์™€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œ
9
+ 3. `agent.py`์—์„œ Google ADK `LlmAgent`์™€ retrieval tool ๊ตฌ์„ฑ
10
+ 4. `chat.py`์—์„œ ์„ธ์…˜ ์‹คํ–‰๊ณผ ๋Œ€ํ™” ์š”์•ฝ ๊ด€๋ฆฌ
11
+ 5. `app_gradio.py`์—์„œ PC์šฉ ์ฑ„ํŒ… UI ์ œ๊ณต
12
+
13
+ ## ํŒŒ์ผ๋ณ„ ์—ญํ• 
14
+
15
+ ### `megumin_agent/bootstrap.py`
16
+
17
+ - `.env` ๋กœ๋“œ
18
+ - ๋กœ์ปฌ `adk-python/src` ๊ฒฝ๋กœ ๋“ฑ๋ก
19
+ - Hugging Face dataset repo์—์„œ ๋ฐ์ดํ„ฐ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
20
+ - ๋‹ค์šด๋กœ๋“œ ์‹คํŒจ ์‹œ ๋กœ์ปฌ `data/processed`๋ฅผ fallback์œผ๋กœ ์‚ฌ์šฉ
21
+
22
+ ๋‹ค์šด๋กœ๋“œ ๋Œ€์ƒ:
23
+
24
+ - `megumin_qa_dataset.json`
25
+ - `megumin_questions.faiss`
26
+ - `megumin_question_answer.faiss`
27
+ - `megumin_questions_meta.json`
28
+ - `namuwiki_qa.json`
29
+ - `namuwiki_questions.faiss`
30
+ - `namuwiki_question_answer.faiss`
31
+ - `namuwiki_questions_meta.json`
32
+
33
+ ### `megumin_agent/retrieval.py`
34
+
35
+ - QA JSON ๋ ˆ์ฝ”๋“œ ๋กœ๋“œ
36
+ - Gemini ์ž„๋ฒ ๋”ฉ ๊ธฐ๋ฐ˜ FAISS ๊ฒ€์ƒ‰
37
+ - question-only ์ธ๋ฑ์Šค์™€ question+answer ์ธ๋ฑ์Šค๋ฅผ ๋‘˜ ๋‹ค ์กฐํšŒ
38
+ - ๋‘ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ํ•ฉ์ณ ์ ์ˆ˜๊ฐ€ ๋†’์€ ํ›„๋ณด top-k๋ฅผ ๋ฐ˜ํ™˜
39
+
40
+ ๋ฐ์ดํ„ฐ ๊ณ„์ธต:
41
+
42
+ - ํŽ˜๋ฅด์†Œ๋‚˜ ๊ณ„์ธต: `megumin_qa_dataset.json`
43
+ - ์‚ฌ์‹ค ๊ณ„์ธต: `namuwiki_qa.json`
44
+
45
+ ### `megumin_agent/agent.py`
46
+
47
+ - ๋ฉ”๊ตฌ๋ฐ ํŽ˜๋ฅด์†Œ๋‚˜ ํ”„๋กฌํ”„ํŠธ ์ •์˜
48
+ - `retrieve_megumin_examples` tool ์ •์˜
49
+ - ํŽ˜๋ฅด์†Œ๋‚˜์šฉ top-3, ์‚ฌ์‹ค์šฉ top-3๋ฅผ ๊ฐ๊ฐ ์ˆ˜์ง‘
50
+ - ADK callback์œผ๋กœ ๋Œ€ํ™” ์š”์•ฝ, ์ตœ๊ทผ ์งˆ์˜, RAG ํ”์ ์„ state์— ๊ธฐ๋ก
51
+
52
+ tool ๋ฐ˜ํ™˜ ํ•ต์‹ฌ:
53
+
54
+ - `persona_matches`
55
+ - `fact_matches`
56
+ - `style_notes`
57
+ - `fact_notes`
58
+
59
+ ### `megumin_agent/chat.py`
60
+
61
+ - `Runner`์™€ `InMemorySessionService` ์ƒ์„ฑ
62
+ - ์งˆ๋ฌธ 1ํšŒ ์‹คํ–‰ ๋‹จ์œ„์ธ `chat_once()` ์ œ๊ณต
63
+ - ์ตœ๊ทผ 6ํ„ด์„ ๋‚จ๊ธฐ๊ณ , ๊ทธ ์ด์ „ ๋Œ€ํ™”๋Š” `conversation_summary`๋กœ ์••์ถ•
64
+
65
+ ### `app_gradio.py`
66
+
67
+ - PC์šฉ 3ํŒจ๋„ ๋ ˆ์ด์•„์›ƒ ์ œ๊ณต
68
+ - ์™ผ์ชฝ: ๋ฉ”๊ตฌ๋ฐ ํ”„๋กœํ•„, ํŽ˜๋ฅด์†Œ๋‚˜ ์„ค๋ช…, ์˜ˆ์‹œ ์งˆ๋ฌธ
69
+ - ๊ฐ€์šด๋ฐ: ๋ฐ˜ํˆฌ๋ช… ์ฑ„ํŒ… ํŒจ๋„
70
+ - ์˜ค๋ฅธ์ชฝ: ๋ฉ”๊ตฌ๋ฐ ๋น„์ฃผ์–ผ ํŒจ๋„
71
+ - ๋ฐฐ๊ฒฝ์—๋Š” ํ๋ฆฟํ•œ ๋ฉ”๊ตฌ๋ฐ ์ผ๋Ÿฌ์ŠคํŠธ์™€ ํญ๋ ฌ ๋ถ„์œ„๊ธฐ ๋ ˆ์ด์–ด๋ฅผ ๋ฐฐ์น˜
72
+
73
+ ### `app.py`
74
+
75
+ - Hugging Face Spaces ์ง„์ž…์ 
76
+ - `app_gradio.py`์˜ `demo`๋ฅผ ๊ทธ๋Œ€๋กœ ๋กœ๋“œ
77
+
78
+ ## ๋Œ€ํ™” ํ๋ฆ„
79
+
80
+ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด ๋“ค์–ด์˜ค๋ฉด:
81
+
82
+ 1. `app_gradio.py`๊ฐ€ `chat_once()` ํ˜ธ์ถœ
83
+ 2. `chat.py`๊ฐ€ ADK Runner๋กœ ์„ธ์…˜ ์‹คํ–‰
84
+ 3. `agent.py`์˜ tool์ด retrieval ์ˆ˜ํ–‰
85
+ 4. `retrieval.py`๊ฐ€
86
+ - ํŽ˜๋ฅด์†Œ๋‚˜ ๋ฐ์ดํ„ฐ top-3
87
+ - ์‚ฌ์‹ค ๋ฐ์ดํ„ฐ top-3
88
+ ๋ฅผ ๊ฐ๊ฐ ๊ฒ€์ƒ‰
89
+ 5. Agent๊ฐ€ ๋‘ ์ข…๋ฅ˜์˜ ๊ทผ๊ฑฐ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ๋ฉ”๊ตฌ๋ฐ ๋งํˆฌ๋กœ ๋‹ต๋ณ€
90
+ 6. ์„ธ์…˜ ์ข…๋ฃŒ ํ›„ ์˜ค๋ž˜๋œ ์ด๋ฒคํŠธ๋ฅผ ์š”์•ฝ ์ƒํƒœ๋กœ ์••์ถ•
91
+
92
+ ## ์„ธ์…˜๊ณผ ๋ฉ”๋ชจ๋ฆฌ
93
+
94
+ ํ˜„์žฌ ์ €์žฅ ๋ฐฉ์‹์€ `InMemorySessionService`์ž…๋‹ˆ๋‹ค.
95
+
96
+ - ์„œ๋ฒ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‚ด์•„ ์žˆ๋Š” ๋™์•ˆ๋งŒ ์œ ์ง€
97
+ - ์žฌ์‹œ์ž‘ ์‹œ ์ดˆ๊ธฐํ™”
98
+ - ์ตœ๊ทผ 6ํ„ด๋งŒ ์œ ์ง€
99
+ - ์˜ค๋ž˜๋œ ๋‚ด์šฉ์€ ์งง์€ summary๋กœ state์— ๋‚จ๊น€
100
+
101
+ ## UI ๋ชฉ์ 
102
+
103
+ ํ˜„์žฌ UI๋Š” ๋ชจ๋ฐ”์ผ ์ „์šฉ์ด ์•„๋‹ˆ๋ผ PC ํ™”๋ฉด ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.
104
+
105
+ - ์บ๋ฆญํ„ฐ์™€ ์‹ค์ œ๋กœ ๋งˆ์ฃผ ๋ณด๊ณ  ๋Œ€ํ™”ํ•˜๋Š” ๋А๋‚Œ
106
+ - ๋ฐ˜ํˆฌ๋ช… ์œ ๋ฆฌ ํŒจ๋„ ์ค‘์‹ฌ ๊ตฌ์„ฑ
107
+ - ๋ฉ”๊ตฌ๋ฐ ์„ธ๊ณ„๊ด€๊ณผ ์ฑ—๋ด‡ ์‚ฌ์šฉ๋ฒ•์„ ํ•œ ํ™”๋ฉด์—์„œ ์•ˆ๋‚ด
108
+
docs/data-collection-spec.md ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Data Collection Spec
2
+
3
+ ## ๊ฐœ์š”
4
+
5
+ ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋ฉ”๊ตฌ๋ฐ ์ฑ—๋ด‡์˜ RAG ์ž์›์„ ๋‘ ๊ณ„์ธต์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
6
+
7
+ - ์Šคํƒ€์ผ/ํŽ˜๋ฅด์†Œ๋‚˜์šฉ ๋ฐ์ดํ„ฐ
8
+ - ์˜ˆ: `megumin_qa_dataset.json`
9
+ - ์‚ฌ์‹ค/์„ค์ •์šฉ ๋ฐ์ดํ„ฐ
10
+ - ์˜ˆ: `namuwiki_qa.json`
11
+
12
+ ์‚ฌ์‹ค/์„ค์ •์šฉ ๋ฐ์ดํ„ฐ๋Š” ๋‚˜๋ฌด์œ„ํ‚ค ๋ฌธ์„œ๋ฅผ ์„ ๋ณ„ ์ˆ˜์ง‘ํ•ด QA JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์ดํ›„ FAISS ์ธ๋ฑ์Šค๋กœ ๊ฒ€์ƒ‰ํ•œ๋‹ค.
13
+
14
+ ## ์ˆ˜์ง‘ ๋Œ€์ƒ
15
+
16
+ ๋‚˜๋ฌด์œ„ํ‚ค ๋ฌธ์„œ๋Š” ๋ณ„์นญ์œผ๋กœ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‹ค์ œ ๊ฒ€์ƒ‰ ์‹œ์—๋Š” ์ •์‹ ๋ฌธ์„œ๋ช…์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
17
+
18
+ ์˜ˆ:
19
+
20
+ - `์นด์ฆˆ๋งˆ` -> `์‚ฌํ†  ์นด์ฆˆ๋งˆ`
21
+ - `์•„์ฟ ์•„` -> `์•„์ฟ ์•„(์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!)`
22
+ - `๋‹คํฌ๋‹ˆ์Šค` -> `๋‹คํฌ๋‹ˆ์Šค(์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!)`
23
+ - `์„ธ๊ณ„๊ด€` -> `์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!/์„ค์ •`
24
+ - `์ง€์—ญ` -> `์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!/์ง€์—ญ`
25
+
26
+ ์ €์žฅ ์‹œ `source.title`์€ ์งง์€ ํ‘œ์‹œ๋ช…์œผ๋กœ ์ •๊ทœํ™”ํ•œ๋‹ค.
27
+
28
+ ์˜ˆ:
29
+
30
+ - `์‚ฌํ†  ์นด์ฆˆ๋งˆ` -> `์นด์ฆˆ๋งˆ`
31
+ - `์•„์ฟ ์•„(์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!)` -> `์•„์ฟ ์•„`
32
+ - `์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!/์„ค์ •` -> `์„ธ๊ณ„๊ด€`
33
+ - `์ด ๋ฉ‹์ง„ ์„ธ๊ณ„์— ์ถ•๋ณต์„!/์ง€์—ญ` -> `์„ธ๊ณ„๊ด€`
34
+
35
+ ## ๋ณ€ํ™˜ ๊ทœ์น™
36
+
37
+ - ์ถœ๋ ฅ ํฌ๋งท์€ QA JSON ์œ ์ง€
38
+ - `question`์€ ์‚ฌ์šฉ์ž ์งˆ๋ฌธํ˜•์ด ์•„๋‹ˆ๋ผ ๊ฒ€์ƒ‰์šฉ ์†Œ์ œ๋ชฉ ์š”์•ฝ
39
+ - `answer`๋Š” ์ค‘๋ฆฝ ์š”์•ฝํ˜• ๋ณธ๋ฌธ
40
+ - ํ‘œ, ์ด๋ฏธ์ง€, ๋ถˆํ•„์š”ํ•œ ์žฅ์‹ ์š”์†Œ๋Š” ์ œ์™ธ
41
+ - chunk ๊ธธ์ด๋Š” ์•ฝ 200์ž ๋‚ด์™ธ
42
+ - chunk overlap์€ 1~2๋ฌธ์žฅ
43
+
44
+ ## ์ €์žฅ ํŒŒ์ผ
45
+
46
+ - `data/processed/namuwiki_qa.json`
47
+ - ๋‚˜๋ฌด์œ„ํ‚ค ๊ธฐ๋ฐ˜ ํ†ตํ•ฉ QA ๋ฐ์ดํ„ฐ
48
+ - `data/processed/megumin_qa_dataset.json`
49
+ - ๊ธฐ์กด ๋ฉ”๊ตฌ๋ฐ ์Šคํƒ€์ผ/ํŽ˜๋ฅด์†Œ๋‚˜ QA ๋ฐ์ดํ„ฐ
50
+ - `data/processed/megumin_questions.faiss`
51
+ - ์Šคํƒ€์ผ ๋ฐ์ดํ„ฐ question ์ธ๋ฑ์Šค
52
+ - `data/processed/megumin_question_answer.faiss`
53
+ - ์Šคํƒ€์ผ ๋ฐ์ดํ„ฐ question+answer ์ธ๋ฑ์Šค
54
+ - `data/processed/megumin_questions_meta.json`
55
+ - ์Šคํƒ€์ผ ๋ฐ์ดํ„ฐ ์ธ๋ฑ์Šค์™€ ์›๋ฌธ ๋ ˆ์ฝ”๋“œ ๋งคํ•‘
56
+ - `data/processed/namuwiki_questions.faiss`
57
+ - ๋‚˜๋ฌด์œ„ํ‚ค ๋ฐ์ดํ„ฐ question ์ธ๋ฑ์Šค
58
+ - `data/processed/namuwiki_question_answer.faiss`
59
+ - ๋‚˜๋ฌด์œ„ํ‚ค ๋ฐ์ดํ„ฐ question+answer ์ธ๋ฑ์Šค
60
+ - `data/processed/namuwiki_questions_meta.json`
61
+ - ๋‚˜๋ฌด์œ„ํ‚ค ๋ฐ์ดํ„ฐ ์ธ๋ฑ์Šค์™€ ์›๋ฌธ ๋ ˆ์ฝ”๋“œ ๋งคํ•‘
62
+
63
+ ## ๋ณ‘ํ•ฉ ์ €์žฅ ๊ทœ์น™
64
+
65
+ `crawl_namuwiki_to_qa.py`๋Š” ์ถœ๋ ฅ ํŒŒ์ผ์ด ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ๊ธฐ์กด `items`์™€ ์ƒˆ ๊ฒฐ๊ณผ๋ฅผ ๋ณ‘ํ•ฉํ•œ๋‹ค.
66
+
67
+ - ์šฐ์„  ์ค‘๋ณต ๊ธฐ์ค€: `chunk_id`
68
+ - ๋ณด์กฐ ๊ธฐ์ค€: `source.url + chunk_index + question`
69
+
70
+ ๋ณ‘ํ•ฉ ํ›„ ์‹๋ณ„์ž๋Š” ๋‹ค์Œ ๊ทœ์น™์œผ๋กœ ์ •๊ทœํ™”ํ•œ๋‹ค.
71
+
72
+ - `chunk_id`
73
+ - title๋ณ„ ์—ฐ์† ๋ฒˆํ˜ธ ์œ ์ง€
74
+ - ์˜ˆ: `๋ฉ”๊ตฌ๋ฐ_0000`, `์นด์ฆˆ๋งˆ_0185`
75
+ - `chunk_index`
76
+ - ์ „์ฒด ํŒŒ์ผ ๊ธฐ์ค€ ์—ฐ์† ๋ฒˆํ˜ธ
77
+ - ์˜ˆ: `0`, `135`, `320`
78
+
79
+ ## ๊ด€๋ จ ์Šคํฌ๋ฆฝํŠธ
80
+
81
+ - `scripts/crawl_namuwiki_to_qa.py`
82
+ - ๋‚˜๋ฌด์œ„ํ‚ค ๋ฌธ์„œ๋ฅผ QA JSON์œผ๋กœ ๋ณ€ํ™˜
83
+ - `scripts/build_faiss_index.py`
84
+ - ์Šคํƒ€์ผ/๋‚˜๋ฌด์œ„ํ‚ค ๋ฐ์ดํ„ฐ ๊ฐ๊ฐ์— ๋Œ€ํ•ด question ์ธ๋ฑ์Šค์™€ question+answer ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑ
85
+ - `scripts/expand_persona_from_namuwiki.py`
86
+ - ์‚ฌ์‹ค/์„ค์ • QA๋ฅผ ๋ฉ”๊ตฌ๋ฐ ์Šคํƒ€์ผ QA ์ดˆ์•ˆ์œผ๋กœ ํ™•์žฅ
87
+
88
+ ## ์šด์˜ ๋ฉ”๋ชจ
89
+
90
+ - ๋‚˜๋ฌด์œ„ํ‚ค ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ๋Š” ์‚ฌ์‹ค/์„ค์ • ๋ณด๊ฐ•์šฉ์ด๋‹ค.
91
+ - ๊ธฐ์กด `megumin_qa_dataset.json`์€ ๋ฉ”๊ตฌ๋ฐ ๋งํˆฌ์™€ ๊ฐ์ •์„  ์œ ์ง€์— ๋” ์ค‘์š”ํ•˜๋‹ค.
92
+ - ์ตœ์ข… Agent๋Š” ๋‘ ๋ฐ์ดํ„ฐ์›์„ ํ•จ๊ป˜ ๊ฒ€์ƒ‰ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.