1. āĻā§āĻŽāĻŋāĻāĻž

ā§§. āĻā§āϝāĻžāϞā§āĻā§āĻ
āĻĻā§āϰā§āϝā§āĻ āĻŽā§āĻāĻžāĻŦā§āϞāĻžāϰ āĻĒāϰāĻŋāϏā§āĻĨāĻŋāϤāĻŋāϤā§, āĻŦāĻŋāĻāĻŋāύā§āύ āϏā§āĻĨāĻžāύ⧠āĻŦāĻŋāĻāĻŋāύā§āύ āĻĻāĻā§āώāϤāĻž, āϏāĻŽā§āĻĒāĻĻ āĻāĻŦāĻ āĻāĻžāĻšāĻŋāĻĻāĻžāϰ āϏāĻžāĻĨā§ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋāĻĻā§āϰ āϏāĻŽāύā§āĻŦāϝāĻŧ āĻāϰāĻžāϰ āĻāύā§āϝ āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ āĻĄā§āĻāĻž āĻŦā§āϝāĻŦāϏā§āĻĨāĻžāĻĒāύāĻž āĻāĻŦāĻ āĻ āύā§āϏāύā§āϧāĻžāύ āĻā§āώāĻŽāϤāĻž āĻĒā§āϰāϝāĻŧā§āĻāύāĨ¤ āĻāĻ āĻāϰā§āĻŽāĻļāĻžāϞāĻž āĻāĻĒāύāĻžāĻā§ āĻāĻāĻāĻŋ āĻā§āĻĒāĻžāĻĻāύ āĻā§āϤā§āϰāĻŋāĻŽ āĻŦā§āĻĻā§āϧāĻŋāĻŽāϤā§āϤāĻž āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āϤā§āϰāĻŋ āĻāϰāϤ⧠āĻļā§āĻāĻžāϝāĻŧ āϝāĻž āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻŦāĻŋāώāϝāĻŧāĻā§āϞāĻŋāĻā§ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§:
- đī¸ āĻā§āϰāĻžāĻĢ āĻĄāĻžāĻāĻžāĻŦā§āϏ (āϏā§āĻĒā§āϝāĻžāύāĻžāϰ) : āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋ, āĻĻāĻā§āώāϤāĻž āĻāĻŦāĻ āϏāĻŽā§āĻĒāĻĻā§āϰ āĻŽāϧā§āϝ⧠āĻāĻāĻŋāϞ āϏāĻŽā§āĻĒāϰā§āĻ āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āύ
- đ āĻāĻāĻ-āĻāĻžāϞāĻŋāϤ āĻ āύā§āϏāύā§āϧāĻžāύ : āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ + āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ
- đ¸ āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒā§āϰāϏā§āϏāĻŋāĻ : āĻāĻŦāĻŋ, āĻā§āĻā§āϏāĻ āĻāĻŦāĻ āĻāĻŋāĻĄāĻŋāĻ āĻĨā§āĻā§ āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰā§āĻĄ āĻĄā§āĻāĻž āĻŦā§āϰ āĻāϰā§āύ
- đ¤ āĻŽāĻžāϞā§āĻāĻŋ-āĻāĻā§āύā§āĻ āĻ āϰā§āĻā§āϏā§āĻā§āϰā§āĻļāύ : āĻāĻāĻŋāϞ āĻāϰā§āĻŽāĻĒā§āϰāĻŦāĻžāĻšā§āϰ āĻāύā§āϝ āĻŦāĻŋāĻļā§āώāĻžāϝāĻŧāĻŋāϤ āĻāĻā§āύā§āĻāĻĻā§āϰ āϏāĻŽāύā§āĻŦāϝāĻŧ āĻāϰā§āύ
- đ§ āĻĻā§āϰā§āĻāĻŽā§āϝāĻŧāĻžāĻĻā§ āϏā§āĻŽā§āϤāĻŋ : āĻāĻžāϰā§āĻā§āĻā§āϏ āĻāĻāĻ āĻŽā§āĻŽā§āϰāĻŋ āĻŦā§āϝāĻžāĻāĻā§āϰ āϏāĻžāĻšāĻžāϝā§āϝ⧠āĻŦā§āϝāĻā§āϤāĻŋāĻāϤāĻāϰāĻŖ

⧍. āϤā§āĻŽāĻŋ āĻā§ āϤā§āϰāĻŋ āĻāϰāĻŦā§
āĻāĻāĻāĻŋ āϏāĻžāϰāĻāĻžāĻāĻāĻžāϰ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻ āĻā§āϰāĻžāĻĢ āĻĄāĻžāĻāĻžāĻŦā§āϏ āϝāĻžāϰ āϏāĻžāĻĨā§:
- đēī¸ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āϏāĻŽā§āĻĒāϰā§āĻā§āϰ 3D āĻāύā§āĻāĻžāϰā§āĻā§āĻāĻŋāĻ āĻā§āϰāĻžāĻĢ āĻāĻŋāĻā§āϝā§āϝāĻŧāĻžāϞāĻžāĻāĻā§āĻļāύ
- đ āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ āĻ āύā§āϏāύā§āϧāĻžāύ (āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ, āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻāĻŦāĻ āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ)
- đ¸ āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻāĻĒāϞā§āĻĄ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ (āĻāĻŦāĻŋ/āĻāĻŋāĻĄāĻŋāĻ āĻĨā§āĻā§ āϏāϤā§āϤāĻž āĻŦā§āϰ āĻāϰā§āύ)
- đ¤ āĻāĻāĻŋāϞ āĻāĻžāĻā§āϰ āĻāύā§āϝ āĻŽāĻžāϞā§āĻāĻŋ-āĻāĻā§āύā§āĻ āϏāĻŋāϏā§āĻā§āĻŽ
- đ§ āĻŦā§āϝāĻā§āϤāĻŋāĻāϤāĻā§āϤ āĻŽāĻŋāĻĨāϏā§āĻā§āϰāĻŋāϝāĻŧāĻžāϰ āĻāύā§āϝ āĻŽā§āĻŽā§āϰāĻŋ āĻŦā§āϝāĻžāĻāĻ āĻāύā§āĻāĻŋāĻā§āϰā§āĻļāύ
ā§Š. āĻŽā§āϞ āĻĒā§āϰāϝā§āĻā§āϤāĻŋ
āĻāĻĒāĻžāĻĻāĻžāύ | āĻĒā§āϰāϝā§āĻā§āϤāĻŋ | āĻāĻĻā§āĻĻā§āĻļā§āϝ |
āĻĄāĻžāĻāĻžāĻŦā§āϏ | āĻā§āϞāĻžāĻāĻĄ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ | āϏā§āĻā§āϰ āύā§āĻĄ (āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋ, āĻĻāĻā§āώāϤāĻž) āĻāĻŦāĻ āĻĒā§āϰāĻžāύā§āϤ (āϏāĻŽā§āĻĒāϰā§āĻ) |
āĻāĻāĻ āĻ āύā§āϏāύā§āϧāĻžāύ | āĻŽāĻŋāĻĨā§āύ + āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ | āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻŦā§āϧāĻāĻŽā§āϝāϤāĻž + āϏāĻžāĻĻā§āĻļā§āϝ āĻ āύā§āϏāύā§āϧāĻžāύ |
āĻāĻā§āύā§āĻ āĻĢā§āϰā§āĻŽāĻāϝāĻŧāĻžāϰā§āĻ | ADK (āĻāĻā§āύā§āĻ āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻ āĻāĻŋāĻ) | āĻāĻāĻ āĻāϰā§āĻŽāĻĒā§āϰāĻŦāĻžāĻšā§āϰ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āĻāϰā§āύ |
āϏā§āĻŽā§āϤāĻŋ | āĻāĻžāϰā§āĻā§āĻā§āϏ āĻāĻāĻ āĻŽā§āĻŽā§āϰāĻŋ āĻŦā§āϝāĻžāĻāĻ | āĻĻā§āϰā§āĻāĻŽā§āϝāĻŧāĻžāĻĻā§ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻĒāĻāύā§āĻĻā§āϰ āϏāĻā§āĻāϝāĻŧāϏā§āĻĨāĻžāύ |
āĻĢā§āϰāύā§āĻāĻāύā§āĻĄ | āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻž + āĻĨā§āϰāĻŋ.āĻā§āĻāϏ | āĻāύā§āĻāĻžāϰā§āĻā§āĻāĻŋāĻ 3D āĻā§āϰāĻžāĻĢ āĻāĻŋāĻā§āϝā§āϝāĻŧāĻžāϞāĻžāĻāĻā§āĻļāύ |
⧍. āĻĒāϰāĻŋāĻŦā§āĻļāĻāϤ āĻĒā§āϰāϏā§āϤā§āϤāĻŋ (āĻāϰā§āĻŽāĻļāĻžāϞāĻžāϝāĻŧ āĻĨāĻžāĻāϞ⧠āĻāĻĄāĻŧāĻŋāϝāĻŧā§ āϝāĻžāύ)
āĻĒā§āϰāĻĨāĻŽ āĻ āĻāĻļ: āĻŦāĻŋāϞāĻŋāĻ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻ āϏāĻā§āώāĻŽ āĻāϰā§āύ
- ā§Ģ āĻĄāϞāĻžāϰ āĻā§āϰā§āĻĄāĻŋāĻ āĻĻāĻŋā§ā§ āĻāĻĒāύāĻžāϰ āĻŦāĻŋāϞāĻŋāĻ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻ āĻĻāĻžāĻŦāĻŋ āĻāϰāĻžāϰ āĻāύā§āϝ, āĻāĻĒāύāĻžāϰ āĻāĻāĻŋ āϏā§āĻĨāĻžāĻĒāύā§āϰ āĻāύā§āϝ āĻĒā§āϰāϝāĻŧā§āĻāύ āĻšāĻŦā§āĨ¤ āĻāĻĒāύāĻžāϰ āĻāĻŋāĻŽā§āĻāϞ āĻ ā§āϝāĻžāĻāĻžāĻāύā§āĻāĻāĻŋ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰā§āύāĨ¤
āĻĻā§āĻŦāĻŋāϤā§āϝāĻŧ āĻ āĻāĻļ: āĻāύā§āĻŽā§āĻā§āϤ āĻĒāϰāĻŋāĻŦā§āĻļ
- đ āϏāϰāĻžāϏāϰāĻŋ āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āϝā§āϤ⧠āĻāĻ āϞāĻŋāĻā§āĻā§ āĻā§āϞāĻŋāĻ āĻāϰā§āύāĨ¤
- đ āĻāĻāĻ āϝāĻĻāĻŋ āϝā§āĻā§āύ⧠āϏāĻŽāϝāĻŧ āĻ
āύā§āĻŽā§āĻĻāύā§āϰ āĻ
āύā§āϰā§āϧ āĻāĻžāύāĻžāύ⧠āĻšāϝāĻŧ, āϤāĻžāĻšāϞ⧠āĻāĻžāϞāĻŋāϝāĻŧā§ āϝā§āϤ⧠āĻ
āύā§āĻŽā§āĻĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύāĨ¤

- đ āϝāĻĻāĻŋ āϏā§āĻā§āϰāĻŋāύā§āϰ āύā§āĻā§ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞāĻāĻŋ āύāĻž āĻĻā§āĻāĻž āϝāĻžā§, āϤāĻžāĻšāϞ⧠āĻāĻāĻŋ āĻā§āϞā§āύ:
- āĻāĻŋāĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύ
- āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻā§āϞāĻŋāĻ āĻāϰā§āύ

- đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāĻŽāĻžāύā§āĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āϝāĻžāĻāĻžāĻ āĻāϰā§āύ āϝ⧠āĻāĻĒāύāĻŋ āĻāϤāĻŋāĻŽāϧā§āϝā§āĻ āĻĒā§āϰāĻŽāĻžāĻŖā§āĻāϰāĻŖāĻĒā§āϰāĻžāĻĒā§āϤ āĻāĻŦāĻ āĻĒā§āϰāĻāϞā§āĻĒāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻāϞā§āĻĒ āĻāĻāĻĄāĻŋāϤ⧠āϏā§āĻ āĻāϰāĻž āĻāĻā§:
gcloud auth list - đđģ GitHub āĻĨā§āĻā§ āĻŦā§āĻāϏā§āĻā§āϰā§āϝāĻžāĻĒ āĻĒā§āϰāĻāϞā§āĻĒāĻāĻŋ āĻā§āϞā§āύ āĻāϰā§āύ:
git clone https://github.com/google-americas/way-back-home.git
3. āĻĒāϰāĻŋāĻŦā§āĻļ āϏā§āĻāĻāĻĒ
ā§§. āĻāϰāĻŽā§āĻ āĻāϰā§āύ
āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āϝāĻĻāĻŋ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞāĻāĻŋ āϏā§āĻā§āϰāĻŋāύā§āϰ āύā§āĻā§ āύāĻž āĻĻā§āĻāĻž āϝāĻžāϝāĻŧ, āϤāĻžāĻšāϞ⧠āĻāĻāĻŋ āĻā§āϞā§āύ:
- āĻāĻŋāĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύ
- āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻā§āϞāĻŋāĻ āĻāϰā§āύ

đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, init āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋ āĻāĻā§āϏāĻŋāĻāĻŋāĻāĻā§āĻŦāϞ āĻāϰā§āύ āĻāĻŦāĻ āĻāĻāĻŋ āĻāĻžāϞāĻžāύ:
cd ~/way-back-home/level_2
./init.sh
2. āĻĒā§āϰāĻāϞā§āĻĒ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰā§āύ
đđģ āĻāĻĒāύāĻžāϰ āĻĒā§āϰā§āĻā§āĻā§āĻ āĻāĻāĻĄāĻŋ āϏā§āĻ āĻāϰā§āύ:
gcloud config set project $(cat ~/project_id.txt) --quiet
đđģ āĻĒā§āϰā§ā§āĻāύā§ā§ API āĻā§āϞāĻŋ āϏāĻā§āώāĻŽ āĻāϰā§āύ (āĻāϤ⧠~⧍-ā§Š āĻŽāĻŋāύāĻŋāĻ āϏāĻŽāϝāĻŧ āϞāĻžāĻā§):
gcloud services enable compute.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
spanner.googleapis.com \
storage.googleapis.com
ā§Š. āϏā§āĻāĻāĻĒ āϏā§āĻā§āϰāĻŋāĻĒā§āĻ āĻāĻžāϞāĻžāύ
đđģ āϏā§āĻāĻāĻĒ āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋ āĻāĻžāϰā§āϝāĻāϰ āĻāϰā§āύ:
cd ~/way-back-home/level_2
./setup.sh
āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻāύā§āϝ .env āϤā§āϰāĻŋ āĻāϰāĻŦā§āĨ¤ āĻāĻĒāύāĻžāϰ āĻā§āϞāĻžāĻāĻĄāĻļā§āϞā§, way_back_home āĻĒā§āϰāĻā§āĻā§āĻ āĻā§āϞā§āύāĨ¤ level_2 āĻĢā§āϞā§āĻĄāĻžāϰā§āϰ āĻ
āϧā§āύā§, āĻāĻĒāύāĻŋ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ āϝ⧠.env āĻĢāĻžāĻāϞāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻāύā§āϝ āϤā§āϰāĻŋ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤ āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āĻāĻāĻŋ āĻā§āĻāĻā§ āύāĻž āĻĒāĻžāύ, āϤāĻžāĻšāϞ⧠āĻāĻĒāύāĻŋ āĻāĻāĻŋ āĻĻā§āĻāϤ⧠View -> Toggle Hidden File āĻā§āϞāĻŋāĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤ 
ā§Ē. āύāĻŽā§āύāĻž āĻĄā§āĻāĻž āϞā§āĻĄ āĻāϰā§āύ
đđģ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄā§ āύā§āĻāĻŋāĻā§āĻ āĻāϰā§āύ āĻāĻŦāĻ āύāĻŋāϰā§āĻāϰāϤāĻž āĻāύāϏā§āĻāϞ āĻāϰā§āύ:
cd ~/way-back-home/level_2/backend
uv sync
đđģ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āϤāĻĨā§āϝ āϞā§āĻĄ āĻāϰā§āύ:
uv run python ~/way-back-home/level_2/backend/setup_data.py
āĻāĻāĻŋ āϤā§āϰāĻŋ āĻāϰā§:
- āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻāύāϏā§āĻā§āϝāĻžāύā§āϏ (
survivor-network) - āĻĄāĻžāĻāĻžāĻŦā§āϏ (
graph-db) - āϏāĻāϞ āύā§āĻĄ āĻāĻŦāĻ āĻāĻ āĻā§āĻŦāĻŋāϞ
- āĻā§āϝāĻŧā§āϰāĻŋ āĻāϰāĻžāϰ āĻāύā§āϝ āϏāĻŽā§āĻĒāϤā§āϤāĻŋ āĻā§āϰāĻžāĻĢ āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āĻāĻāĻāĻĒā§āĻ :
============================================================
SUCCESS! Database setup complete.
============================================================
Instance: survivor-network
Database: graph-db
Graph: SurvivorGraph
Access your database at:
https://console.cloud.google.com/spanner/instances/survivor-network/databases/graph-db?project=waybackhome
āĻāĻāĻāĻĒā§āĻā§ Access your database at āĻĒāϰ⧠āϞāĻŋāĻā§āĻā§ āĻā§āϞāĻŋāĻ āĻāϰāϞā§, āĻāĻĒāύāĻŋ Google Cloud Console Spanner āĻā§āϞāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤

āĻāϰ āϤā§āĻŽāĻŋ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āĻāύāϏā§āϞ⧠āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§!

ā§Ē. āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻāϤ⧠āĻā§āϰāĻžāĻĢ āĻĄā§āĻāĻž āĻāĻŋāĻā§āϝā§āϝāĻŧāĻžāϞāĻžāĻāĻ āĻāϰāĻž
āĻāĻ āύāĻŋāϰā§āĻĻā§āĻļāĻŋāĻāĻžāĻāĻŋ āĻāĻĒāύāĻžāĻā§ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āĻāύāϏā§āϞ⧠āϏāϰāĻžāϏāϰāĻŋ āϏāĻžāϰāĻāĻžāĻāĻāĻžāϰ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻ āĻā§āϰāĻžāĻĢ āĻĄā§āĻāĻž āĻāϞā§āĻĒāύāĻž āĻāϰāϤ⧠āĻāĻŦāĻ āϤāĻžāϰ āϏāĻžāĻĨā§ āĻāύā§āĻāĻžāϰāĻ ā§āϝāĻžāĻā§āĻ āĻāϰāϤ⧠āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰā§āĨ¤ āĻāĻĒāύāĻžāϰ āĻāĻāĻ āĻāĻā§āύā§āĻ āϤā§āϰāĻŋ āĻāϰāĻžāϰ āĻāĻā§ āĻāĻĒāύāĻžāϰ āĻĄā§āĻāĻž āϝāĻžāĻāĻžāĻ āĻāϰāĻžāϰ āĻāĻŦāĻ āĻā§āϰāĻžāĻĢ āĻāĻžāĻ āĻžāĻŽā§ āĻŦā§āĻāĻžāϰ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻĻā§āϰā§āĻĻāĻžāύā§āϤ āĻāĻĒāĻžāϝāĻŧāĨ¤
ā§§. āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻ āĻ ā§āϝāĻžāĻā§āϏā§āϏ āĻāϰā§āύ
- āĻļā§āώ āϧāĻžāĻĒā§, āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰā§āύ āϝ⧠āĻāĻĒāύāĻŋ āϞāĻŋāĻā§āĻāĻāĻŋāϤ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āĻā§āύ āĻāĻŦāĻ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻāĻāĻŋ āĻā§āϞāĻā§āύāĨ¤

2. āĻā§āϰāĻžāĻĢ āĻāĻžāĻ āĻžāĻŽā§ āĻŦā§āĻāĻž ("āĻŦāĻĄāĻŧ āĻāĻŦāĻŋ")
āϏāĻžāϰāĻāĻžāĻāĻāĻžāϰ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻ āĻĄā§āĻāĻžāϏā§āĻāĻā§ āĻāĻāĻāĻŋ āϞāĻāĻŋāĻ āĻĒāĻžāĻāϞ āĻŦāĻž āĻāĻāĻāĻŋ āĻā§āĻŽ āϏā§āĻā§āĻ āĻšāĻŋāϏā§āĻŦā§ āĻāĻžāĻŦā§āύ:
āϏāϤā§āϤāĻž | āϏāĻŋāϏā§āĻā§āĻŽā§ āĻā§āĻŽāĻŋāĻāĻž | āĻāĻĒāĻŽāĻž |
āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋāϰāĻž | āĻāĻā§āύā§āĻ/āĻā§āϞā§āϝāĻŧāĻžāĻĄāĻŧāϰāĻž | āĻā§āϞā§āϝāĻŧāĻžāĻĄāĻŧāϰāĻž |
āĻŦāĻžāϝāĻŧā§āĻŽ | āϤāĻžāϰāĻž āĻā§āĻĨāĻžāϝāĻŧ āĻ āĻŦāϏā§āĻĨāĻŋāϤ | āĻŽāĻžāύāĻāĻŋāϤā§āϰ āĻ āĻā§āĻāϞ |
āĻĻāĻā§āώāϤāĻž | āϤāĻžāϰāĻž āĻāĻŋ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠| āĻā§āώāĻŽāϤāĻž |
āĻāĻžāĻšāĻŋāĻĻāĻž | āϤāĻžāĻĻā§āϰ āĻā§ āĻ āĻāĻžāĻŦ (āϏāĻā§āĻāĻ) | āĻā§āϝāĻŧā§āϏā§āĻ/āĻŽāĻŋāĻļāύ |
āϰāĻŋāϏā§āϰā§āϏ | āĻĒā§āĻĨāĻŋāĻŦā§āϤ⧠āĻĒāĻžāĻāϝāĻŧāĻž āĻāĻŋāύāĻŋāϏāĻĒāϤā§āϰ | āϞā§āĻ |
āϞāĻā§āώā§āϝ : āĻāĻāĻ āĻāĻā§āύā§āĻā§āϰ āĻāĻžāĻ āĻšāϞ āĻĻāĻā§āώāϤāĻž (āϏāĻŽāĻžāϧāĻžāύ) āĻā§ āĻāĻžāĻšāĻŋāĻĻāĻž (āϏāĻŽāϏā§āϝāĻž) āĻāϰ āϏāĻžāĻĨā§ āϏāĻāϝā§āĻā§āϤ āĻāϰāĻž, āĻā§āĻŦāĻŋāĻ (āĻ āĻŦāϏā§āĻĨāĻžāύā§āϰ āϏā§āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž) āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰā§āĨ¤
đ āĻĒā§āϰāĻžāύā§āϤ (āϏāĻŽā§āĻĒāϰā§āĻ):
-
SurvivorInBiome: āĻ āĻŦāϏā§āĻĨāĻžāύ āĻā§āϰā§āϝāĻžāĻāĻŋāĻ -
SurvivorHasSkill: āĻĻāĻā§āώāϤāĻžāϰ āϤāĻžāϞāĻŋāĻāĻž -
SurvivorHasNeed: āϏāĻā§āϰāĻŋāϝāĻŧ āϏāĻŽāϏā§āϝāĻžāϰ āϤāĻžāϞāĻŋāĻāĻž -
SurvivorFoundResource: āĻāĻāĻā§āĻŽā§āϰ āϤāĻžāϞāĻŋāĻāĻž -
SurvivorCanHelp: āĻ āύā§āĻŽāĻžāύāĻā§āϤ āϏāĻŽā§āĻĒāϰā§āĻ (āĻāĻāĻ āĻāĻāĻŋ āĻāĻŖāύāĻž āĻāϰā§!)
ā§Š. āĻā§āϰāĻžāĻĢāĻāĻŋ āĻ āύā§āϏāύā§āϧāĻžāύ āĻāϰāĻž
āĻĄā§āĻāĻžāϤ⧠"āĻāϞā§āĻĒ" āĻĻā§āĻāĻžāϰ āĻāύā§āϝ āĻāϝāĻŧā§āĻāĻāĻŋ āĻā§āϝāĻŧā§āϰāĻŋ āϰāĻžāύ āĻāϰāĻž āϝāĻžāĻāĨ¤
āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ GQL (āĻā§āϰāĻžāĻĢ āĻā§āϝāĻŧā§āϰāĻŋ āϞā§āϝāĻžāĻā§āĻā§āϝāĻŧā§āĻ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤ āĻāĻāĻāĻŋ āĻā§āϝāĻŧā§āϰāĻŋ āĻāĻžāϞāĻžāύā§āϰ āĻāύā§āϝ, GRAPH SurvivorNetwork āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ āĻāĻŦāĻ āϤāĻžāϰāĻĒāϰ⧠āĻāĻĒāύāĻžāϰ āĻŽā§āϝāĻžāĻ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύāĨ¤
đ āĻĒā§āϰāĻļā§āύ ā§§: āĻā§āϞā§āĻŦāĻžāϞ āϰā§āϏā§āĻāĻžāϰ (āĻā§ āĻā§āĻĨāĻžāϝāĻŧ?) āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻāĻŋāϤā§āϤāĻŋ - āĻāĻĻā§āϧāĻžāϰ āĻ āĻāĻŋāϝāĻžāύā§āϰ āĻāύā§āϝ āĻ āĻŦāϏā§āĻĨāĻžāύ āĻŦā§āĻāĻž āĻ āϤā§āϝāύā§āϤ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖāĨ¤
GRAPH SurvivorNetwork
MATCH result = (s:Survivors)-[:SurvivorInBiome]->(b:Biomes)
RETURN TO_JSON(result) AS json_result
āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻāĻļāĻž āĻāϰāĻŋ: 
đ āĻĒā§āϰāĻļā§āύ ⧍: āĻĻāĻā§āώāϤāĻž āĻŽā§āϝāĻžāĻā§āϰāĻŋāĻā§āϏ (āĻā§āώāĻŽāϤāĻž) āĻāĻāύ āĻāĻĒāύāĻŋ āĻāĻžāύā§āύ āϝ⧠āϏāĻŦāĻžāĻ āĻā§āĻĨāĻžāϝāĻŧ , āϤāĻžāϰāĻž āĻā§ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠āϤāĻž āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰā§āύāĨ¤
GRAPH SurvivorNetwork
MATCH result = (s:Survivors)-[h:SurvivorHasSkill]->(k:Skills)
RETURN TO_JSON(result) AS json_result
āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻāĻļāĻž āĻāϰāĻŋ: 
đ āĻĒā§āϰāĻļā§āύ ā§Š: āĻāĻžāϰāĻž āϏāĻāĻāĻā§ āĻāĻā§āύ? ("āĻŽāĻŋāĻļāύ āĻŦā§āϰā§āĻĄ") āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋāĻĻā§āϰ āĻĻā§āĻā§āύ āϝāĻžāĻĻā§āϰ āϏāĻžāĻšāĻžāϝā§āϝā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āĻāĻŦāĻ āϤāĻžāĻĻā§āϰ āĻā§ āĻĒā§āϰāϝāĻŧā§āĻāύāĨ¤
GRAPH SurvivorNetwork
MATCH result = (s:Survivors)-[h:SurvivorHasNeed]->(n:Needs)
RETURN TO_JSON(result) AS json_result
āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻāĻļāĻž āĻāϰāĻŋ: 
đ āĻāύā§āύāϤ: āĻŽā§āϝāĻžāĻāĻŽā§āĻāĻŋāĻ - āĻā§ āĻāĻžāĻā§ āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰāϤ⧠āĻĒāĻžāϰā§?
āĻāĻāĻžāύā§āĻ āĻā§āϰāĻžāĻĢāĻāĻŋ āĻļāĻā§āϤāĻŋāĻļāĻžāϞ⧠āĻšāϝāĻŧā§ āĻāĻ ā§! āĻāĻ āĻ āύā§āϏāύā§āϧāĻžāύ⧠āĻāĻŽāύ āĻā§āĻŦāĻŋāϤāĻĻā§āϰ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§ āϝāĻžāĻĻā§āϰ āĻĻāĻā§āώāϤāĻž āϰāϝāĻŧā§āĻā§ āϝāĻž āĻ āύā§āϝāĻžāύā§āϝ āĻā§āĻŦāĻŋāϤāĻĻā§āϰ āĻāĻžāĻšāĻŋāĻĻāĻž āĻŽā§āĻāĻžāϤ⧠āĻĒāĻžāϰ⧠āĨ¤
GRAPH SurvivorNetwork
MATCH result = (helper:Survivors)-[:SurvivorHasSkill]->(skill:Skills)-[:SkillTreatsNeed]->(need:Needs)<-[:SurvivorHasNeed]-(helpee:Survivors)
RETURN TO_JSON(result) AS json_result
āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻāĻļāĻž āĻāϰāĻŋ: 
āĻāϤāĻŋāĻŦāĻžāĻāĻ āĻĻāĻŋāĻ āĻšāϞ⧠, āĻāĻ āĻā§āϝāĻŧā§āϰāĻŋāĻāĻŋ āĻā§ āĻāϰā§:
"āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻžāϝāĻŧ āĻĒā§āĻĄāĻŧāĻžāϰ āĻāĻŋāĻāĻŋā§āϏāĻž āĻāϰāĻž āĻšāϝāĻŧ" āĻĻā§āĻāĻžāύā§āϰ āĻĒāϰāĻŋāĻŦāϰā§āϤ⧠(āϝāĻž āϏā§āĻāĻŋāĻŽāĻž āĻĨā§āĻā§ āϏā§āĻĒāώā§āĻ), āĻāĻ āĻā§āϝāĻŧā§āϰāĻŋāĻāĻŋ āĻā§āĻāĻā§ āĻĒāĻžāϝāĻŧ:
- āĻĄāĻžāĻ āĻāϞā§āύāĻž āĻĢā§āϰāϏā§āĻ (āϝāĻžāϰ āĻāĻŋāĻāĻŋā§āϏāĻž āĻĒā§āϰāĻļāĻŋāĻā§āώāĻŖ āĻāĻā§) â āĻāĻŋāĻāĻŋā§āϏāĻž āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ â āĻā§āϝāĻžāĻĒā§āĻā§āύ āϤāĻžāύāĻžāĻāĻž (āϝāĻžāϰ āĻĒā§āĻĄāĻŧāĻž)
- āĻĄā§āĻāĻŋāĻĄ āĻā§āύ (āϝāĻžāϰ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž āĻāĻā§) â āĻāĻŋāĻāĻŋā§āϏāĻž āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ â āϞā§āĻĢāĻā§āύā§āϝāĻžāύā§āĻ āĻĒāĻžāϰā§āĻ (āϝāĻžāϰ āĻā§āĻĄāĻŧāĻžāϞāĻŋ āĻŽāĻāĻā§ āĻā§āĻā§)
āĻā§āύ āĻāĻāĻŋ āĻļāĻā§āϤāĻŋāĻļāĻžāϞā§:
āĻāĻĒāύāĻžāϰ āĻāĻāĻ āĻāĻā§āύā§āĻ āĻā§ āĻāϰāĻŦā§:
āϝāĻāύ āĻāĻāĻāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰ⧠āĻāĻŋāĻā§āĻāĻžāϏāĻž āĻāϰā§āύ "āĻĒā§āĻĄāĻŧāĻžāϰ āĻāĻŋāĻāĻŋā§āϏāĻž āĻā§ āĻāϰāϤ⧠āĻĒāĻžāϰā§?" , āϤāĻāύ āĻāĻā§āύā§āĻ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤāĻā§āϞāĻŋ āĻāϰāĻŦā§āύ:
- āĻāĻāĻ āϧāϰāĻŖā§āϰ āĻā§āϰāĻžāĻĢ āĻā§āϝāĻŧā§āϰāĻŋ āĻāĻžāϞāĻžāύ
- āĻĒā§āϰāϤā§āϝāĻžāĻŦāϰā§āϤāύ: "āĻĄāĻ āĻĢā§āϰāϏā§āĻā§āϰ āĻāĻŋāĻāĻŋā§āϏāĻž āĻĒā§āϰāĻļāĻŋāĻā§āώāĻŖ āĻāĻā§ āĻāĻŦāĻ āϤāĻŋāύāĻŋ āĻā§āϝāĻžāĻĒā§āĻā§āύ āϤāĻžāύāĻžāĻāĻžāĻā§ āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ"
- āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻŽāϧā§āϝāĻŦāϰā§āϤ⧠āĻā§āĻŦāĻŋāϞ āĻŦāĻž āϏāĻŽā§āĻĒāϰā§āĻ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāĻžāύāĻžāϰ āĻĻāϰāĻāĻžāϰ āύā§āĻ!
ā§Ģ. āϏā§āĻĒā§āϝāĻžāύāĻžāϰ⧠āĻāĻāĻ-āĻāĻžāϞāĻŋāϤ āĻāĻŽāĻŦā§āĻĄāĻŋāĻ
ā§§. āĻā§āύ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ? (āĻā§āύāĻ āĻĒāĻĻāĻā§āώā§āĻĒ āύā§āĻ, āĻā§āĻŦāϞ āĻĒāĻ āύāϝā§āĻā§āϝ)
āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻžāϰ āĻā§āώā§āϤā§āϰā§, āϏāĻŽāϝāĻŧ āĻ
āϤā§āϝāύā§āϤ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖ āĨ¤ āϝāĻāύ āĻāĻāĻāύ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋ āĻāϰā§āϰāĻŋ āĻ
āĻŦāϏā§āĻĨāĻžāϰ āĻāĻĨāĻž āĻāĻžāύāĻžāϝāĻŧ, āϝā§āĻŽāύ I need someone who can treat burns āĻ
āĻĨāĻŦāĻž Looking for a medic , āϤāĻāύ āϤāĻžāϰāĻž āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āϏāĻ āĻŋāĻ āĻĻāĻā§āώāϤāĻžāϰ āύāĻžāĻŽ āĻ
āύā§āĻŽāĻžāύ āĻāϰ⧠āϏāĻŽāϝāĻŧ āύāώā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠āύāĻžāĨ¤
āĻāϏāϞ āĻĻā§āĻļā§āϝ : āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋ: Captain Tanaka has burnsâwe need medical help NOW!
"medic" āĻāϰ āĻāύā§āϝ āĻāϤāĻŋāĻšā§āϝāĻŦāĻžāĻšā§ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ â 0 āĻĢāϞāĻžāĻĢāϞ â
āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϏāĻš āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ â "āĻāĻŋāĻāĻŋā§āϏāĻž āĻĒā§āϰāĻļāĻŋāĻā§āώāĻŖ", "āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž" āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰ⧠â
āĻāĻā§āύā§āĻāĻĻā§āϰ āĻ āĻŋāĻ āĻāĻāĻžāĻ āĻĒā§āϰā§ā§āĻāύ: āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ, āĻŽāĻžāύā§āώā§āϰ āĻŽāϤ⧠āĻ āύā§āϏāύā§āϧāĻžāύ āϝāĻž āĻā§āĻŦāϞ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āύāϝāĻŧ, āĻāĻĻā§āĻĻā§āĻļā§āϝ āĻŦā§āĻā§āĨ¤
2. āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āĻŽāĻĄā§āϞ āϤā§āϰāĻŋ āĻāϰā§āύ

āĻāĻāύ āĻāϏā§āύ āĻāĻŽāύ āĻāĻāĻāĻŋ āĻŽāĻĄā§āϞ āϤā§āϰāĻŋ āĻāϰāĻŋ āϝāĻž āĻā§āĻāϞā§āϰ text-embedding-004 āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻā§āĻā§āϏāĻāĻā§ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻāϝāĻŧā§ āϰā§āĻĒāĻžāύā§āϤāϰ āĻāϰā§āĨ¤
đ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻāϤā§, āĻāĻ SQL āĻāĻžāϞāĻžāύ ( $YOUR_PROJECT_ID āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻā§āϤ āĻĒā§āϰāĻā§āĻā§āĻ āĻāĻāĻĄāĻŋ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ):
âŧī¸ āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠, āĻĒā§āϰ⧠āĻĒā§āϰāĻāϞā§āĻĒāĻāĻŋ āĻĻā§āĻāϤ⧠File -> Open Folder -> way-back-home/level_2 āĻā§āϞā§āύāĨ¤

đ āύāĻŋāĻā§āϰ āĻā§āϝāĻŧā§āϰāĻŋāĻāĻŋ āĻāĻĒāĻŋ āĻāϰ⧠āĻĒā§āϏā§āĻ āĻāϰ⧠āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻāϤ⧠āĻāĻ āĻā§āϝāĻŧā§āϰāĻŋāĻāĻŋ āĻāĻžāϞāĻžāύ, āĻāĻŦāĻ āϤāĻžāϰāĻĒāϰ āϰāĻžāύ āĻŦā§āϤāĻžāĻŽā§ āĻā§āϞāĻŋāĻ āĻāϰā§āύ:
CREATE MODEL TextEmbeddings
INPUT(content STRING(MAX))
OUTPUT(embeddings STRUCT<values ARRAY<FLOAT32>>)
REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/$YOUR_PROJECT_ID/locations/us-central1/publishers/google/models/text-embedding-004'
);
āĻāϰ āĻāĻžāĻ āĻā§ :
- āϏā§āĻĒā§āϝāĻžāύāĻžāϰ⧠āĻāĻāĻāĻŋ āĻāĻžāϰā§āĻā§āϝāĻŧāĻžāϞ āĻŽāĻĄā§āϞ āϤā§āϰāĻŋ āĻāϰ⧠(āϏā§āĻĨāĻžāύā§āϝāĻŧāĻāĻžāĻŦā§ āĻā§āύāĻ āĻŽāĻĄā§āϞ āĻāĻāύ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻž āĻšāϝāĻŧ āύāĻž)
- Vertex AI-āϤ⧠Google-āĻāϰ
text-embedding-004āĻĻāĻŋāĻā§ āĻāĻā§āĻāĻŋāϤ āĻāϰāĻž āĻšāĻā§āĻā§ - āĻā§āĻā§āϤāĻŋ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰā§: āĻāύāĻĒā§āĻ āĻšāϞ āĻā§āĻā§āϏāĻ, āĻāĻāĻāĻĒā§āĻ āĻšāϞ āĻāĻāĻāĻŋ 768-āĻŽāĻžāϤā§āϰāĻž āĻĢā§āϞā§āĻ āĻ ā§āϝāĻžāϰā§
"āϰāĻŋāĻŽā§āĻ āĻ āĻĒāĻļāύ" āĻā§āύ?
- āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āύāĻŋāĻā§āĻ āĻŽāĻĄā§āϞāĻāĻŋ āĻāĻžāϞāĻžāϝāĻŧ āύāĻžāĨ¤
-
ML.PREDICTāĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāĻāĻŋ API āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ Vertex AI āĻāϞ āĻāϰā§āĨ¤ - āĻāĻŋāϰā§-āĻāĻāĻŋāĻāϞ : āĻĒāĻžāĻāĻĨāύ⧠āĻĄā§āĻāĻž āϰāĻĒā§āϤāĻžāύāĻŋ, āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāϰāĻŖ āĻāĻŦāĻ āĻĒā§āύāϰāĻžāϝāĻŧ āĻāĻŽāĻĻāĻžāύāĻŋ āĻāϰāĻžāϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻāĨ¤
Run āĻŦāĻžāĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ, āĻāĻāĻŦāĻžāϰ āĻāĻāĻŋ āϏāĻĢāϞ āĻšāϝāĻŧā§ āĻā§āϞā§, āĻāĻĒāύāĻŋ āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ:

ā§Š. āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āĻāϞāĻžāĻŽ āϝā§āĻ āĻāϰā§āύ
đ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāϤ⧠āĻāĻāĻāĻŋ āĻāϞāĻžāĻŽ āϝā§āĻ āĻāϰā§āύ:
ALTER TABLE Skills ADD COLUMN skill_embedding ARRAY<FLOAT32>;
Run āĻŦāĻžāĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ, āĻāĻāĻŦāĻžāϰ āĻāĻāĻŋ āϏāĻĢāϞ āĻšāϝāĻŧā§ āĻā§āϞā§, āĻāĻĒāύāĻŋ āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ:

ā§Ē. āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰā§āύ
đ āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻĻāĻā§āώāϤāĻžāϰ āĻāύā§āϝ āĻā§āĻā§āĻāϰ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰāϤ⧠AI āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ:
UPDATE Skills
SET skill_embedding = (
SELECT embeddings.values
FROM ML.PREDICT(
MODEL TextEmbeddings,
(SELECT name AS content)
)
)
WHERE skill_embedding IS NULL;
Run āĻŦāĻžāĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ, āĻāĻāĻŦāĻžāϰ āĻāĻāĻŋ āϏāĻĢāϞ āĻšāϝāĻŧā§ āĻā§āϞā§, āĻāĻĒāύāĻŋ āύā§āĻā§āϰ āĻŽāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ:

āĻā§ āĻāĻā§ : āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻĻāĻā§āώāϤāĻžāϰ āύāĻžāĻŽ (āϝā§āĻŽāύ, "āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž") āĻāĻāĻāĻŋ 768-āĻŽāĻžāϤā§āϰāĻžāϰ āĻā§āĻā§āĻāϰ⧠āϰā§āĻĒāĻžāύā§āϤāϰāĻŋāϤ āĻšāϝāĻŧ āϝāĻž āĻāϰ āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āϰā§āĻĨ āĻāĻĒāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āĨ¤
ā§Ģ. āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϝāĻžāĻāĻžāĻ āĻāϰā§āύ
đ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§ āĻāĻŋāύāĻž āϤāĻž āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ:
SELECT
skill_id,
name,
ARRAY_LENGTH(skill_embedding) AS embedding_dimensions
FROM Skills
LIMIT 5;
āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āĻāĻāĻāĻĒā§āĻ :

ā§Ŧ. āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ
āĻāĻāύ āĻāĻŽāϰāĻž āĻāĻŽāĻžāĻĻā§āϰ āĻĒāϰāĻŋāϏā§āĻĨāĻŋāϤāĻŋ āĻĨā§āĻā§ āϏāĻ āĻŋāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āĻā§āώā§āϤā§āϰ⧠āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻŦ : "āĻāĻŋāĻāĻŋā§āϏāĻ" āĻļāĻŦā§āĻĻāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻŋāĻāĻŋā§āϏāĻž āĻĻāĻā§āώāϤāĻž āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰāĻžāĨ¤
đ "āĻāĻŋāĻāĻŋā§āϏāĻ" āĻāϰ āĻŽāϤ⧠āĻĻāĻā§āώāϤāĻž āĻā§āĻāĻā§āύ:
WITH query_embedding AS (
SELECT embeddings.values AS val
FROM ML.PREDICT(MODEL TextEmbeddings, (SELECT "medic" AS content))
)
SELECT
s.name AS skill_name,
s.category,
COSINE_DISTANCE(s.skill_embedding, (SELECT val FROM query_embedding)) AS distance
FROM Skills AS s
WHERE s.skill_embedding IS NOT NULL
ORDER BY distance ASC
LIMIT 10;
- āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻ āύā§āϏāύā§āϧāĻžāύ āĻļāĻŦā§āĻĻ "medic" āĻā§ āĻāĻāĻāĻŋ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻāϝāĻŧā§ āϰā§āĻĒāĻžāύā§āϤāϰāĻŋāϤ āĻāϰā§
- āĻāĻāĻŋāĻā§
query_embeddingāĻ āϏā§āĻĨāĻžāϝāĻŧā§ āĻā§āĻŦāĻŋāϞ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤
āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āĻĢāϞāĻžāĻĢāϞ (āĻāĻŽ āĻĻā§āϰāϤā§āĻŦ = āĻāϰāĻ āĻ āύā§āϰā§āĻĒ):

ā§. āĻŦāĻŋāĻļā§āϞā§āώāĻŖā§āϰ āĻāύā§āϝ āĻŽāĻŋāĻĨā§āύ āĻŽāĻĄā§āϞ āϤā§āϰāĻŋ āĻāϰā§āύ

đ āĻāĻāĻāĻŋ āĻā§āύāĻžāϰā§āĻāĻŋāĻ āĻāĻāĻ āĻŽāĻĄā§āϞ āϰā§āĻĢāĻžāϰā§āύā§āϏ āϤā§āϰāĻŋ āĻāϰā§āύ ( $YOUR_PROJECT_ID āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻā§āϤ āĻĒā§āϰāĻā§āĻā§āĻ āĻāĻāĻĄāĻŋ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ):
CREATE MODEL GeminiPro
INPUT(prompt STRING(MAX))
OUTPUT(content STRING(MAX))
REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/$YOUR_PROJECT_ID/locations/us-central1/publishers/google/models/gemini-2.5-pro',
default_batch_size = 1
);
āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āĻŽāĻĄā§āϞ āĻĨā§āĻā§ āĻĒāĻžāϰā§āĻĨāĻā§āϝ :
- āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ : āĻā§āĻā§āϏāĻ â āĻā§āĻā§āĻāϰ (āϏāĻžāĻĻā§āĻļā§āϝ āĻ āύā§āϏāύā§āϧāĻžāύā§āϰ āĻāύā§āϝ)
- āĻŽāĻŋāĻĨā§āύ : āĻā§āĻā§āϏāĻ â āĻā§āύāĻžāϰā§āĻā§āĻĄ āĻā§āĻā§āϏāĻ (āϝā§āĻā§āϤāĻŋ/āĻŦāĻŋāĻļā§āϞā§āώāĻŖā§āϰ āĻāύā§āϝ)

ā§Ž. āϏāĻžāĻŽāĻā§āĻāϏā§āϝ āĻŦāĻŋāĻļā§āϞā§āώāĻŖā§āϰ āĻāύā§āϝ āĻā§āĻŽāĻŋāύāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ
đ āĻŽāĻŋāĻļāύā§āϰ āϏāĻžāĻŽāĻā§āĻāϏā§āϝā§āϰ āĻāύā§āϝ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻā§āĻĄāĻŧāĻž āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰā§āύ:
WITH PairData AS (
SELECT
s1.name AS Name_A,
s2.name AS Name_B,
CONCAT(
"Assess compatibility of these two survivors for a resource-gathering mission. ",
"Survivor 1: ", s1.name, ". ",
"Survivor 2: ", s2.name, ". ",
"Give a score from 1-10 and a 1-sentence reason."
) AS prompt
FROM Survivors s1
JOIN Survivors s2 ON s1.survivor_id < s2.survivor_id
LIMIT 1
)
SELECT
Name_A,
Name_B,
content AS ai_assessment
FROM ML.PREDICT(
MODEL GeminiPro,
(SELECT Name_A, Name_B, prompt FROM PairData)
);
āĻĒā§āϰāϤā§āϝāĻžāĻļāĻŋāϤ āĻāĻāĻāĻĒā§āĻ :
Name_A | Name_B | ai_assessment
----------------|-------------------|----------------
"David Chen" | "Dr. Elena Frost" | "**Score: 9/10** Their compatibility is extremely high as David's practical, hands-on scavenging skills are perfectly complemented by Dr. Frost's specialized knowledge to identify critical medical supplies and avoid biological hazards."
ā§Ŧ. āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻĒāύāĻžāϰ āĻā§āϰāĻžāĻĢ RAG āĻāĻā§āύā§āĻ āϤā§āϰāĻŋ āĻāϰāĻž
ā§§. āϏāĻŋāϏā§āĻā§āĻŽ āĻāϰā§āĻāĻŋāĻā§āĻāĻāĻžāϰ āĻāĻāĻžāϰāĻāĻŋāĻ
āĻāĻ āĻŦāĻŋāĻāĻžāĻāĻāĻŋ āĻāĻāĻāĻŋ āĻŦāĻšā§-āĻĒāĻĻā§āϧāϤāĻŋāĻāϤ āĻ āύā§āϏāύā§āϧāĻžāύ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āϤā§āϰāĻŋ āĻāϰ⧠āϝāĻž āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻāĻā§ āĻŦāĻŋāĻāĻŋāύā§āύ āϧāϰāĻŖā§āϰ āĻĒā§āϰāĻļā§āύ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰāĻžāϰ āύāĻŽāύā§āϝāĻŧāϤāĻž āĻĻā§āϝāĻŧāĨ¤ āϏāĻŋāϏā§āĻā§āĻŽāĻāĻŋāϤ⧠āϤāĻŋāύāĻāĻŋ āϏā§āϤāϰ āϰāϝāĻŧā§āĻā§: āĻāĻā§āύā§āĻ āϏā§āϤāϰ , āϏāϰāĻā§āĻāĻžāĻŽ āϏā§āϤāϰ , āĻĒāϰāĻŋāώā§āĻŦāĻž āϏā§āϤāϰ āĨ¤

āϤāĻŋāύ āϏā§āϤāϰ āĻā§āύ?
- āĻāĻĻā§āĻŦā§āĻā§āϰ āĻŦāĻŋāĻā§āĻā§āĻĻ : āĻāĻā§āύā§āĻ āĻāĻĻā§āĻĻā§āĻļā§āϝā§āϰ āĻāĻĒāϰ, āϏāϰāĻā§āĻāĻžāĻŽāĻā§āϞāĻŋāϰ āĻāĻĒāϰ āĻāύā§āĻāĻžāϰāĻĢā§āϏ, āĻĒāϰāĻŋāώā§āĻŦāĻž āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύā§āϰ āĻāĻĒāϰ āĻĻā§āώā§āĻāĻŋ āύāĻŋāĻŦāĻĻā§āϧ āĻāϰā§
- āύāĻŽāύā§āϝāĻŧāϤāĻž : āĻāĻā§āύā§āĻ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻĒāĻĻā§āϧāϤāĻŋ āĻā§āϰ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠āĻ āĻĨāĻŦāĻž AI-āĻā§ āϏā§āĻŦāϝāĻŧāĻāĻā§āϰāĻŋāϝāĻŧāĻāĻžāĻŦā§ āϰā§āĻ āĻāϰāϤ⧠āĻĻāĻŋāϤ⧠āĻĒāĻžāϰā§
- āĻ āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻā§āĻļāύ : āĻĒāĻĻā§āϧāϤāĻŋ āĻāĻžāύāĻž āĻĨāĻžāĻāϞ⧠āĻŦā§āϝāϝāĻŧāĻŦāĻšā§āϞ āĻāĻāĻ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāĻĄāĻŧāĻŋāϝāĻŧā§ āϝā§āϤ⧠āĻĒāĻžāϰā§
āĻāĻ āĻŦāĻŋāĻāĻžāĻā§, āĻāĻĒāύāĻŋ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ (RAG) āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰāĻŦā§āύ - āĻā§āĻŦāϞ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āύāϝāĻŧ, āĻ āϰā§āĻĨ āĻĻāĻŋāϝāĻŧā§ āĻĢāϞāĻžāĻĢāϞ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰāĻžāĨ¤ āĻĒāϰā§, āĻāĻŽāϰāĻž āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰāĻŦ āĻāĻŋāĻāĻžāĻŦā§ āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ āĻāĻāĻžāϧāĻŋāĻ āĻĒāĻĻā§āϧāϤāĻŋāĻā§ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§āĨ¤
⧍. āĻāϰāĻāĻāĻŋ āĻĒāϰāĻŋāώā§āĻŦāĻž āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/services/hybrid_search_service.py
āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āϏāύāĻžāĻā§āϤ āĻāϰā§āύ # TODO: REPLACE_SQL
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
# This is your working query from the successful run!
sql = """
WITH query_embedding AS (
SELECT embeddings.values AS val
FROM ML.PREDICT(
MODEL TextEmbeddings,
(SELECT @query AS content)
)
)
SELECT
s.survivor_id,
s.name AS survivor_name,
s.biome,
sk.skill_id,
sk.name AS skill_name,
sk.category,
COSINE_DISTANCE(
sk.skill_embedding,
(SELECT val FROM query_embedding)
) AS distance
FROM Survivors s
JOIN SurvivorHasSkill shs ON s.survivor_id = shs.survivor_id
JOIN Skills sk ON shs.skill_id = sk.skill_id
WHERE sk.skill_embedding IS NOT NULL
ORDER BY distance ASC
LIMIT @limit
"""
ā§Š. āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ āϏāϰāĻā§āĻāĻžāĻŽā§āϰ āϏāĻāĻā§āĻāĻž
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/tools/hybrid_search_tools.py
hybrid_search_tools.py āϤā§, āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āϏāύāĻžāĻā§āϤ āĻāϰā§āύ # TODO: REPLACE_SEMANTIC_SEARCH_TOOL
đ āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
async def semantic_search(query: str, limit: int = 10) -> str:
"""
Force semantic (RAG) search using embeddings.
Use this when you specifically want to find things by MEANING,
not just matching keywords. Great for:
- Finding conceptually similar items
- Handling vague or abstract queries
- When exact terms are unknown
Example: "healing abilities" will find "first aid", "surgery",
"herbalism" even though no keywords match exactly.
Args:
query: What you're looking for (describe the concept)
limit: Maximum results
Returns:
Semantically similar results ranked by relevance
"""
try:
service = _get_service()
result = service.smart_search(
query,
force_method=SearchMethod.RAG,
limit=limit
)
return _format_results(
result["results"],
result["analysis"],
show_analysis=True
)
except Exception as e:
return f"Error in semantic search: {str(e)}"
āϝāĻāύ āĻāĻā§āύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠:
- āϏāĻžāĻĻā§āĻļā§āϝā§āϰ āĻāύā§āϝ āĻāĻŋāĻā§āĻāĻžāϏāĻž āĻāϰāĻž āĻĒā§āϰāĻļā§āύ ("X āĻāϰ āĻ āύā§āϰā§āĻĒ āĻā§āĻāĻā§āύ")
- āϧāĻžāϰāĻŖāĻžāĻāϤ āĻĒā§āϰāĻļā§āύ ("āύāĻŋāϰāĻžāĻŽāϝāĻŧ āĻā§āώāĻŽāϤāĻž")
- āϝāĻāύ āĻ āϰā§āĻĨ āĻŦā§āĻāĻž āĻ āϤā§āϝāύā§āϤ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖ
ā§Ē. āĻāĻā§āύā§āĻ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āύāĻŋāϰā§āĻĻā§āĻļāĻŋāĻāĻž (āύāĻŋāϰā§āĻĻā§āĻļāύāĻž)
āĻāĻā§āύā§āĻ āϏāĻāĻā§āĻāĻžā§, āύāĻŋāϰā§āĻĻā§āĻļā§āϰ āϏāĻžāĻĨā§ āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻ āĻāĻļāĻāĻŋ āĻāĻĒāĻŋ āĻĒā§āϏā§āĻ āĻāϰā§āύāĨ¤
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/agent.py
āĻāĻā§āύā§āĻ āϏāĻ āĻŋāĻ āĻā§āϞāĻāĻŋ āύāĻŋāϰā§āĻŦāĻžāĻāύ āĻāϰāϤ⧠āĻāĻ āύāĻŋāϰā§āĻĻā§āĻļāĻŋāĻāĻžāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§:
agent.py āĻĢāĻžāĻāϞā§, āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āϏāύāĻžāĻā§āϤ āĻāϰā§āύ # TODO: REPLACE_SEARCH_LOGIC , āĻāĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
- `semantic_search`: Force RAG/embedding search
Use for: "Find similar to X", conceptual queries, unknown terminology
Example: "Find skills related to healing"
đāĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āϏāύāĻžāĻā§āϤ āĻāϰā§āύ # TODO: ADD_SEARCH_TOOL āĻāĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
semantic_search, # Force RAG
ā§Ģ. āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰ⧠āϤāĻž āĻŦā§āĻāĻž (āĻā§āĻŦāϞāĻŽāĻžāϤā§āϰ āĻĒāĻ āύāϝā§āĻā§āϝ, āĻā§āύāĻ āĻĒāĻĻāĻā§āώā§āĻĒā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻ)
āϧāĻžāĻĒ ā§¨-ā§Ē-āĻ, āĻāĻĒāύāĻŋ āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ (RAG) āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰā§āĻā§āύ, āĻŽā§āϞ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāĻĻā§āϧāϤāĻŋ āϝāĻž āĻ āϰā§āĻĨ āĻ āύā§āϏāĻžāϰ⧠āĻĢāϞāĻžāĻĢāϞ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰā§āĨ¤ āĻāĻŋāύā§āϤ⧠āĻāĻĒāύāĻŋ āĻšāϝāĻŧāϤ⧠āϞāĻā§āώā§āϝ āĻāϰā§āĻā§āύ āϝ⧠āϏāĻŋāϏā§āĻā§āĻŽāĻāĻŋāĻā§ "āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ" āĻŦāϞāĻž āĻšāϝāĻŧāĨ¤ āĻāĻāĻžāύ⧠āϏāĻŦāĻāĻŋāĻā§ āĻāĻāϏāĻžāĻĨā§ āĻā§āĻāĻžāĻŦā§ āĻāĻžāĻĒ āĻāĻžāϝāĻŧ:
āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻŽāĻžāϰā§āĻ āĻāĻŋāĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰ⧠:
way-back-home/level_2/backend/services/hybrid_search_service.py āĻĢāĻžāĻāϞā§, āϝāĻāύ hybrid_search() āĻāϞ āĻāϰāĻž āĻšāϝāĻŧ, āϤāĻāύ āĻĒāϰāĻŋāώā§āĻŦāĻžāĻāĻŋ āĻāĻāϝāĻŧ āĻ
āύā§āϏāύā§āϧāĻžāύ āĻāĻžāϞāĻžāϝāĻŧ āĻāĻŦāĻ āĻĢāϞāĻžāĻĢāϞ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§:
# Location: backend/services/hybrid_search_service.py
rank_kw = keyword_ranks.get(surv_id, float('inf'))
rank_rag = rag_ranks.get(surv_id, float('inf'))
rrf_score = 0.0
if rank_kw != float('inf'):
rrf_score += 1.0 / (K + rank_kw)
if rank_rag != float('inf'):
rrf_score += 1.0 / (K + rank_rag)
combined_score = rrf_score
āĻāĻ āĻā§āĻĄāϞā§āϝāĻžāĻŦā§āϰ āĻāύā§āϝ , āĻāĻĒāύāĻŋ āϏāĻŋāĻŽā§āύā§āĻāĻŋāĻ āϏāĻžāϰā§āĻ āĻāĻŽā§āĻĒā§āύā§āύā§āĻ (RAG) āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰā§āĻā§āύ, āϝāĻž āĻāĻŋāϤā§āϤāĻŋāĨ¤ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻāĻŦāĻ āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻĒāĻĻā§āϧāϤāĻŋāĻā§āϞāĻŋ āĻāϤāĻŋāĻŽāϧā§āϝā§āĻ āĻĒāϰāĻŋāώā§āĻŦāĻžāĻāĻŋāϤ⧠āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§ - āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻ āϤāĻŋāύāĻāĻŋāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§!
āĻ āĻāĻŋāύāύā§āĻĻāύ! āĻāĻĒāύāĻŋ āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻĒāύāĻžāϰ āĻā§āϰāĻžāĻĢ āĻāϰāĻāĻāĻŋ āĻāĻā§āύā§āĻ āϏāĻĢāϞāĻāĻžāĻŦā§ āĻļā§āώ āĻāϰā§āĻā§āύ!
ā§. ADK āĻāϝāĻŧā§āĻŦā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻā§āϰ āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻž
āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻ āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻžāϰ āϏāĻŦāĻā§āϝāĻŧā§ āϏāĻšāĻ āĻāĻĒāĻžāϝāĻŧ āĻšāϞ adk web āĻāĻŽāĻžāύā§āĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž, āϝāĻž āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻāĻā§ āĻāĻāĻāĻŋ āĻ
āύā§āϤāϰā§āύāĻŋāϰā§āĻŽāĻŋāϤ āĻā§āϝāĻžāĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻžāϞ⧠āĻāϰā§āĨ¤
ā§§. āĻāĻā§āύā§āĻ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž
đđģ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻĄāĻŋāϰā§āĻā§āĻāϰāĻŋāϤ⧠āύā§āĻāĻŋāĻā§āĻ āĻāϰā§āύ (āϝā§āĻāĻžāύ⧠āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ) āĻāĻŦāĻ āĻāϝāĻŧā§āĻŦ āĻāύā§āĻāĻžāϰāĻĢā§āϏ āĻāĻžāϞ⧠āĻāϰā§āύ::
cd ~/way-back-home/level_2/backend
uv run adk web
āĻāĻ āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāĻā§āύā§āĻ āĻļā§āϰ⧠āĻāϰā§
agent/agent.py
āĻāĻŦāĻ āĻĒāϰā§āĻā§āώāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻāϝāĻŧā§āĻŦ āĻāύā§āĻāĻžāϰāĻĢā§āϏ āĻā§āϞā§āĨ¤
đ URL āĻā§āϞā§āύ:
āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻāĻāĻāĻŋ āϏā§āĻĨāĻžāύā§āϝāĻŧ URL āĻāĻāĻāĻĒā§āĻ āĻāϰāĻŦā§ (āϏāĻžāϧāĻžāϰāĻŖāϤ http://127.0.0.1:8000 āĻŦāĻž āĻ
āύā§āϰā§āĻĒ)āĨ¤ āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āĻā§āϞā§āύāĨ¤

URL-āĻ āĻā§āϞāĻŋāĻ āĻāϰāĻžāϰ āĻĒāϰ, āĻāĻĒāύāĻŋ ADK āĻāϝāĻŧā§āĻŦ UI āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύāĨ¤ āĻāĻĒāϰā§āϰ āĻŦāĻžāĻŽ āĻā§āĻŖ āĻĨā§āĻā§ "āĻāĻā§āύā§āĻ" āύāĻŋāϰā§āĻŦāĻžāĻāύ āĻāϰā§āύāĨ¤

2. āĻ āύā§āϏāύā§āϧāĻžāύ āĻā§āώāĻŽāϤāĻž āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻž
āĻāĻā§āύā§āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻļā§āύā§āϰ āĻŦā§āĻĻā§āϧāĻŋāĻŽāϤā§āϤāĻžāϰ āϏāĻžāĻĨā§ āϏāĻŽāĻžāϧāĻžāύ āĻāϰāĻžāϰ āĻāύā§āϝ āĻĄāĻŋāĻāĻžāĻāύ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤ āĻŦāĻŋāĻāĻŋāύā§āύ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāĻĻā§āϧāϤāĻŋ āĻāĻžāϰā§āϝāĻāϰāĻāĻžāĻŦā§ āĻĻā§āĻāϤ⧠āĻā§āϝāĻžāĻ āĻāĻāύā§āĻĄā§āϤ⧠āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāύāĻĒā§āĻāĻā§āϞāĻŋ āĻā§āώā§āĻāĻž āĻāϰā§āύāĨ¤
đ§Ŧ A. āĻā§āϰāĻžāĻĢ RAG (āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ)
āĻ āϰā§āĻĨ āĻāĻŦāĻ āϧāĻžāϰāĻŖāĻžāϰ āĻāĻĒāϰ āĻāĻŋāϤā§āϤāĻŋ āĻāϰ⧠āĻāĻāĻā§āĻŽāĻā§āϞāĻŋ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰā§, āĻāĻŽāύāĻāĻŋ āϝāĻĻāĻŋ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄāĻā§āϞāĻŋ āĻŽāĻŋāϞ āύāĻžāĻ āĻšāϝāĻŧāĨ¤
āĻĒāϰā§āĻā§āώāĻžāϰ āĻĒā§āϰāĻļā§āύ: (āύā§āĻā§āϰ āϝā§āĻā§āύ⧠āĻāĻāĻāĻŋ āĻŦā§āĻā§ āύāĻŋāύ)
Who can help with injuries?
What abilities are related to survival?
āĻā§ āĻā§āĻāĻāĻŦā§āύ:
- āϝā§āĻā§āϤāĻŋāϤ⧠āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻŦāĻž RAG āĻ āύā§āϏāύā§āϧāĻžāύ āĻāϞā§āϞā§āĻ āĻāϰāĻž āĻāĻāĻŋāϤāĨ¤
- āĻāĻĒāύāĻžāϰ āϧāĻžāϰāĻŖāĻžāĻāϤāĻāĻžāĻŦā§ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻā§āĻž āĻāĻāĻŋāϤ (āϝā§āĻŽāύ, "āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž" āĻāĻŋāĻā§āĻāĻžāϏāĻž āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ "āĻ āϏā§āϤā§āϰā§āĻĒāĻāĻžāϰ")āĨ¤
- āĻĢāϞāĻžāĻĢāϞ⧠đ§Ŧ āĻāĻāĻāύ āĻĨāĻžāĻāĻŦā§āĨ¤
đ āĻ. āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ
āĻāĻāĻŋāϞ āĻĒā§āϰāĻļā§āύā§āϰ āĻāύā§āϝ āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻŦā§āĻāĻžāϰ āϏāĻžāĻĨā§ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻĢāĻŋāϞā§āĻāĻžāϰāĻā§āϞāĻŋāĻā§ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§āĨ¤
āĻĒāϰā§āĻā§āώāĻžāϰ āĻĒā§āϰāĻļā§āύ: (āύā§āĻā§āϰ āϝā§āĻā§āύ⧠āĻāĻāĻāĻŋ āĻŦā§āĻā§ āύāĻŋāύ)
Find someone who can ply a plane in the volcanic area
Who has healing abilities in the FOSSILIZED?
Who has healing abilities in the mountains?
āĻā§ āĻā§āĻāĻāĻŦā§āύ:
- āϝā§āĻā§āϤāĻŋāϤ⧠āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύā§āϰ āĻāĻĨāĻž āĻāϞā§āϞā§āĻ āĻāϰāĻž āĻāĻāĻŋāϤāĨ¤
- āĻĢāϞāĻžāĻĢāϞ āĻāĻāϝāĻŧ āĻŽāĻžāύāĻĻāĻŖā§āĻĄā§āϰ (āϧāĻžāϰāĻŖāĻž + āĻ āĻŦāϏā§āĻĨāĻžāύ/āĻŦāĻŋāĻāĻžāĻ) āϏāĻžāĻĨā§ āĻŽāĻŋāϞāĻŋāϤ āĻšāĻāϝāĻŧāĻž āĻāĻāĻŋāϤāĨ¤
- āĻāĻāϝāĻŧ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧠āĻĒāĻžāĻāϝāĻŧāĻž āĻĢāϞāĻžāĻĢāϞ⧠đ āĻāĻāĻāύ āĻĨāĻžāĻāĻŦā§ āĻāĻŦāĻ āϏāϰā§āĻŦā§āĻā§āĻ āϏā§āĻĨāĻžāύ āĻĒāĻžāĻŦā§āĨ¤
đđģ āĻĒāϰā§āĻā§āώāĻž āĻļā§āώ āĻšāϞā§, āĻāĻĒāύāĻžāϰ āĻāĻŽāĻžāύā§āĻĄ āϞāĻžāĻāύ⧠Ctrl+C āĻāĻŋāĻĒā§ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāĻŋ āĻļā§āώ āĻāϰā§āύāĨ¤
ā§Ž. āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻāĻŦā§āĻĻāύāĻĒāϤā§āϰ āĻāĻžāϞāĻžāύā§
āĻĢā§āϞ āϏā§āĻā§āϝāĻžāĻ āĻāϰā§āĻāĻŋāĻā§āĻāĻāĻžāϰ āĻāĻāĻžāϰāĻāĻŋāĻ

āϏā§āĻļāύ āϏāĻžāϰā§āĻāĻŋāϏ āĻāĻŦāĻ āϰāĻžāύāĻžāϰ āϝā§āĻ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠chat.py āĻĢāĻžāĻāϞāĻāĻŋ āĻāĻžāϞ⧠āĻāϰā§āύ (āĻāĻāĻŋāϝāĻŧā§ āϝāĻžāĻāϝāĻŧāĻžāϰ āĻāĻā§ āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāĻŋ āĻļā§āώ āĻāϰāϤ⧠"ctrl+C" āĻāϰā§āĻā§āύ āĻāĻŋāύāĻž āϤāĻž āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰā§āύ):
cloudshell edit ~/way-back-home/level_2/backend/api/routes/chat.py
chat.py āĻĢāĻžāĻāϞā§, āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āĻā§āĻāĻā§āύ # TODO: REPLACE_INMEMORY_SERVICES , āĻāĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
session_service = InMemorySessionService()
memory_service = InMemoryMemoryService()
chat.py āĻĢāĻžāĻāϞā§, āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āϏāύāĻžāĻā§āϤ āĻāϰā§āύ # TODO: REPLACE_RUNNER , āĻāĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
runner = Runner(
agent=root_agent,
session_service=session_service,
memory_service=memory_service,
app_name="survivor-network"
)
1. āĻāĻŦā§āĻĻāύ āĻļā§āϰ⧠āĻāϰā§āύ
āϝāĻĻāĻŋ āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞāĻāĻŋ āĻāĻāύāĻ āĻāϞāĻŽāĻžāύ āĻĨāĻžāĻā§, āϤāĻžāĻšāϞ⧠Ctrl+C āĻāĻŋāĻĒā§ āĻāĻāĻŋ āĻļā§āώ āĻāϰā§āύāĨ¤
đđģ āĻ ā§āϝāĻžāĻĒ āĻļā§āϰ⧠āĻāϰā§āύ:
cd ~/way-back-home/level_2/
./start_app.sh
āϝāĻāύ āĻāĻāĻŋ āϏāĻĢāϞāĻāĻžāĻŦā§ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻļā§āϰ⧠āĻāϰāĻŦā§, āϤāĻāύ āĻāĻĒāύāĻŋ āύā§āĻā§āϰ āĻŽāϤ Local: http://localhost:5173/" āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ: 
đ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻĨā§āĻā§ Local: http://localhost:5173/ āĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύāĨ¤

2. āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ
āĻĒā§āϰāĻļā§āύ :
Find skills similar to healing

āĻāĻŋ āĻšāϝāĻŧ :
- āĻāĻā§āύā§āĻ āϏāĻžāĻĻā§āĻļā§āϝ āĻ āύā§āϰā§āϧ āϏā§āĻŦā§āĻā§āϤāĻŋ āĻĻā§āϝāĻŧ
- "āύāĻŋāϰāĻžāĻŽāϝāĻŧ" āĻāϰ āĻāύā§āϝ āĻāĻŽā§āĻŦā§āĻĄāĻŋāĻ āϤā§āϰāĻŋ āĻāϰā§
- āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻāϤāĻāĻžāĻŦā§ āĻ āύā§āϰā§āĻĒ āĻĻāĻā§āώāϤāĻž āĻā§āĻāĻā§ āĻĒā§āϤ⧠āĻā§āϏāĻžāĻāύ āĻĻā§āϰāϤā§āĻŦ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§
- āϰāĻŋāĻāĻžāϰā§āύāϏ: āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž (āϝāĻĻāĻŋāĻ āύāĻžāĻŽāĻā§āϞāĻŋ "āύāĻŋāϰāĻžāĻŽāϝāĻŧ" āĻāϰ āϏāĻžāĻĨā§ āĻŽā§āϞ⧠āύāĻž)
ā§Š. āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ
āĻĒā§āϰāĻļā§āύ :
Find medical skills in the mountains
āĻāĻŋ āĻšāϝāĻŧ :
- āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻāĻŽā§āĻĒā§āύā§āύā§āĻ :
category='medical'āĻāϰ āĻāύā§āϝ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāϰā§āύ - āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻāĻĒāĻžāĻĻāĻžāύ : "āĻāĻŋāĻāĻŋā§āϏāĻž" āĻāĻŽā§āĻŦā§āĻĄ āĻāϰā§āύ āĻāĻŦāĻ āϏāĻžāĻĻā§āĻļā§āϝ āĻ āύā§āϏāĻžāϰ⧠āϰâā§āϝāĻžāĻā§āĻ āĻāϰā§āύ
- āĻŽāĻžāϰā§āĻ āĻāϰā§āύ : āĻāĻāϝāĻŧ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧠āĻĒāĻžāĻāϝāĻŧāĻž āĻĢāϞāĻžāĻĢāϞāĻā§āϞāĻŋāĻā§ āĻ āĻā§āϰāĻžāϧāĻŋāĻāĻžāϰ āĻĻāĻŋāϝāĻŧā§ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§āύ đ
āĻĒā§āϰāĻļā§āύ (āĻāĻā§āĻāĻŋāĻ) :
Who is good at survival and in the forest?
āĻāĻŋ āĻšāϝāĻŧ :
- āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻā§āĻāĻā§ āĻĒāĻžā§:
biome='forest' - āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻāĻŦāĻŋāώā§āĻāĻžāϰ: "āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻžāϰ" āĻŽāϤ⧠āĻĻāĻā§āώāϤāĻž
- āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āϏā§āϰāĻž āĻĢāϞāĻžāĻĢāϞā§āϰ āĻāύā§āϝ āĻāĻāϝāĻŧāĻā§āĻ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§
đđģ āϝāĻāύ āĻāĻĒāύāĻŋ āĻĒāϰā§āĻā§āώāĻž āĻļā§āώ āĻāϰāĻŦā§āύ, āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, Ctrl+C āĻāĻŋāĻĒā§ āĻāĻāĻŋ āĻļā§āώ āĻāϰā§āύāĨ¤
⧝. āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ â āĻā§āϞāĻŋāĻ āϞā§āϝāĻŧāĻžāϰ
āĻā§āύ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻāĻāĻŋ āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύ?
āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻžāϰ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻ āĻā§āĻŦāϞ āĻā§āĻā§āϏāĻ āύāϝāĻŧāĨ¤ āĻā§āώā§āϤā§āϰā§āϰ āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋāϰāĻž āϏāϰāĻžāϏāϰāĻŋ āĻā§āϝāĻžāĻā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻ āϏāĻāĻāĻ āĻŋāϤ āϤāĻĨā§āϝ āĻĒāĻžāĻ āĻžāύ:
- đ¸ āĻāĻŦāĻŋ : āϏāĻŽā§āĻĒāĻĻ, āĻŦāĻŋāĻĒāĻĻ, āĻŦāĻž āϏāϰāĻā§āĻāĻžāĻŽā§āϰ āĻāĻŦāĻŋ
- đĨ āĻāĻŋāĻĄāĻŋāĻ : āϏā§āĻā§āϝāĻžāĻāĻžāϏ āϰāĻŋāĻĒā§āϰā§āĻ āĻŦāĻž SOS āϏāĻŽā§āĻĒā§āϰāĻāĻžāϰ
- đ āĻā§āĻā§āϏāĻ : āĻĢāĻŋāϞā§āĻĄ āύā§āĻ āĻŦāĻž āϞāĻ
āĻāĻŽāϰāĻž āĻā§āύ āĻĢāĻžāĻāϞāĻā§āϞāĻŋ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž āĻāϰāĻāĻŋ?
āĻāĻā§āϰ āϧāĻžāĻĒā§ āϝā§āĻāĻžāύ⧠āĻāĻŽāϰāĻž āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻĄā§āĻāĻž āĻ
āύā§āϏāύā§āϧāĻžāύ āĻāϰā§āĻāĻŋ, āϤāĻžāϰ āĻŦāĻŋāĻĒāϰā§āϤā§, āĻāĻāĻžāύ⧠āĻāĻŽāϰāĻž User-Uploaded Files āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž āĻāϰāĻŋāĨ¤ chat.py āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ āĻāϤāĻŋāĻļā§āϞāĻāĻžāĻŦā§ āĻĢāĻžāĻāϞ āϏāĻāϝā§āĻā§āϤāĻŋ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰā§:
āĻā§āϏ | āĻāύā§āĻā§āύā§āĻ | āϞāĻā§āώā§āϝ |
āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āϏāĻāϝā§āĻā§āϤāĻŋ | āĻāĻŦāĻŋ/āĻāĻŋāĻĄāĻŋāĻ/āĻā§āĻā§āϏāĻ | āĻā§āϰāĻžāĻĢā§ āϝā§āĻ āĻāϰāĻžāϰ āĻāύā§āϝ āϤāĻĨā§āϝ |
āĻā§āϝāĻžāĻ āĻĒā§āϰāϏāĻā§āĻ | "āĻāĻāĻžāύ⧠āϏāϰāĻŦāϰāĻžāĻšā§āϰ āĻāĻāĻāĻŋ āĻāĻŦāĻŋ" | āĻāĻĻā§āĻĻā§āĻļā§āϝ āĻāĻŦāĻ āĻ āϤāĻŋāϰāĻŋāĻā§āϤ āĻŦāĻŋāĻŦāϰāĻŖ |
āĻĒāϰāĻŋāĻāϞā§āĻĒāĻŋāϤ āĻĒāĻĻā§āϧāϤāĻŋ: āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏāĻŋāϝāĻŧāĻžāϞ āĻāĻā§āύā§āĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ
āĻāĻŽāϰāĻž āĻāĻāĻāĻŋ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏāĻŋāϝāĻŧāĻžāϞ āĻāĻā§āύā§āĻ ( multimedia_agent.py ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŋ āϝāĻž āĻŦāĻŋāĻļā§āώāĻžāϝāĻŧāĻŋāϤ āĻāĻā§āύā§āĻāĻĻā§āϰ āĻāĻāϏāĻžāĻĨā§ āĻļā§āĻā§āĻāϞāĻŋāϤ āĻāϰā§:

āĻāĻāĻŋāĻā§ backend/agent/multimedia_agent.py āϤ⧠SequentialAgent āĻšāĻŋāϏā§āĻŦā§ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤
āĻā§āϞāĻŋāĻ āϞā§āϝāĻŧāĻžāϰāĻāĻŋ āĻāĻā§āύā§āĻāĻĻā§āϰ āĻāύā§āϝ āĻĒā§āϰāϝāĻŧā§āĻāύā§āϝāĻŧ āĻā§āώāĻŽāϤāĻž āĻĒā§āϰāĻĻāĻžāύ āĻāϰā§āĨ¤ āĻā§āϞāĻā§āϞāĻŋ "āĻā§āĻāĻžāĻŦā§" āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰ⧠â āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž, āϏāϤā§āϤāĻž āĻŦā§āϰ āĻāϰāĻž āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻžāĨ¤
ā§§. āĻā§āϞāϏ āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ
đđģ āĻāĻāĻāĻŋ āύāϤā§āύ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻā§āϞā§āύāĨ¤ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/tools/extraction_tools.py
2. upload_media āĻā§āϞāĻāĻŋ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰā§āύ
āĻāĻ āĻā§āϞāĻāĻŋ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϏā§āĻā§āϰā§āĻā§ āĻāĻāĻāĻŋ āϏā§āĻĨāĻžāύā§āϝāĻŧ āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄ āĻāϰā§āĨ¤
đ extraction_tools.py āϤā§, āĻŽāύā§āϤāĻŦā§āϝ pass # TODO: REPLACE_UPLOAD_MEDIA_FUNCTION āĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
"""
Upload media file to GCS and detect its type.
Args:
file_path: Path to the local file
survivor_id: Optional survivor ID to associate with upload
Returns:
Dict with gcs_uri, media_type, and status
"""
try:
if not file_path:
return {"status": "error", "error": "No file path provided"}
# Strip quotes if present
file_path = file_path.strip().strip("'").strip('"')
if not os.path.exists(file_path):
return {"status": "error", "error": f"File not found: {file_path}"}
gcs_uri, media_type, signed_url = gcs_service.upload_file(file_path, survivor_id)
return {
"status": "success",
"gcs_uri": gcs_uri,
"signed_url": signed_url,
"media_type": media_type.value,
"file_name": os.path.basename(file_path),
"survivor_id": survivor_id
}
except Exception as e:
logger.error(f"Upload failed: {e}")
return {"status": "error", "error": str(e)}
ā§Š. extract_from_media āĻā§āϞāĻāĻŋ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰā§āύ
āĻāĻ āĻā§āϞāĻāĻŋ āĻāĻāĻāĻŋ āϰāĻžāĻāĻāĻžāϰ â āĻāĻāĻŋ media_type āĻĒāϰā§āĻā§āώāĻž āĻāϰ⧠āĻāĻŦāĻ āϏāĻ āĻŋāĻ āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻāϰ⧠(āĻā§āĻā§āϏāĻ, āĻāĻŦāĻŋ, āĻŦāĻž āĻāĻŋāĻĄāĻŋāĻ) āĻĒā§āϰā§āϰāĻŖ āĻāϰā§āĨ¤
extraction_tools.py āϤā§, āĻŽāύā§āϤāĻŦā§āϝ pass # TODO: REPLACE_EXTRACT_FROM_MEDIA āĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
"""
Extract entities and relationships from uploaded media.
Args:
gcs_uri: GCS URI of the uploaded file
media_type: Type of media (text/image/video)
signed_url: Optional signed URL for public/temporary access
Returns:
Dict with extraction results
"""
try:
if not gcs_uri:
return {"status": "error", "error": "No GCS URI provided"}
# Select appropriate extractor
if media_type == MediaType.TEXT.value or media_type == "text":
result = await text_extractor.extract(gcs_uri)
elif media_type == MediaType.IMAGE.value or media_type == "image":
result = await image_extractor.extract(gcs_uri)
elif media_type == MediaType.VIDEO.value or media_type == "video":
result = await video_extractor.extract(gcs_uri)
else:
return {"status": "error", "error": f"Unsupported media type: {media_type}"}
# Inject signed URL into broadcast info if present
if signed_url:
if not result.broadcast_info:
result.broadcast_info = {}
result.broadcast_info['thumbnail_url'] = signed_url
return {
"status": "success",
"extraction_result": result.to_dict(), # Return valid JSON dict instead of object
"summary": result.summary,
"entities_count": len(result.entities),
"relationships_count": len(result.relationships),
"entities": [e.to_dict() for e in result.entities],
"relationships": [r.to_dict() for r in result.relationships]
}
except Exception as e:
logger.error(f"Extraction failed: {e}")
return {"status": "error", "error": str(e)}
āĻŽā§āϞ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύā§āϰ āĻŦāĻŋāĻŦāϰāĻŖ:
- āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻāύāĻĒā§āĻ : āĻāĻŽāϰāĻž āĻā§āĻā§āϏāĻ āĻĒā§āϰāĻŽā§āĻĒāĻ (
_get_extraction_prompt()) āĻāĻŦāĻ āĻāĻŽā§āĻ āĻ āĻŦāĻā§āĻā§āĻ āĻāĻāϝāĻŧāĻā§āĻgenerate_contentāĻ āĻĒāĻžāϏ āĻāϰāĻŋāĨ¤ - āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰā§āĻĄ āĻāĻāĻāĻĒā§āĻ :
response_mime_type="application/json"āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰ⧠āϝ⧠LLM āĻŦā§āϧ JSON āĻĒā§āϰāĻĻāĻžāύ āĻāϰā§, āϝāĻž āĻĒāĻžāĻāĻĒāϞāĻžāĻāύā§āϰ āĻāύā§āϝ āĻ āϤā§āϝāύā§āϤ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖāĨ¤ - āĻāĻŋāĻā§āϝā§āϝāĻŧāĻžāϞ āĻāύā§āĻāĻŋāĻāĻŋ āϞāĻŋāĻā§āĻāĻŋāĻ : āĻĒā§āϰāĻŽā§āĻĒāĻā§ āĻĒāϰāĻŋāĻāĻŋāϤ āĻāύā§āĻāĻŋāĻāĻŋ āĻ āύā§āϤāϰā§āĻā§āĻā§āϤ āĻĨāĻžāĻā§ āϝāĻžāϤ⧠āĻŽāĻŋāĻĨā§āύ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻ āĻā§āώāϰ āĻāĻŋāύāϤ⧠āĻĒāĻžāϰā§āĨ¤
ā§Ē. save_to_spanner āĻā§āϞāĻāĻŋ āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰā§āύ
āĻāĻ āĻā§āϞāĻāĻŋ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ āĻĄāĻŋāĻŦāĻŋāϤ⧠āύāĻŋāώā§āĻāĻžāĻļāĻŋāϤ āϏāϤā§āϤāĻž āĻāĻŦāĻ āϏāĻŽā§āĻĒāϰā§āĻāĻā§āϞāĻŋāĻā§ āϧāϰ⧠āϰāĻžāĻā§āĨ¤
extraction_tools.py āϤā§, āĻŽāύā§āϤāĻŦā§āϝ pass # TODO: REPLACE_SPANNER_AGENT āϏāύāĻžāĻā§āϤ āĻāϰā§āύāĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
"""
Save extracted entities and relationships to Spanner Graph DB.
Args:
extraction_result: ExtractionResult object (or dict from previous step if passed as dict)
survivor_id: Optional survivor ID to associate with the broadcast
Returns:
Dict with save statistics
"""
try:
# Handle if extraction_result is passed as the wrapper dict from extract_from_media
result_obj = extraction_result
if isinstance(extraction_result, dict) and 'extraction_result' in extraction_result:
result_obj = extraction_result['extraction_result']
# If result_obj is a dict (from to_dict()), reconstruct it
if isinstance(result_obj, dict):
from extractors.base_extractor import ExtractionResult
result_obj = ExtractionResult.from_dict(result_obj)
if not result_obj:
return {"status": "error", "error": "No extraction result provided"}
stats = spanner_service.save_extraction_result(result_obj, survivor_id)
return {
"status": "success",
"entities_created": stats['entities_created'],
"entities_existing": stats['entities_found_existing'],
"relationships_created": stats['relationships_created'],
"broadcast_id": stats['broadcast_id'],
"errors": stats['errors'] if stats['errors'] else None
}
except Exception as e:
logger.error(f"Spanner save failed: {e}")
return {"status": "error", "error": str(e)}
āĻāĻā§āύā§āĻāĻĻā§āϰ āĻāĻā§āĻ-āϏā§āϤāϰā§āϰ āϏāϰāĻā§āĻāĻžāĻŽ āĻĒā§āϰāĻĻāĻžāύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§, āĻāĻŽāϰāĻž āĻāĻā§āύā§āĻā§āϰ āϝā§āĻā§āϤāĻŋ āĻā§āώāĻŽāϤāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻĄā§āĻāĻž āĻ āĻāĻŖā§āĻĄāϤāĻž āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰāĻŋāĨ¤
ā§Ģ. GCS āĻĒāϰāĻŋāώā§āĻŦāĻž āĻāĻĒāĻĄā§āĻ āĻāϰā§āύ
GCSService āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϏā§āĻā§āϰā§āĻā§ āĻĒā§āϰāĻā§āϤ āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰā§āĨ¤
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/services/gcs_service.py
đ gcs_service.py āĻĢāĻžāĻāϞā§, upload_file āĻĢāĻžāĻāĻļāύā§āϰ āĻāĻŋāϤāϰ⧠# TODO: REPLACE_SAVE_TO_GCS āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āĻā§āĻāĻā§āύāĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
blob = self.bucket.blob(blob_name)
blob.upload_from_filename(file_path)
āĻāĻāĻŋāĻā§ āĻāĻāĻāĻŋ āĻĒāϰāĻŋāώā§āĻŦāĻžāϤ⧠āϏāĻāĻā§āώā§āĻĒāĻŋāϤ āĻāϰā§, āĻāĻā§āύā§āĻāĻā§ GCS āĻŦāĻžāĻā§āĻ, āĻŦā§āϞāĻŦ āύāĻžāĻŽ, āĻ āĻĨāĻŦāĻž āϏā§āĻŦāĻžāĻā§āώāϰāĻŋāϤ URL āĻā§āύāĻžāϰā§āĻļāύ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāĻžāύāϤ⧠āĻšāĻŦā§ āύāĻžāĨ¤ āĻāĻāĻŋ āĻā§āĻŦāϞ "āĻāĻĒāϞā§āĻĄ" āĻāϰāϤ⧠āĻŦāϞā§āĨ¤
ā§Ŧ. (āĻā§āĻŦāϞ āĻĒāĻ āύāϝā§āĻā§āϝ) āĻā§āύ āĻāĻā§āύā§āĻāĻŋāĻ āĻāϰā§āĻŽāĻĒā§āϰāĻŦāĻžāĻš > āĻāϤāĻŋāĻšā§āϝāĻŦāĻžāĻšā§ āĻĒāĻĻā§āϧāϤāĻŋ?
āĻāĻā§āύā§āĻāĻŋāĻ āϏā§āĻŦāĻŋāϧāĻž:
āĻŦā§āĻļāĻŋāώā§āĻā§āϝ | āĻŦā§āϝāĻžāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ | āĻāĻā§āύā§āĻ-āĻāĻžāϞāĻŋāϤ | āĻāĻā§āύā§āĻāĻŋāĻ āĻāϰā§āĻŽāĻĒā§āϰāĻŦāĻžāĻš |
āĻāĻāĻŋāϞāϤāĻž | āĻāĻŽ (ā§§āĻāĻŋ āϏā§āĻā§āϰāĻŋāĻĒā§āĻ) | āĻāĻā§āĻ (ā§Ģ+ āĻĒāϰāĻŋāώā§āĻŦāĻž) | āύāĻŋāĻŽā§āύ (ā§§āĻāĻŋ āĻĒāĻžāĻāĻĨāύ āĻĢāĻžāĻāϞ: |
āϰāĻžāĻā§āϝ āĻŦā§āϝāĻŦāϏā§āĻĨāĻžāĻĒāύāĻž | āĻā§āϞā§āĻŦāĻžāϞ āĻā§āϰāĻŋāϝāĻŧā§āĻŦāϞ | āĻļāĻā§āϤ (āĻŦāĻŋāĻā§āĻāĻŋāύā§āύ) | āĻāĻāύāĻŋāĻĢāĻžāĻāĻĄ (āĻāĻā§āύā§āĻ āϏā§āĻā§āĻ) |
āϤā§āϰā§āĻāĻŋ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž | āĻā§āϰā§āϝāĻžāĻļ | āύā§āϰāĻŦ āϞāĻ | āĻāύā§āĻāĻžāϰā§āĻā§āĻāĻŋāĻ ("āĻāĻŽāĻŋ āϏā§āĻ āĻĢāĻžāĻāϞāĻāĻŋ āĻĒāĻĄāĻŧāϤ⧠āĻĒāĻžāϰāĻŋāύāĻŋ") |
āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻž | āĻāύāϏā§āϞ āĻĒā§āϰāĻŋāύā§āĻ | āĻĒā§āϞāĻŋāĻ āĻĒā§āϰāϝāĻŧā§āĻāύ | āϤāĻžā§āĻā§āώāĻŖāĻŋāĻ (āĻā§āϝāĻžāĻā§āϰ āĻ āĻāĻļ) |
āĻ āĻāĻŋāϝā§āĻāύāϝā§āĻā§āϝāϤāĻž | āϏā§āĻĨāĻŋāϰ āϝā§āĻā§āϤāĻŋ | āĻ āύāĻŽāύā§āϝāĻŧ āĻĢāĻžāĻāĻļāύ | āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ (āĻāϞāĻāϞāĻāĻŽ āĻĒāϰāĻŦāϰā§āϤ⧠āĻĒāĻĻāĻā§āώā§āĻĒ āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰā§) |
āĻĒā§āϰāϏāĻā§āĻ āϏāĻā§āϤāύāϤāĻž | āĻā§āύāĻāĻŋāĻ āύāϝāĻŧ | āĻā§āύāĻāĻŋāĻ āύāϝāĻŧ | āϏāĻŽā§āĻĒā§āϰā§āĻŖ (āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāĻĻā§āĻĻā§āĻļā§āϝ āĻāĻžāύā§) |
āĻā§āύ āĻāĻāĻŋ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖ: multimedia_agent.py (ā§ĒāĻāĻŋ āϏāĻžāĻŦ-āĻāĻā§āύā§āĻ āϏāĻš āĻāĻāĻāĻŋ SequentialAgent: āĻāĻĒāϞā§āĻĄ â āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ â āϏāĻāϰāĻā§āώāĻŖ â āϏāĻžāϰāĻžāĻāĻļ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§, āĻāĻŽāϰāĻž āĻāĻāĻŋāϞ āĻ
āĻŦāĻāĻžāĻ āĻžāĻŽā§ āĻāĻŦāĻ āĻāĻā§āĻā§āϰ āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻā§āϞāĻŋāĻā§ āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ, āĻāĻĨā§āĻĒāĻāĻĨāύāĻŽā§āϞāĻ āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āϞāĻāĻŋāĻ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰāĻŋāĨ¤
ā§§ā§Ļ. āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ â āĻāĻā§āύā§āĻ āϏā§āϤāϰ
āĻāĻā§āύā§āĻ āϏā§āϤāϰāĻāĻŋ āĻŦā§āĻĻā§āϧāĻŋāĻŽāϤā§āϤāĻžāĻā§ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰ⧠â āĻāĻā§āύā§āĻāϰāĻž āĻāĻžāĻ āϏāĻŽā§āĻĒāύā§āύ āĻāϰāĻžāϰ āĻāύā§āϝ āϏāϰāĻā§āĻāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤ āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāĻā§āύā§āĻā§āϰ āĻāĻāĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻā§āĻŽāĻŋāĻāĻž āĻĨāĻžāĻā§ āĻāĻŦāĻ āĻĒā§āϰāϏāĻā§āĻāĻāĻŋ āĻĒāϰāĻŦāϰā§āϤā§āĻāĻŋāϤ⧠āĻĒā§āϰā§āϰāĻŖ āĻāϰā§āĨ¤ āύā§āĻā§ āĻŽāĻžāϞā§āĻāĻŋāĻāĻā§āύā§āĻ āϏāĻŋāϏā§āĻā§āĻŽā§āϰ āĻāύā§āϝ āĻāϰā§āĻāĻŋāĻā§āĻāĻāĻžāϰ āĻĄāĻžāϝāĻŧāĻžāĻā§āϰāĻžāĻŽ āĻĻā§āĻāϝāĻŧāĻž āĻšāϞāĨ¤

ā§§. āĻāĻā§āύā§āĻ āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/multimedia_agent.py
2. āĻāĻĒāϞā§āĻĄ āĻāĻā§āύā§āĻā§āϰ āϏāĻāĻā§āĻāĻž āĻĻāĻŋāύ
āĻāĻ āĻāĻā§āύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻŦāĻžāϰā§āϤāĻž āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻĢāĻžāĻāϞ āĻĒāĻžāĻĨ āĻŦā§āϰ āĻāϰ⧠āĻāĻŦāĻ GCS-āĻ āĻāĻĒāϞā§āĻĄ āĻāϰā§āĨ¤
multimedia_agent.py āĻĢāĻžāĻāϞā§, # TODO: REPLACE_UPLOAD_AGENT āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āĻā§āĻāĻā§āύāĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
upload_agent = LlmAgent(
name="UploadAgent",
model="gemini-2.5-flash",
instruction="""Extract the file path from the user's message and upload it.
Use `upload_media(file_path, survivor_id)` to upload the file.
The survivor_id is optional - include it if the user mentions a specific survivor (e.g., "survivor Sarah" -> "Sarah").
If the user provides a path like "/path/to/file", use that.
Return the upload result with gcs_uri and media_type.""",
tools=[upload_media],
output_key="upload_result"
)
ā§Š. āύāĻŋāώā§āĻāĻžāĻļāύ āĻāĻā§āύā§āĻā§āϰ āϏāĻāĻā§āĻāĻž āĻĻāĻžāĻ
āĻāĻ āĻāĻā§āύā§āĻ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž āĻŽāĻŋāĻĄāĻŋāϝāĻŧāĻž "āĻĻā§āĻā§" āĻāĻŦāĻ āĻā§āĻŽāĻŋāύāĻŋ āĻāĻŋāĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰā§āĻĄ āĻĄā§āĻāĻž āĻŦā§āϰ āĻāϰā§āĨ¤
multimedia_agent.py āĻĢāĻžāĻāϞā§, # TODO: REPLACE_EXTRACT_AGENT āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āĻā§āĻāĻā§āύāĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
extraction_agent = LlmAgent(
name="ExtractionAgent",
model="gemini-2.5-flash",
instruction="""Extract information from the uploaded media.
Previous step result: {upload_result}
Use `extract_from_media(gcs_uri, media_type, signed_url)` with the values from the upload result.
The gcs_uri is in upload_result['gcs_uri'], media_type in upload_result['media_type'], and signed_url in upload_result['signed_url'].
Return the extraction results including entities and relationships found.""",
tools=[extract_from_media],
output_key="extraction_result"
)
āϞāĻā§āώā§āϝ āĻāϰā§āύ āĻāĻŋāĻāĻžāĻŦā§ instruction {upload_result} āĻāϞā§āϞā§āĻ āĻāϰ⧠â ADK-āϤ⧠āĻāĻā§āύā§āĻāĻĻā§āϰ āĻŽāϧā§āϝ⧠āĻāĻāĻāĻžāĻŦā§ āĻ
āĻŦāϏā§āĻĨāĻž āĻĒā§āϰā§āϰāĻŖ āĻāϰāĻž āĻšāϝāĻŧ āĨ¤
ā§Ē. āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻāĻā§āύā§āĻā§āϰ āϏāĻāĻā§āĻāĻž āĻĻāĻžāĻ
āĻāĻ āĻāĻā§āύā§āĻāĻāĻŋ āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ āĻāϰāĻž āϏāϤā§āϤāĻž āĻāĻŦāĻ āϏāĻŽā§āĻĒāϰā§āĻāĻā§āϞāĻŋāĻā§ āĻā§āϰāĻžāĻĢ āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤
multimedia_agent.py āĻĢāĻžāĻāϞā§, āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ # TODO: REPLACE_SPANNER_AGENT āĻā§āĻāĻā§āύāĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
spanner_agent = LlmAgent(
name="SpannerAgent",
model="gemini-2.5-flash",
instruction="""Save the extracted information to the database.
Upload result: {upload_result}
Extraction result: {extraction_result}
Use `save_to_spanner(extraction_result, survivor_id)` to save to Spanner.
Pass the WHOLE `extraction_result` object/dict from the previous step.
Include survivor_id if it was provided in the upload step.
Return the save statistics.""",
tools=[save_to_spanner],
output_key="spanner_result"
)
āĻāĻ āĻāĻā§āύā§āĻāĻāĻŋ āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āĻāĻāϝāĻŧ āϧāĻžāĻĒ ( upload_result āĻāĻŦāĻ extraction_result ) āĻĨā§āĻā§ āĻĒā§āϰāϏāĻā§āĻ āĻā§āϰāĻšāĻŖ āĻāϰā§āĨ¤
ā§Ģ. āϏāĻžāϰāĻžāĻāĻļ āĻāĻā§āύā§āĻ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰā§āύ
āĻāĻ āĻāĻā§āύā§āĻāĻāĻŋ āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āϏāĻŽāϏā§āϤ āĻĒāĻĻāĻā§āώā§āĻĒā§āϰ āĻĢāϞāĻžāĻĢāϞāĻā§āϞāĻŋāĻā§ āĻāĻāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§-āĻŦāĻžāύā§āϧāĻŦ āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻžāϝāĻŧ āϏāĻāĻļā§āϞā§āώāĻŋāϤ āĻāϰā§āĨ¤
multimedia_agent.py āĻĢāĻžāĻāϞā§, āĻŽāύā§āϤāĻŦā§āϝ summary_instruction="" # TODO: REPLACE_SUMMARY_AGENT_PROMPT āĨ¤
āĻāĻ āĻĒā§āϰ⧠āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
USE_MEMORY_BANK = os.getenv("USE_MEMORY_BANK", "false").lower() == "true"
save_msg = "6. Mention that the data is also being synced to the memory bank." if USE_MEMORY_BANK else ""
summary_instruction = f"""Provide a user-friendly summary of the media processing.
Upload: {{upload_result}}
Extraction: {{extraction_result}}
Database: {{spanner_result}}
Summarize:
1. What file was processed (name and type)
2. Key information extracted (survivors, skills, needs, resources found) - list names and counts
3. Relationships identified
4. What was saved to the database (broadcast ID, number of entities)
5. Any issues encountered
{save_msg}
Be concise but informative."""
āĻāĻ āĻāĻā§āύā§āĻā§āϰ āĻā§āύāĻ āϏāϰāĻā§āĻāĻžāĻŽā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻ - āĻāĻāĻŋ āĻā§āĻŦāϞ āĻāĻžāĻ āĻāϰāĻž āĻĒā§āϰāϏāĻā§āĻāĻāĻŋ āĻĒāĻĄāĻŧā§ āĻāĻŦāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻĒāϰāĻŋāώā§āĻāĻžāϰ āϏāĻžāϰāĻžāĻāĻļ āϤā§āϰāĻŋ āĻāϰā§āĨ¤
đ§ āϏā§āĻĨāĻžāĻĒāϤā§āϝā§āϰ āϏāĻžāϰāĻžāĻāĻļ
āϏā§āϤāϰ | āĻĢāĻžāĻāϞ | āĻĻāĻžāϝāĻŧāĻŋāϤā§āĻŦ |
āĻā§āϞāĻŋāĻ | | āĻāĻŋāĻāĻžāĻŦā§ â āĻāĻĒāϞā§āĻĄ, āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ, āϏāĻāϰāĻā§āώāĻŖ |
āĻāĻā§āύā§āĻ | | āĻā§ â āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āϏāĻžāĻāĻžāύ⧠|
ā§§ā§§. āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĄā§āĻāĻž āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ â āĻ āϰā§āĻā§āϏā§āĻā§āϰā§āĻļāύ
āĻāĻŽāĻžāĻĻā§āϰ āύāϤā§āύ āϏāĻŋāϏā§āĻā§āĻŽā§āϰ āĻŽā§āϞ āĻšāϞ⧠backend/agent/multimedia_agent.py āϤ⧠āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ MultimediaExtractionPipeline āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĨ¤ āĻāĻāĻŋ ADK (āĻāĻā§āύā§āĻ āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻ āĻāĻŋāĻ) āĻĨā§āĻā§ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏāĻŋāϝāĻŧāĻžāϞ āĻāĻā§āύā§āĻ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤
ā§§. āĻā§āύ āϏāĻŋāĻā§ā§ā§āύāĻļāĻŋā§āĻžāϞ?
āĻāĻĒāϞā§āĻĄ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāϰāĻŖ āĻāĻāĻāĻŋ āϰā§āĻāĻŋāĻ āύāĻŋāϰā§āĻāϰāϤāĻž āĻļā§āĻā§āĻāϞ:
- āĻĢāĻžāĻāϞ (āĻāĻĒāϞā§āĻĄ) āύāĻž āĻĒāĻžāĻāϝāĻŧāĻž āĻĒāϰā§āϝāύā§āϤ āĻāĻĒāύāĻŋ āĻĄā§āĻāĻž āĻŦā§āϰ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āύāĻžāĨ¤
- āĻāĻĒāύāĻŋ āĻĄā§āĻāĻž āĻāĻā§āϏāĻā§āϰāĻžāĻā§āĻ āύāĻž āĻāϰāĻž āĻĒāϰā§āϝāύā§āϤ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āύāĻž (āĻāĻā§āϏāĻā§āϰāĻžāĻāĻļāύ)āĨ¤
- āĻĢāϞāĻžāĻĢāϞ āύāĻž āĻĒāĻžāĻā§āĻž āĻĒāϰā§āϝāύā§āϤ āϤā§āĻŽāĻŋ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§ āύāĻž (āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§)āĨ¤
āĻāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ SequentialAgent āĻāĻĒāϝā§āĻā§āϤāĨ¤ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻāĻā§āύā§āĻā§āϰ āĻāĻāĻāĻĒā§āĻāĻā§ āĻĒā§āϰāϏāĻā§āĻ/āĻāύāĻĒā§āĻ āĻšāĻŋāϏā§āĻŦā§ āĻ
āύā§āϝ āĻāĻā§āύā§āĻā§ āĻĒā§āϰā§āϰāĻŖ āĻāϰā§āĨ¤
2. āĻāĻā§āύā§āĻā§āϰ āϏāĻāĻā§āĻāĻž
āĻāϞā§āύ āĻĻā§āĻāĻŋ āĻāĻŋāĻāĻžāĻŦā§ multimedia_agent.py āĻāϰ āύā§āĻā§ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύāĻāĻŋ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰāĻž āĻšāϝāĻŧ: đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/multimedia_agent.py
āĻāĻāĻŋ āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āĻĻā§āĻāĻŋ āϧāĻžāĻĒ āĻĨā§āĻā§ āĻāύāĻĒā§āĻ āĻā§āϰāĻšāĻŖ āĻāϰā§āĨ¤ āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āĻā§āĻāĻā§āύ # TODO: REPLACE_ORCHESTRATION āĨ¤ āĻāĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
sub_agents=[upload_agent, extraction_agent, spanner_agent, summary_agent]
ā§Š. āϰā§āĻ āĻāĻā§āύā§āĻā§āϰ āϏāĻžāĻĨā§ āϏāĻāϝā§āĻ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/agent.py
āĻŽāύā§āϤāĻŦā§āϝāĻāĻŋ āϏāύāĻžāĻā§āϤ āĻāϰā§āύ # TODO: REPLACE_ADD_SUBAGENT āĨ¤ āĻāĻ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϞāĻžāĻāύāĻāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰā§āύ :
sub_agents=[multimedia_agent],
āĻāĻ āĻāĻāĻ āĻŦāϏā§āϤ⧠āĻāĻžāϰā§āϝāĻāϰāĻāĻžāĻŦā§ āĻāĻžāϰāĻāύ "āĻŦāĻŋāĻļā§āώāĻā§āĻ" āĻā§ āĻāĻāĻāĻŋ āĻāϞāϝā§āĻā§āϝ āϏāϤā§āϤāĻžāϝāĻŧ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§āĨ¤
ā§Ē. āĻāĻā§āύā§āĻāĻĻā§āϰ āĻŽāϧā§āϝ⧠āϤāĻĨā§āϝ āĻĒā§āϰāĻŦāĻžāĻš
āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāĻā§āύā§āĻ āϤāĻžāϰ āĻāĻāĻāĻĒā§āĻ āĻāĻāĻāĻŋ āĻāĻžāĻ āĻāϰāĻž āĻĒā§āϰāϏāĻā§āĻā§ āϏāĻāϰāĻā§āώāĻŖ āĻāϰ⧠āϝāĻž āĻĒāϰāĻŦāϰā§āϤ⧠āĻāĻā§āύā§āĻāϰāĻž āĻ ā§āϝāĻžāĻā§āϏā§āϏ āĻāϰāϤ⧠āĻĒāĻžāϰā§:

ā§Ģ. āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻā§āϞā§āύ (āĻ ā§āϝāĻžāĻĒāĻāĻŋ āĻāĻāύāĻ āĻāĻžāϞ⧠āĻĨāĻžāĻāϞ⧠āĻāĻĄāĻŧāĻŋāϝāĻŧā§ āϝāĻžāύ)
đđģ āĻ ā§āϝāĻžāĻĒ āĻļā§āϰ⧠āĻāϰā§āύ:
cd ~/way-back-home/level_2/
./start_app.sh
đ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻĨā§āĻā§ Local: http://localhost:5173/ āĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύāĨ¤
ā§Ŧ. āĻĒāϰā§āĻā§āώāĻžāĻŽā§āϞāĻ āĻāĻŦāĻŋ āĻāĻĒāϞā§āĻĄ
đ āĻā§āϝāĻžāĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏā§, āĻāĻāĻžāύ āĻĨā§āĻā§ āϝā§āĻā§āύ⧠āĻāĻāĻāĻŋ āĻāĻŦāĻŋ āĻŦā§āĻā§ āύāĻŋāύ āĻāĻŦāĻ UI āϤ⧠āĻāĻĒāϞā§āĻĄ āĻāϰā§āύ:
- āĻĒāϰā§āĻā§āώāĻž_āĻāĻŦāĻŋ ā§§,
- āĻĒāϰā§āĻā§āώāĻž_āĻāĻŦāĻŋ ⧍,
- āĻĒāϰā§āĻā§āώāĻž_āĻāĻŦāĻŋā§Š ,
- āĻĒāϰā§āĻā§āώāĻž_āĻāĻŦāĻŋā§Ē
āĻā§āϝāĻžāĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏā§, āĻāĻā§āύā§āĻāĻā§ āĻāĻĒāύāĻžāϰ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻĒā§āϰā§āĻā§āώāĻžāĻĒāĻ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻŦāϞā§āύ:
Here is the survivor note
āĻāĻŦāĻ āϤāĻžāϰāĻĒāϰ āĻāĻŦāĻŋāĻāĻŋ āĻāĻāĻžāύ⧠āϏāĻāϝā§āĻā§āϤ āĻāϰā§āύāĨ¤


đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻĒāϰā§āĻā§āώāĻž āĻļā§āώ āĻšāϞā§, āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāĻŋ āĻļā§āώ āĻāϰāϤ⧠"Ctrl+C" āĻāĻŋāĻĒā§āύāĨ¤
6. Verify Multimodal Uploading in GCS Bucket
- Open the Google Cloud Console Storage .
- Select "bucket" in cloud storage

- Select your bucket and click into
media.

- View your uploaded image here.

7. Verify Multimodal Uploading in Spanner (Optional)
Below is example output in UI for test_photo1 .
- Open the Google Cloud Console Spanner .
- Select your instance:
Survivor Network - Select your database:
graph-db - In the left sidebar, click Spanner Studio
đ In Spanner Studio, query the new data:
SELECT
s.name AS Survivor,
s.role AS Role,
b.name AS Biome,
r.name AS FoundResource,
s.created_at
FROM Survivors s
LEFT JOIN SurvivorInBiome sib ON s.survivor_id = sib.survivor_id
LEFT JOIN Biomes b ON sib.biome_id = b.biome_id
LEFT JOIN SurvivorFoundResource sfr ON s.survivor_id = sfr.survivor_id
LEFT JOIN Resources r ON sfr.resource_id = r.resource_id
ORDER BY s.created_at DESC;
We can verify it by see the result below:

12. Memory Bank with Agent Engine
1. How Memory Works
The system uses a dual-memory approach to handle both immediate context and long-term learning.

2. What Are Memory Topics?
Memory Topics define the categories of information the agent should remember across conversations. Think of them as filing cabinets for different types of user preferences.
Our 2 Topics:
-
search_preferences: How the user likes to search- Do they prefer keyword or semantic search?
- What skills/biomes do they search for often?
- Example memory: "User prefers semantic search for medical skills"
-
urgent_needs_context: What crises they're tracking- What resources are they monitoring?
- Which survivors are they concerned about?
- Example memory: "User is tracking medicine shortage in Northern Camp"
3. Setting Up Memory Topics
Custom memory topics define what the agent should remember. These are configured when deploying the Agent Engine.
đđģ In the terminal, open the file in the Cloud Shell Editor by running:
cloudshell edit ~/way-back-home/level_2/backend/deploy_agent.py
This opens ~/way-back-home/level_2/backend/deploy_agent.py in your editor.
We define structure MemoryTopic objects to guide the LLM on what information to extract and save.
đIn the file deploy_agent.py , replace the # TODO: SET_UP_TOPIC with the following:
# backend/deploy_agent.py
custom_topics = [
# Topic 1: Survivor Search Preferences
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="search_preferences",
description="""Extract the user's preferences for how they search for survivors. Include:
- Preferred search methods (keyword, semantic, direct lookup)
- Common filters used (biome, role, status)
- Specific skills they value or frequently look for
- Geographic areas of interest (e.g., "forest biome", "mountain outpost")
Example: "User prefers semantic search for finding similar skills."
Example: "User frequently checks for survivors in the Swamp Biome."
""",
)
),
# Topic 2: Urgent Needs Context
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="urgent_needs_context",
description="""Track the user's focus on urgent needs and resource shortages. Include:
- Specific resources they are monitoring (food, medicine, ammo)
- Critical situations they are tracking
- Survivors they are particularly concerned about
Example: "User is monitoring the medicine shortage in the Northern Camp."
Example: "User is looking for a doctor for the injured survivors."
""",
)
)
]
4. Agent Integration
The agent code must be aware of the Memory Bank to save and retrieve information.
đđģ In the terminal, open the file in the Cloud Shell Editor by running:
cloudshell edit ~/way-back-home/level_2/backend/agent/agent.py
This opens ~/way-back-home/level_2/backend/agent/agent.py in your editor.
Agent Creation
When creating the agent, we pass the after_agent_callback to ensure sessions are saved to memory after interactions. The add_session_to_memory function runs asynchronously to avoid slowing down the chat response.
đIn the file agent.py , locate the comment # TODO: REPLACE_ADD_SESSION_MEMORY , Replace this whole line with the following code:
async def add_session_to_memory(
callback_context: CallbackContext
) -> Optional[types.Content]:
"""Automatically save completed sessions to memory bank in the background"""
if hasattr(callback_context, "_invocation_context"):
invocation_context = callback_context._invocation_context
if invocation_context.memory_service:
# Use create_task to run this in the background without blocking the response
asyncio.create_task(
invocation_context.memory_service.add_session_to_memory(
invocation_context.session
)
)
logger.info("Scheduled session save to memory bank in background")
Background Saving
đIn the file agent.py , locate the comment # TODO: REPLACE_ADD_MEMORY_BANK_TOOL , Replace this whole line with the following code:
if USE_MEMORY_BANK:
agent_tools.append(PreloadMemoryTool())
đIn the file agent.py , locate the comment # TODO: REPLACE_ADD_CALLBACK , Replace this whole line with the following code:
after_agent_callback=add_session_to_memory if USE_MEMORY_BANK else None
Set Up Vertex AI Session Service
đđģ In the terminal, open the file chat.py in the Cloud Shell Editor by running:
cloudshell edit ~/way-back-home/level_2/backend/api/routes/chat.py
đIn chat.py file, locate the comment # TODO: REPLACE_VERTEXAI_SERVICES , Replace this whole line with the following code:
session_service = VertexAiSessionService(
project=project_id,
location=location,
agent_engine_id=agent_engine_id
)
memory_service = VertexAiMemoryBankService(
project=project_id,
location=location,
agent_engine_id=agent_engine_id
)
4. Setup & Deployment
Before testing the memory features, you need to deploy the agent with the new memory topics and ensure your environment is configured correctly.
We have provided a convenience script to handle this process.
Running the Deployment Script
đđģ In the terminal, run the deployment script:
cd ~/way-back-home/level_2
./deploy_and_update_env.sh
This script performs the following actions:
- Runs
backend/deploy_agent.pyto register the agent and memory topics with Vertex AI. - Captures the new Agent Engine ID .
- Automatically updates your
.envfile withAGENT_ENGINE_ID. - Ensures
USE_MEMORY_BANK=TRUEis set in your.envfile.
[!IMPORTANT] If you make changes to custom_topics in deploy_agent.py , you must re-run this script to update the Agent Engine.
13. Verify Memory Bank with Multimodal Data
You can verify that the memory bank is working by teaching the agent a preference and checking if it persists across sessions.
1. Open the application (Skip this step if your application is already running)
Open the Application again by following the instruction below: If the previous terminal is still running, end it by pressing Ctrls+C .
đđģ Start App:
cd ~/way-back-home/level_2/
./start_app.sh
đ Click Local: http://localhost:5173/ from the terminal.
2. Testing Memory Bank with Text
In the chat interface, tell the agent about your specific context:
"I'm planning a medical rescue mission in the mountains. I need survivors with first aid and climbing skills."
đ Wait ~30 seconds for the memory to process in the background.
2. Start a New Session
Refresh the page to clear the current conversation history (short-term memory).
Ask a question that relies on the context you provided earlier:
"What kind of missions am I interested in?"
Expected Response :
"Based on your previous conversations, you're interested in:
- Medical rescue missions
- Mountain/high-altitude operations
- Skills needed: first aid, climbing
Would you like me to find survivors matching these criteria?"
3. Test with Image Upload
Upload an image, and ask:
remember this
You can choose any of the photo here or your own and upload to the UI:
4. Verify in Vertex AI Agent Engine
Go to Google Cloud Console Agent Engine
- Make sure you select the project from top left project selector:

- Verify the agent engine you just deployed from previous command
use_memory_bank.sh:
Click into the agent engine you just created. - Click the
MemoriesTab in this deployed agent, you can view all the memory here.
đđģ When you finish testing, in you terminal, click "Ctrl + C" to end the process.
đ Congratulations! You just attached the memory bank to your agent!
14. Deploy to Cloud Run
1. Run the Deployment Script
đđģ Run the deployment script:
cd ~/way-back-home/level_2
./deploy_cloud_run.sh
After it successfully deployed, you will have the url, this is deployed url for you! 
đđģ Before you grab the url, grant the permission by running:
source .env && gcloud run services add-iam-policy-binding survivor-frontend --region $REGION --member=allUsers --role=roles/run.invoker && gcloud run services add-iam-policy-binding survivor-backend --region $REGION --member=allUsers --role=roles/run.invoker
Go to the deployed url, and you will see you application live there!
2. Understanding the Build Pipeline
The cloudbuild.yaml file defines the following sequential steps:
- Backend Build : Builds the Docker image from
backend/Dockerfile. - Backend Deploy : Deploys the backend container to Cloud Run.
- Capture URL : Gets the new Backend URL.
- Frontend Build :
- Installs dependencies.
- Builds the React app, injecting
VITE_API_URL=.
- Frontend Image : Builds the Docker image from
frontend/Dockerfile(packaging the static assets). - Frontend Deploy : Deploys the frontend container.
3. Verify Deployment
Once the build completes (check the logs link provided by the script), you can verify:
- Go to the Cloud Run Console .
- Find the
survivor-frontendservice. - Click the URL to open the application.
- Perform a search query to ensure the frontend can talk to the backend.
4. (!ONLY FOR WORKSHOP ATTENDEE) Update your location
đđģ Run the completion script:
cd ~/way-back-home/level_2
./set_level_2.sh
Now open waybackhome.dev , and you will see your location has updated. Congratulations on finishing level 2!

(OPTIONAL) 5. Manual Deployment
If you prefer to run the commands manually or understand the process better, here is how to use cloudbuild.yaml directly.
Writing cloudbuild.yaml
A cloudbuild.yaml file tells Google Cloud Build what steps to execute.
- steps : A list of sequential actions. Each step runs in a container (eg,
docker,gcloud,node,bash). - substitutions : Variables that can be passed at build time (eg,
$_REGION). - workspace : A shared directory where steps can share files (like how we share
backend_url.txt).
Running the Deployment
To deploy manually without the script, use the gcloud builds submit command. You MUST pass the required substitution variables.
# Load your env vars first or replace these values manually
export PROJECT_ID=your-project-id
export REGION=us-central1
gcloud builds submit --config cloudbuild.yaml \
--project "$PROJECT_ID" \
--substitutions _REGION="us-central1",_GOOGLE_API_KEY="",_AGENT_ENGINE_ID="your-agent-id",_USE_MEMORY_BANK="TRUE",_GOOGLE_GENAI_USE_VERTEXAI="TRUE"
15. Conclusion
1. What You've Built
â
Graph Database : Spanner with nodes (survivors, skills) and edges (relationships)
â
AI Search : Keyword, semantic, and hybrid search with embeddings
â
Multimodal Pipeline : Extract entities from images/video with Gemini
â
Multi-Agent System : Coordinated workflow with ADK
â
Memory Bank : Long-term personalization with Vertex AI
â
Production Deployment : Cloud Run + Agent Engine
2. Architecture Summary

3. Key Learnings
- Graph RAG : Combines graph database structure with semantic embeddings for intelligent search
- Multi-Agent Patterns : Sequential pipelines for complex, multi-step workflows
- Multimodal AI : Extract structured data from unstructured media (images/video)
- Stateful Agents : Memory Bank enables personalization across sessions
4. Workshop Content
- Level0 : Identify Yourself
- Level1 : Pinpoint Location
- Level2 This One : Build a Multimodal AI Agent with Graph RAG, ADK & Memory Bank
- Level3 : Building an ADK Bi-Directional Streaming Agent
- Level4 : Live Bidirectional Multi-Agent system
- Level5 : Event-Driven Architecture with Google ADK, A2A, and Kafka