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

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

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

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

- đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āϝāĻžāĻāĻžāĻ āĻāϰā§āύ āϝ⧠āĻāĻĒāύāĻŋ āĻāϤāĻŋāĻŽāϧā§āϝā§āĻ āĻĒā§āϰāĻŽāĻžāĻŖā§āĻā§āϤ āĻāĻŦāĻ āĻĒā§āϰāĻā§āĻā§āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻā§āĻā§āĻ āĻāĻāĻĄāĻŋāϤ⧠āϏā§āĻ āĻāϰāĻž āĻāĻā§:
gcloud auth list - đđģ āĻāĻŋāĻāĻšāĻžāĻŦ āĻĨā§āĻā§ āĻŦā§āĻāϏā§āĻā§āϰā§āϝāĻžāĻĒ āĻĒā§āϰāĻā§āĻā§āĻāĻāĻŋ āĻā§āϞā§āύ āĻāϰā§āύ:
git clone https://github.com/gca-americas/way-back-home.git
āϤā§āϤā§āϝāĻŧ āĻĒāϰā§āĻŦ: āĻāĻāĻāĻŋ āύāϤā§āύ āĻĒā§āϰāĻā§āĻā§āĻ āϤā§āϰāĻŋ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, init āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋāĻā§ āĻāĻā§āϏāĻŋāĻāĻŋāĻāĻā§āĻŦāϞ āĻāϰ⧠āĻāĻžāϞāĻžāύ:
cd ~/way-back-home/level_2
./init.sh
ā§Š. đ ī¸ āĻĒāϰāĻŋāĻŦā§āĻļ āϏā§āĻāĻāĻĒ
ā§§. āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻā§āϞā§āύ
āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āϝāĻĻāĻŋ āϏā§āĻā§āϰāĻŋāύā§āϰ āύā§āĻā§ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞāĻāĻŋ āĻĻā§āĻāĻž āύāĻž āϝāĻžāϝāĻŧ, āϤāĻžāĻšāϞ⧠āĻāĻāĻŋ āĻā§āϞā§āύ:
- āĻāĻŋāĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύ
- āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ

⧍. āĻĒā§āϰāĻā§āĻā§āĻ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰā§āύ
đđģ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āĻāĻĒāύāĻžāϰ āĻĒā§āϰāĻā§āĻā§āĻ āĻāĻāĻĄāĻŋ āϏā§āĻ āĻāϰā§āύ:
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 āĻĒāϰā§āϰ āϞāĻŋāĻā§āĻā§ āĻā§āϞāĻŋāĻ āĻāϰāϞ⧠āĻāĻĒāύāĻŋ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āĻāύāϏā§āϞ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϞāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤

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

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

⧍. āĻā§āϰāĻžāĻĢā§āϰ āĻāĻ āύ āĻŦā§āĻāĻž (āĻŦā§āĻšā§ āĻāĻŋāϤā§āϰ)
āϏāĻžāϰāĻāĻžāĻāĻāĻžāϰ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻ āĻĄā§āĻāĻžāϏā§āĻāĻāĻŋāĻā§ āĻāĻāĻāĻŋ āϞāĻāĻŋāĻ āĻĒāĻžāĻāϞ āĻŦāĻž āĻā§āĻŽ āϏā§āĻā§āĻ āĻšāĻŋāϏā§āĻŦā§ āĻāĻžāĻŦā§āύ:
āϏāϤā§āϤāĻž | āϏāĻŋāϏā§āĻā§āĻŽā§ āĻā§āĻŽāĻŋāĻāĻž | āϏāĻžāĻĻā§āĻļā§āϝ |
āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋāϰāĻž | āĻāĻā§āύā§āĻ/āĻā§āϞā§āϝāĻŧāĻžāĻĄāĻŧāϰāĻž | āĻā§āϞā§āϝāĻŧāĻžāĻĄāĻŧāϰāĻž |
āĻŦāĻžāϝāĻŧā§āĻŽ | āϝā§āĻāĻžāύ⧠āϤāĻžāϰāĻž āĻ āĻŦāϏā§āĻĨāĻŋāϤ | āĻŽāĻžāύāĻāĻŋāϤā§āϰ āĻ āĻā§āĻāϞ |
āĻĻāĻā§āώāϤāĻž | āϤāĻžāϰāĻž āϝāĻž āĻāϰāϤ⧠āĻĒāĻžāϰ⧠| āĻā§āώāĻŽāϤāĻž |
āĻāĻžāĻšāĻŋāĻĻāĻž | āϤāĻžāĻĻā§āϰ āϝāĻž āĻ āĻāĻžāĻŦ (āϏāĻāĻāĻ) | āĻ āύā§āϏāύā§āϧāĻžāύ/āĻ āĻāĻŋāϝāĻžāύ |
āϏāĻŽā§āĻĒāĻĻ | āĻŦāĻŋāĻļā§āĻŦā§ āĻĒāĻžāĻāϝāĻŧāĻž āĻāĻŋāύāĻŋāϏāĻĒāϤā§āϰ | āϞā§āĻ |
āϞāĻā§āώā§āϝ : āĻāĻāĻ āĻāĻā§āύā§āĻā§āϰ āĻāĻžāĻ āĻšāϞ⧠āĻŦāĻžāϝāĻŧā§āĻŽ (āĻ āĻŦāϏā§āĻĨāĻžāύāĻāϤ āϏā§āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž) āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰ⧠āĻĻāĻā§āώāϤāĻž (āϏāĻŽāĻžāϧāĻžāύ)-āĻā§ āĻāĻžāĻšāĻŋāĻĻāĻž (āϏāĻŽāϏā§āϝāĻž)-āϰ āϏāĻžāĻĨā§ āϏāĻāϝā§āĻā§āϤ āĻāϰāĻžāĨ¤
đ āĻĒā§āϰāĻžāύā§āϤ (āϏāĻŽā§āĻĒāϰā§āĻ):
-
SurvivorInBiome: āĻ āĻŦāϏā§āĻĨāĻžāύ āĻā§āϰā§āϝāĻžāĻāĻŋāĻ -
SurvivorHasSkill: āĻĻāĻā§āώāϤāĻžāϰ āϤāĻžāϞāĻŋāĻāĻž -
SurvivorHasNeed: āϏāĻā§āϰāĻŋāϝāĻŧ āϏāĻŽāϏā§āϝāĻžāĻā§āϞāĻŋāϰ āϤāĻžāϞāĻŋāĻāĻž -
SurvivorFoundResource: āĻāĻŋāύāĻŋāϏāĻĒāϤā§āϰā§āϰ āϤāĻžāϞāĻŋāĻāĻž -
SurvivorCanHelp: āĻ āύā§āĻŽāĻŋāϤ āϏāĻŽā§āĻĒāϰā§āĻ (āĻāĻāĻ āĻāĻāĻŋ āĻāĻŖāύāĻž āĻāϰā§!)
ā§Š. āĻā§āϰāĻžāĻĢ āĻ āύā§āϏāύā§āϧāĻžāύ āĻāϰāĻž
āĻĄā§āĻāĻžāϰ āĻŽāϧā§āϝ⧠'Story' āĻĻā§āĻāϤ⧠āĻāϞā§āύ āĻāϝāĻŧā§āĻāĻāĻŋ āĻā§āϝāĻŧā§āϰāĻŋ āĻāĻžāϞāĻžāύ⧠āϝāĻžāĻāĨ¤
āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ 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!
'āĻŽā§āĻĄāĻŋāĻ' āĻāϰ āĻāύā§āϝ āĻĒā§āϰāĻāϞāĻŋāϤ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻ āύā§āϏāύā§āϧāĻžāύ â ā§ĻāĻāĻŋ āĻĢāϞāĻžāĻĢāϞ â
āĻāĻŽāĻŦā§āĻĄāĻŋāĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ â 'āĻŽā§āĻĄāĻŋāĻā§āϞ āĻā§āϰā§āύāĻŋāĻ', 'āĻĢāĻžāϰā§āϏā§āĻ āĻāĻāĻĄ' āĻā§āĻāĻā§ āĻĒāĻžāĻāϝāĻŧāĻž āĻā§āĻā§ â
āĻāĻā§āύā§āĻāĻĻā§āϰ āĻ āĻŋāĻ āĻāĻāĻžāĻ āĻĒā§āϰāϝāĻŧā§āĻāύ: āĻŦā§āĻĻā§āϧāĻŋāĻĻā§āĻĒā§āϤ, āĻŽāĻžāύā§āώā§āϰ āĻŽāϤ⧠āĻ āύā§āϏāύā§āϧāĻžāύ āĻŦā§āϝāĻŦāϏā§āĻĨāĻž āϝāĻž āĻļā§āϧ⧠āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āύāϝāĻŧ, āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāĻĻā§āĻĻā§āĻļā§āϝāĻ āĻŦā§āĻā§āĨ¤
⧍. āĻāĻŽāĻŦā§āĻĄāĻŋāĻ āĻŽāĻĄā§āϞ āϤā§āϰāĻŋ āĻāϰā§āύ

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

đ āύāĻŋāĻā§āϰ āĻā§āϝāĻŧā§āϰāĻŋāĻāĻŋ āĻāĻĒāĻŋ āĻāϰ⧠āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āϏā§āĻā§āĻĄāĻŋāĻāϤ⧠āĻĒā§āϏā§āĻ āĻāϰā§āύ āĻāĻŦāĻ āϤāĻžāϰāĻĒāϰ āϰāĻžāύ āĻŦāĻžāĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ:
CREATE OR REPLACE 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'
);
āĻāĻāĻŋ āϝāĻž āĻāϰ⧠:
- āϏā§āĻĒā§āϝāĻžāύāĻžāϰ⧠āĻāĻāĻāĻŋ āĻāĻžāϰā§āĻā§āϝāĻŧāĻžāϞ āĻŽāĻĄā§āϞ āϤā§āϰāĻŋ āĻāϰ⧠(āĻŽāĻĄā§āϞā§āϰ āĻā§āύ⧠āĻāϝāĻŧā§āĻ āϏā§āĻĨāĻžāύā§āϝāĻŧāĻāĻžāĻŦā§ āϏāĻāϰāĻā§āώāĻŋāϤ āĻĨāĻžāĻā§ āύāĻž)
- āĻāĻžāϰā§āĻā§āĻā§āϏ āĻāĻāĻ-āϤ⧠āĻā§āĻāϞā§āϰ
text-embedding-004āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰā§āĨ¤ - āĻā§āĻā§āϤāĻŋāĻāĻŋ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰā§: āĻāύāĻĒā§āĻ āĻšāϞ⧠āĻā§āĻā§āϏāĻ, āĻāĻāĻāĻĒā§āĻ āĻšāϞ⧠āĻāĻāĻāĻŋ ā§ā§Ŧā§Ž-āĻŽāĻžāϤā§āϰāĻžāϰ āĻĢā§āϞā§āĻ āĻ ā§āϝāĻžāϰā§āĨ¤
"āϰāĻŋāĻŽā§āĻ āĻ āĻĒāĻļāύ" āĻā§āύ?
- āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āύāĻŋāĻā§ āĻŽāĻĄā§āϞāĻāĻŋ āĻāĻžāϞāĻžāϝāĻŧ āύāĻžāĨ¤
- āĻāĻĒāύāĻŋ āϝāĻāύ
ML.PREDICTāĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ, āϤāĻāύ āĻāĻāĻŋ API-āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ Vertex AI-āĻā§ āĻāϞ āĻāϰā§āĨ¤ - āĻāĻŋāϰā§-āĻāĻāĻŋāĻāϞ : āĻĄā§āĻāĻž āĻĒāĻžāĻāĻĨāύ⧠āĻāĻā§āϏāĻĒā§āϰā§āĻ, āĻĒā§āϰāϏā§āϏ āĻāĻŦāĻ āĻĒā§āύāϰāĻžāϝāĻŧ āĻāĻŽā§āĻĒā§āϰā§āĻ āĻāϰāĻžāϰ āĻā§āύ⧠āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻāĨ¤
Run āĻŦāĻžāĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ, āĻāĻāĻŋ āϏāĻĢāϞ āĻšāϞ⧠āĻāĻĒāύāĻŋ āύā§āĻā§āϰ āĻŽāϤ⧠āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ:

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

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

āϝāĻž āĻāĻā§ : āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻĻāĻā§āώāϤāĻžāϰ āύāĻžāĻŽ (āϝā§āĻŽāύ, "āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž") āϤāĻžāϰ āĻ āϰā§āĻĨāĻāϤ āϤāĻžā§āĻĒāϰā§āϝ āĻĒā§āϰāĻāĻžāĻļāĻāĻžāϰ⧠āĻāĻāĻāĻŋ ā§ā§Ŧā§Ž-āĻŽāĻžāϤā§āϰāĻžāϰ āĻā§āĻā§āĻāϰ⧠āϰā§āĻĒāĻžāύā§āϤāϰāĻŋāϤ āĻšāϝāĻŧāĨ¤
ā§Ģ. āĻāĻŽāĻŦā§āĻĄāĻŋāĻ āϝāĻžāĻāĻžāĻ āĻāϰā§āύ
đ āĻāĻŽāĻŦā§āĻĄāĻŋāĻāĻā§āϞ⧠āϤā§āϰāĻŋ āĻšāϝāĻŧā§āĻā§ āĻāĻŋāύāĻž āϤāĻž āϝāĻžāĻāĻžāĻ āĻāϰā§āύ:
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 OR REPLACE 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) āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰāĻŦā§āύ â āĻ āϰā§āĻĨāĻžā§ āĻļā§āϧ⧠āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āύāϝāĻŧ, āĻ āϰā§āĻĨā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§āĻ āĻĢāϞāĻžāĻĢāϞ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰāĻŦā§āύāĨ¤ āĻĒāϰāĻŦāϰā§āϤā§āϤā§, āĻāĻŽāϰāĻž āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰāĻŦ āĻā§āĻāĻžāĻŦā§ āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āϏāĻžāϰā§āĻ āĻāĻāĻžāϧāĻŋāĻ āĻĒāĻĻā§āϧāϤāĻŋāĻā§ āĻāĻāϤā§āϰāĻŋāϤ āĻāϰā§āĨ¤
⧍. 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 Web āĻĻāĻŋāϝāĻŧā§ āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻ āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻž
āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻ āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻžāϰ āϏāĻŦāĻā§āϝāĻŧā§ āϏāĻšāĻ āĻāĻĒāĻžāϝāĻŧ āĻšāϞ⧠` adk web āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž, āϝāĻž āĻāĻāĻāĻŋ āĻ
āύā§āϤāϰā§āύāĻŋāϰā§āĻŽāĻŋāϤ āĻā§āϝāĻžāĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏ āϏāĻš āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻāĻā§ āĻāĻžāϞ⧠āĻāϰā§āĨ¤
ā§§. āĻāĻā§āύā§āĻ āĻāĻžāϞāĻžāύā§
đđģ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āĻĄāĻŋāϰā§āĻā§āĻāϰāĻŋāϤ⧠(āϝā§āĻāĻžāύ⧠āĻāĻĒāύāĻžāϰ āĻāĻā§āύā§āĻ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰāĻž āĻāĻā§) āϝāĻžāύ āĻāĻŦāĻ āĻāϝāĻŧā§āĻŦ āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ āĻāĻžāϞ⧠āĻāϰā§āύ::
cd ~/way-back-home/level_2/backend
uv run adk web
āĻāĻ āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻāĻā§āύā§āĻ āĻāĻžāϞ⧠āĻāϰ⧠āϝāĻž āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§
agent/agent.py
āĻāĻŦāĻ āĻĒāϰā§āĻā§āώāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻāϝāĻŧā§āĻŦ āĻāύā§āĻāĻžāϰāĻĢā§āϏ āĻā§āϞā§āĨ¤
đ āĻāĻāĻāϰāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
āĻāĻ āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻāĻāĻāĻŋ āϏā§āĻĨāĻžāύā§āϝāĻŧ āĻāĻāĻāϰāĻāϞ (āϏāĻžāϧāĻžāϰāĻŖāϤ http://127.0.0.1:8000 āĻŦāĻž āĻāĻ āĻāĻžāϤā§āϝāĻŧ) āĻāĻāĻāĻĒā§āĻ āĻšāĻŋāϏā§āĻŦā§ āĻĻā§āĻŦā§āĨ¤ āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻŦā§āϰāĻžāĻāĻāĻžāϰ⧠āĻā§āϞā§āύāĨ¤

āĻāĻāĻāϰāĻāϞ-āĻāĻŋāϤ⧠āĻā§āϞāĻŋāĻ āĻāϰāϞ⧠āĻāĻĒāύāĻŋ āĻāĻĄāĻŋāĻā§ āĻāϝāĻŧā§āĻŦ āĻāĻāĻāĻ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύāĨ¤ āĻāĻĒāϰā§āϰ āĻŦāĻžāĻŽ āĻā§āĻŖ āĻĨā§āĻā§ 'āĻāĻā§āύā§āĻ' āύāĻŋāϰā§āĻŦāĻžāĻāύ āĻāϰāϤ⧠āĻā§āϞāĻŦā§āύ āύāĻžāĨ¤

⧍. āĻ āύā§āϏāύā§āϧāĻžāύ āĻā§āώāĻŽāϤāĻž āĻĒāϰā§āĻā§āώāĻž āĻāϰāĻž
āĻāĻā§āύā§āĻāĻāĻŋ āĻāĻĒāύāĻžāϰ āĻ āύā§āϏāύā§āϧāĻžāύāĻā§āϞā§āĻā§ āĻŦā§āĻĻā§āϧāĻŋāĻŽāϤā§āϤāĻžāϰ āϏāĻžāĻĨā§ āϏāĻ āĻŋāĻ āĻĒāĻĨā§ āĻāĻžāϞāĻŋāϤ āĻāϰāĻžāϰ āĻāύā§āϝ āĻĄāĻŋāĻāĻžāĻāύ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤ āĻŦāĻŋāĻāĻŋāύā§āύ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāĻĻā§āϧāϤāĻŋ āĻŦāĻžāϏā§āϤāĻŦā§ āĻĻā§āĻāϤ⧠āĻā§āϝāĻžāĻ āĻāĻāύā§āĻĄā§āϤ⧠āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāύāĻĒā§āĻāĻā§āϞ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻĻā§āĻā§āύāĨ¤
đ§Ŧ āĻ. āĻā§āϰāĻžāĻĢ āϰâā§āϝāĻžāĻ (āϏāĻŋāĻŽāĻžāύā§āĻāĻŋāĻ āϏāĻžāϰā§āĻ)
āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āύāĻž āĻŽāĻŋāϞāϞā§āĻ āĻ āϰā§āĻĨ āĻ āϧāĻžāϰāĻŖāĻžāϰ āĻāĻŋāϤā§āϤāĻŋāϤ⧠āĻāĻāĻā§āĻŽ āĻā§āĻāĻā§ āĻŦā§āϰ āĻāϰā§āĨ¤
āĻĒāϰā§āĻā§āώāĻžāϰ āĻāύā§āϝ āĻĒā§āϰāĻļā§āύ: (āύā§āĻā§āϰ āϝā§āĻā§āύ āĻāĻāĻāĻŋ āĻŦā§āĻā§ āύāĻŋāύ)
Who can help with injuries?
What abilities are related to survival?
āĻā§ āĻā§ āĻĻā§āĻāϤ⧠āĻšāĻŦā§:
- āϝā§āĻā§āϤāĻŋāϤ⧠āϏāĻŋāĻŽāĻžāύā§āĻāĻŋāĻ āĻŦāĻž āϰâā§āϝāĻžāĻ āϏāĻžāϰā§āĻā§āϰ āĻāϞā§āϞā§āĻ āĻĨāĻžāĻāĻž āĻāĻāĻŋāϤāĨ¤
- āĻāĻĒāύāĻžāϰ āĻāĻŽāύ āĻĢāϞāĻžāĻĢāϞ āĻĻā§āĻāĻž āĻāĻāĻŋāϤ āϝāĻž āϧāĻžāϰāĻŖāĻžāĻāϤāĻāĻžāĻŦā§ āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ (āϝā§āĻŽāύ, "āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ āĻāĻŋāĻāĻŋā§āϏāĻž" āĻāĻŋāĻā§āĻāĻžāϏāĻž āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ "āϏāĻžāϰā§āĻāĻžāϰāĻŋ")āĨ¤
- āĻĢāϞāĻžāĻĢāϞ⧠đ§Ŧ āĻāĻāĻāύāĻāĻŋ āĻĨāĻžāĻāĻŦā§āĨ¤
đ āĻ. āĻšāĻžāĻāĻŦā§āϰāĻŋāĻĄ āϏāĻžāϰā§āĻ
āĻāĻāĻŋāϞ āĻā§āϝāĻŧā§āϰāĻŋāϰ āĻāύā§āϝ āĻā§āĻāϝāĻŧāĻžāϰā§āĻĄ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāĻŦāĻ āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻāϤ āĻāĻĒāϞāĻŦā§āϧāĻŋāϰ āϏāĻŽāύā§āĻŦāϝāĻŧ āĻāĻāĻžāϝāĻŧāĨ¤
āĻĒāϰā§āĻā§āώāĻžāϰ āĻāύā§āϝ āĻĒā§āϰāĻļā§āύ: (āύā§āĻā§āϰ āϝā§āĻā§āύ āĻāĻāĻāĻŋ āĻŦā§āĻā§ āύāĻŋāύ)
Find someone who can fly 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"
)
ā§§. āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻļā§āϰ⧠āĻāϰā§āύ
āϝāĻĻāĻŋ āĻāĻā§āϰ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞāĻāĻŋ āĻāĻāύāĻ āĻāĻžāϞ⧠āĻĨāĻžāĻā§, āϤāĻžāĻšāϞ⧠Ctrl+C āĻā§āĻĒā§ āϏā§āĻāĻŋ āĻŦāύā§āϧ āĻāϰā§āύāĨ¤
đđģ āĻ ā§āϝāĻžāĻĒāĻāĻŋ āĻāĻžāϞ⧠āĻāϰā§āύ:
cd ~/way-back-home/level_2/
./start_app.sh
āϝāĻāύ āĻŦā§āϝāĻžāĻāĻāύā§āĻĄ āϏāĻĢāϞāĻāĻžāĻŦā§ āĻāĻžāϞ⧠āĻšāĻŦā§, āĻāĻĒāύāĻŋ āύā§āĻā§āϰ āĻŽāϤ⧠Local: http://localhost:5173/" āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ: 
đ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻĨā§āĻā§ Local: http://localhost:5173/ -āĻ āĻā§āϞāĻŋāĻ āĻāϰā§āύāĨ¤

⧍. āĻļāĻŦā§āĻĻāĻžāϰā§āĻĨāĻŋāĻ āĻ āύā§āϏāύā§āϧāĻžāύ āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āύ
āĻĒā§āϰāĻļā§āύ :
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 āĻā§āĻĒā§ āĻāĻāĻŋ āĻŦāύā§āϧ āĻāϰā§āύāĨ¤
ā§Ē. (āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻāϰā§āĻŽāĻļāĻžāϞāĻžāϰ āĻ āĻāĻļāĻā§āϰāĻšāĻŖāĻāĻžāϰā§āĻĻā§āϰ āĻāύā§āϝ) āĻāĻĒāύāĻžāϰ āĻ āĻŦāϏā§āĻĨāĻžāύ āĻšāĻžāϞāύāĻžāĻāĻžāĻĻ āĻāϰā§āύāĨ¤
đđģ āϏāĻŽāĻžāĻĒā§āϤāĻŋ āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻāĻŋ āĻāĻžāϞāĻžāύ:
cd ~/way-back-home/level_2
./set_level_2.sh
āĻāĻāύ waybackhome.dev āĻā§āϞā§āύ, āĻāĻŦāĻ āĻāĻĒāύāĻŋ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦā§āύ āĻāĻĒāύāĻžāϰ āĻ
āĻŦāϏā§āĻĨāĻžāύ āĻāĻĒāĻĄā§āĻ āĻšāϝāĻŧā§ āĻā§āĻā§āĨ¤ āϞā§āĻā§āϞ ⧍ āϏāĻĢāϞāĻāĻžāĻŦā§ āϏāĻŽā§āĻĒāύā§āύ āĻāϰāĻžāϰ āĻāύā§āϝ āĻ
āĻāĻŋāύāύā§āĻĻāύ!

⧝. âī¸ [āĻāĻā§āĻāĻŋāĻ] āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ (āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻĒāĻ āύāϝā§āĻā§āϝ) â āĻā§āϞāĻŋāĻ āϞā§āϝāĻŧāĻžāϰ
āĻāĻŽāĻžāĻĻā§āϰ āĻā§āύ āĻāĻāĻāĻŋ āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ āĻĒā§āϰāϝāĻŧā§āĻāύ?
āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻžāϰ āύā§āĻāĻāϝāĻŧāĻžāϰā§āĻ āĻļā§āϧ⧠āĻā§āĻā§āϏāĻ-āĻāĻŋāϤā§āϤāĻŋāĻ āύāϝāĻŧāĨ¤ āĻŽāĻžāĻ ā§ āĻĨāĻžāĻāĻž āĻŦā§āĻāĻā§ āĻĨāĻžāĻāĻž āĻŦā§āϝāĻā§āϤāĻŋāϰāĻž āϏāϰāĻžāϏāϰāĻŋ āĻā§āϝāĻžāĻā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻ āϏāĻāĻāĻ āĻŋāϤ āĻĄā§āĻāĻž āĻĒāĻžāĻ āĻžāύ:
- đ¸ āĻāĻŦāĻŋ : āϏāĻŽā§āĻĒāĻĻ, āĻŦāĻŋāĻĒāĻĻ āĻŦāĻž āϏāϰāĻā§āĻāĻžāĻŽā§āϰ āĻāĻŦāĻŋ
- đĨ āĻāĻŋāĻĄāĻŋāĻ : āĻ āĻŦāϏā§āĻĨāĻžāϰ āĻĒā§āϰāϤāĻŋāĻŦā§āĻĻāύ āĻŦāĻž āĻāϰā§āϰāĻŋ āϏāĻžāĻšāĻžāϝā§āϝā§āϰ āĻŦāĻžāϰā§āϤāĻž
- đ āĻĒāĻžāĻ ā§āϝ : āĻŽāĻžāĻ ā§āϰ āύā§āĻ āĻŦāĻž āϞāĻ
āĻāĻŽāϰāĻž āĻā§āύ āĻĢāĻžāĻāϞāĻā§āϞ⧠āĻĒā§āϰāϏā§āϏ āĻāϰāĻāĻŋ?
āĻĒā§āϰā§āĻŦāĻŦāϰā§āϤ⧠āϧāĻžāĻĒā§ āĻāĻŽāϰāĻž āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻĄā§āĻāĻž āĻ
āύā§āϏāύā§āϧāĻžāύ āĻāϰāϞā§āĻ, āĻāĻāĻžāύ⧠āĻāĻŽāϰāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž āĻĢāĻžāĻāϞāĻā§āϞ⧠āĻĒā§āϰāϏā§āϏ āĻāϰāĻŋāĨ¤ chat.py āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ āĻĄāĻžāĻāύāĻžāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻĢāĻžāĻāϞ āĻ
ā§āϝāĻžāĻāĻžāĻāĻŽā§āύā§āĻāĻā§āϞ⧠āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰā§:
āĻā§āϏ | āĻŦāĻŋāώāϝāĻŧāĻŦāϏā§āϤ⧠| āϞāĻā§āώā§āϝ |
āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āϏāĻāϝā§āĻā§āϤāĻŋ | āĻāĻŦāĻŋ/āĻāĻŋāĻĄāĻŋāĻ/āϞā§āĻāĻž | āĻā§āϰāĻžāĻĢā§ āϝā§āĻ āĻāϰāĻžāϰ āĻāύā§āϝ āϤāĻĨā§āϝ |
āĻā§āϝāĻžāĻā§āϰ āĻĒā§āϰāϏāĻā§āĻ | āĻāĻ āĻšāϞ⧠āϏāϰāĻŦāϰāĻžāĻšāĻā§āϞā§āϰ āĻāĻāĻāĻŋ āĻāĻŦāĻŋāĨ¤ | āĻāĻĻā§āĻĻā§āĻļā§āϝ āĻāĻŦāĻ āĻ āϤāĻŋāϰāĻŋāĻā§āϤ āĻŦāĻŋāĻŦāϰāĻŖ |
āĻĒāϰāĻŋāĻāϞā§āĻĒāĻŋāϤ āĻĒāĻĻā§āϧāϤāĻŋ: āĻ āύā§āĻā§āϰāĻŽāĻŋāĻ āĻāĻā§āύā§āĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ
āĻāĻŽāϰāĻž āĻāĻāĻāĻŋ āϏāĻŋāĻā§āϝāĻŧā§āύāĻļāĻŋāϝāĻŧāĻžāϞ āĻāĻā§āύā§āĻ ( multimedia_agent.py ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŋ āϝāĻž āĻŦāĻŋāĻļā§āώāĻžāϝāĻŧāĻŋāϤ āĻāĻā§āύā§āĻāĻā§āϞā§āĻā§ āĻāĻāϏāĻžāĻĨā§ āĻļā§āĻā§āĻāϞāĻŋāϤ āĻāϰā§:

āĻāĻāĻŋ backend/agent/multimedia_agent.py āϤ⧠āĻāĻāĻāĻŋ SequentialAgent āĻšāĻŋāϏā§āĻŦā§ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤
āĻā§āϞāĻŋāĻ āϞā§āϝāĻŧāĻžāϰāĻāĻŋ āϏā§āĻāϏāĻŦ āϏāĻā§āώāĻŽāϤāĻž āĻĒā§āϰāĻĻāĻžāύ āĻāϰ⧠āϝāĻž āĻāĻā§āύā§āĻāϰāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§āĨ¤ āĻā§āϞāĻā§āϞ⧠āĻāĻžāϰā§āϝāĻĒāĻĻā§āϧāϤāĻŋ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰ⧠â āϝā§āĻŽāύ āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄ āĻāϰāĻž, āĻāύāĻāĻŋāĻāĻŋ āύāĻŋāώā§āĻāĻžāĻļāύ āĻāϰāĻž āĻāĻŦāĻ āĻĄā§āĻāĻžāĻŦā§āϏ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻžāĨ¤
ā§§. āĻā§āϞāϏ āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ
đđģ level_2/backend/agent/tools/extraction_tools.py āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ āĻ
āĻĨāĻŦāĻž āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻāĻžāĻāĻĒ āĻāϰā§āύāĨ¤ āĻāĻāĻāĻŋ āύāϤā§āύ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻā§āϞā§āύāĨ¤ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ-āĻ āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/tools/extraction_tools.py
⧍. upload_media āĻā§āϞ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰā§āύ
āĻāĻ āĻā§āϞāĻāĻŋ āϏā§āĻĨāĻžāύā§āϝāĻŧ āĻĢāĻžāĻāϞāĻā§ āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϏā§āĻā§āϰā§āĻā§ āĻāĻĒāϞā§āĻĄ āĻāϰā§āĨ¤
đ def upload_media(file_path: str, survivor_id: Optional[str] = None) -> Dict[str, Any]: āĻāϰ āĻŽāϧā§āϝā§, āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄāĻāĻŋ GCS-āĻ āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄ āĻāϰāĻžāϰ āĻĒāĻĻā§āϧāϤāĻŋ āĻāĻŦāĻ āĻĢāĻžāĻāϞā§āϰ āϧāϰāύ āĻļāύāĻžāĻā§āϤ āĻāϰāĻž āϏāĻŽā§āĻĒāϰā§āĻāĻŋāϤ:
"""
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 āĻĒāϰā§āĻā§āώāĻž āĻāϰ⧠āĻāĻŦāĻ āϏāĻ āĻŋāĻ āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻāϰ⧠(āĻā§āĻā§āϏāĻ, āĻāĻŽā§āĻ āĻŦāĻž āĻāĻŋāĻĄāĻŋāĻ) āĻĒā§āϰā§āϰāĻŖ āĻāϰā§āĨ¤
đ async def extract_from_media(gcs_uri: str, media_type: str, signed_url: Optional[str] = None) -> Dict[str, Any]: ` āĻĢāĻžāĻāĻļāύā§āϰ āĻŽāϧā§āϝā§, āĻāĻĒāϞā§āĻĄ āĻāϰāĻž āĻŽāĻŋāĻĄāĻŋāϝāĻŧāĻž āĻĨā§āĻā§ āĻā§āĻāĻžāĻŦā§ āĻāύāĻāĻŋāĻāĻŋ āĻāĻŦāĻ āϰāĻŋāϞā§āĻļāύāĻļāĻŋāĻĒ āĻŦā§āϰ āĻāϰāϤ⧠āĻšāϝāĻŧ, āύāĻŋāĻā§āϰ āĻā§āĻĄāĻāĻŋ āϤāĻž-āĻ āĻĻā§āĻāĻžāϝāĻŧāĨ¤
"""
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)}
āĻŽā§āϞ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻŦāĻŋāĻŦāϰāĻŖ:
- āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻāύāĻĒā§āĻ : āĻāĻŽāϰāĻž
generate_contentāĻĢāĻžāĻāĻļāύ⧠āĻā§āĻā§āϏāĻ āĻĒā§āϰāĻŽā§āĻĒāĻ (_get_extraction_prompt()) āĻāĻŦāĻ āĻāĻŽā§āĻ āĻ āĻŦāĻā§āĻā§āĻ āĻāĻāϝāĻŧāĻ āĻĒāĻžāϏ āĻāϰāĻŋāĨ¤ - āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰā§āĻĄ āĻāĻāĻāĻĒā§āĻ :
response_mime_type="application/json"āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰ⧠āϝ⧠LLM āĻŦā§āϧ JSON āϰāĻŋāĻāĻžāϰā§āύ āĻāϰāĻŦā§, āϝāĻž āĻĒāĻžāĻāĻĒāϞāĻžāĻāύā§āϰ āĻāύā§āϝ āĻ āϤā§āϝāύā§āϤ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖāĨ¤ - āĻāĻžāĻā§āώā§āώ āϏāϤā§āϤāĻž āϏāĻāϝā§āĻ : āĻĒā§āϰāĻŽā§āĻĒāĻāĻāĻŋāϤ⧠āĻĒāϰāĻŋāĻāĻŋāϤ āϏāϤā§āϤāĻž āĻ āύā§āϤāϰā§āĻā§āĻā§āϤ āϰāϝāĻŧā§āĻā§ āϝāĻžāϤ⧠āĻā§āĻŽāĻŋāύāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻ āĻā§āώāϰ āĻāĻŋāύāϤ⧠āĻĒāĻžāϰā§āĨ¤
ā§Ē. save_to_spanner āĻā§āϞ āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰā§āύ
āĻāĻ āĻā§āϞāĻāĻŋ āύāĻŋāώā§āĻāĻžāĻļāĻŋāϤ āϏāϤā§āϤāĻž āĻāĻŦāĻ āϏāĻŽā§āĻĒāϰā§āĻāĻā§āϞāĻŋāĻā§ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ āĻĄāĻŋāĻŦāĻŋ-āϤ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤
đ def save_to_spanner(extraction_result: Any, survivor_id: Optional[str] = None) -> Dict[str, Any]: āĻāϰ āĻŽāϧā§āϝā§, āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄāĻāĻŋ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ āĻĄāĻŋāĻŦāĻŋ-āϤ⧠āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ āĻāϰāĻž āĻāύāĻāĻŋāĻāĻŋ āĻāĻŦāĻ āϰāĻŋāϞā§āĻļāύāĻļāĻŋāĻĒāĻā§āϞāĻŋ āĻā§āĻāĻžāĻŦā§ āϏā§āĻ āĻāϰāϤ⧠āĻšāϝāĻŧ, āϤāĻž āύāĻŋāϝāĻŧā§ āĻāϞā§āĻāύāĻž āĻāϰā§āĨ¤
"""
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 āĻā§āĻāϞ āĻā§āϞāĻžāĻāĻĄ āϏā§āĻā§āϰā§āĻā§ āĻĢāĻžāĻāϞ āĻāĻĒāϞā§āĻĄā§āϰ āĻāĻžāĻāĻāĻŋ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰā§āĨ¤
đđģ level_2/backend/services/gcs_service.py āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ, āĻ
āĻĨāĻŦāĻž āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ⧠āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞāĻžāϰ āĻāύā§āϝ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āĻāĻžāĻāĻĒ āĻāϰā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/services/gcs_service.py
đ def upload_file(self, file_path: str, survivor_id: Optional[str] = None) -> Tuple[str, MediaType, str]: āĻŽāϧā§āϝā§, āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻā§āĻĄāĻāĻŋ āϏā§āĻĒā§āϝāĻžāύāĻžāϰ āĻā§āϰāĻžāĻĢ āĻĄāĻŋāĻŦāĻŋ-āϤ⧠āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ āĻāϰāĻž āĻāύāĻāĻŋāĻāĻŋ āĻāĻŦāĻ āϰāĻŋāϞā§āĻļāύāĻļāĻŋāĻĒāĻā§āϞāĻŋ āĻā§āĻāĻžāĻŦā§ āϏā§āĻ āĻāϰāϤ⧠āĻšāϝāĻŧ, āϤāĻž āύāĻŋāϝāĻŧā§ āĻāϞā§āĻāύāĻž āĻāϰā§āĨ¤
blob = self.bucket.blob(blob_name)
blob.upload_from_filename(file_path)
āĻāĻ āĻŦāĻŋāώāϝāĻŧāĻāĻŋāĻā§ āĻāĻāĻāĻŋ āϏāĻžāϰā§āĻāĻŋāϏ⧠āϰā§āĻĒāĻžāύā§āϤāϰāĻŋāϤ āĻāϰāĻžāϰ āĻĢāϞā§, āĻāĻā§āύā§āĻā§āϰ āĻāϰ GCS āĻŦāĻžāĻā§āĻ, āĻŦā§āϞāĻŦ āύā§āĻŽ āĻŦāĻž āϏāĻžāĻāύāĻĄ āĻāĻāĻāϰāĻāϞ āĻā§āύāĻžāϰā§āĻļāύ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāĻžāύāĻžāϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āĻšāϝāĻŧ āύāĻžāĨ¤ āĻāĻāĻŋ āĻļā§āϧ⧠'āĻāĻĒāϞā§āĻĄ' āĻāϰāĻžāϰ āĻāύā§āϝ āĻ āύā§āϰā§āϧ āĻāϰā§āĨ¤
ā§Ŧ. āĻā§āύ āĻāĻā§āύā§āĻāĻŋāĻ āĻāϝāĻŧāĻžāϰā§āĻāĻĢā§āϞ⧠> āĻĒā§āϰāĻāϞāĻŋāϤ āĻĒāĻĻā§āϧāϤāĻŋāϏāĻŽā§āĻš?
āĻāĻā§āύā§āĻāĻŋāĻ āϏā§āĻŦāĻŋāϧāĻž:
āĻŦā§āĻļāĻŋāώā§āĻā§āϝ | āĻŦā§āϝāĻžāĻ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ | āĻāĻā§āύā§āĻ-āĻāĻžāϞāĻŋāϤ | āĻāĻā§āύā§āĻāĻŋāĻ āĻāϝāĻŧāĻžāϰā§āĻāĻĢā§āϞ⧠|
āĻāĻāĻŋāϞāϤāĻž | āύāĻŋāĻŽā§āύ (ā§§ āϏā§āĻā§āϰāĻŋāĻĒā§āĻ) | āĻāĻā§āĻ (ā§Ģ+ āĻĒāϰāĻŋāώā§āĻŦāĻž) | āύāĻŋāĻŽā§āύ (ā§§āĻāĻŋ āĻĒāĻžāĻāĻĨāύ āĻĢāĻžāĻāϞ: |
āϰāĻžāώā§āĻā§āϰā§āϝāĻŧ āĻŦā§āϝāĻŦāϏā§āĻĨāĻžāĻĒāύāĻž | āĻŦā§āĻļā§āĻŦāĻŋāĻ āĻāϞāĻ | āĻāĻ āĻŋāύ (āĻŦāĻŋāĻā§āĻāĻŋāύā§āύ) | āĻāĻā§āĻā§āϤ (āĻāĻā§āύā§āĻ āϰāĻžāώā§āĻā§āϰ) |
āϤā§āϰā§āĻāĻŋ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž | āĻĻā§āϰā§āĻāĻāύāĻž | āύā§āϰāĻŦ āϞāĻ | āĻāύā§āĻāĻžāϰā§āĻā§āĻāĻŋāĻ ("āĻāĻŽāĻŋ āĻĢāĻžāĻāϞāĻāĻŋ āĻĒāĻĄāĻŧāϤ⧠āĻĒāĻžāϰāĻŋāύāĻŋ") |
āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻĒā§āϰāϤāĻŋāĻā§āϰāĻŋāϝāĻŧāĻž | āĻāύāϏā§āϞ āĻĒā§āϰāĻŋāύā§āĻ | āĻā§āĻāĻā§āϰāĻšāĻŖ āĻĒā§āϰāϝāĻŧā§āĻāύ | āϤāĻžā§āĻā§āώāĻŖāĻŋāĻ (āĻā§āϝāĻžāĻā§āϰ āĻ āĻāĻļ) |
āĻ āĻāĻŋāϝā§āĻāύāϝā§āĻā§āϝāϤāĻž | āϏā§āĻĨāĻŋāϰ āϝā§āĻā§āϤāĻŋ | āĻāĻ ā§āϰ āĻāĻžāϰā§āϝāĻžāĻŦāϞ⧠| āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ (āĻāϞāĻāϞāĻāĻŽ āĻĒāϰāĻŦāϰā§āϤ⧠āĻĒāĻĻāĻā§āώā§āĻĒ āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰā§) |
āĻĒā§āϰāϏāĻā§āĻ āϏāĻā§āϤāύāϤāĻž | āĻā§āύā§āĻāĻŋāĻ āύāĻž | āĻā§āύā§āĻāĻŋāĻ āύāĻž | āϏāĻŽā§āĻĒā§āϰā§āĻŖ (āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻāĻĻā§āĻĻā§āĻļā§āϝ āĻāĻžāύā§) |
āĻā§āύ āĻāĻāĻŋ āĻā§āϰā§āϤā§āĻŦāĻĒā§āϰā§āĻŖ: multimedia_agent.py (āĻāĻāĻāĻŋ āϏāĻŋāĻā§āϝāĻŧā§āύāĻļāĻŋāϝāĻŧāĻžāϞāĻāĻā§āύā§āĻ āϝāĻžāϰ ā§ĒāĻāĻŋ āϏāĻžāĻŦ-āĻāĻā§āύā§āĻ āϰāϝāĻŧā§āĻā§: āĻāĻĒāϞā§āĻĄ â āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ â āϏā§āĻ â āϏāĻžāĻŽāĻžāϰāĻŋ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§, āĻāĻŽāϰāĻž āĻāĻāĻŋāϞ āĻĒāϰāĻŋāĻāĻžāĻ āĻžāĻŽā§ āĻāĻŦāĻ āĻāĻā§āĻā§āϰ āϏā§āĻā§āϰāĻŋāĻĒā§āĻāĻā§āϞā§āĻā§ āĻŦā§āĻĻā§āϧāĻŋāĻŽāĻžāύ, āĻāĻĨā§āĻĒāĻāĻĨāύāĻŽā§āϞāĻ āĻ
ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āϞāĻāĻŋāĻ āĻĻāĻŋāϝāĻŧā§ āĻĒā§āϰāϤāĻŋāϏā§āĻĨāĻžāĻĒāύ āĻāϰāĻŋāĨ¤
ā§§ā§Ļ. âī¸ [āĻāĻā§āĻāĻŋāĻ] āĻŽāĻžāϞā§āĻāĻŋāĻŽā§āĻĄāĻžāϞ āĻĒāĻžāĻāĻĒāϞāĻžāĻāύ (āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻĒāĻ āύāϝā§āĻā§āϝ) â āĻāĻā§āύā§āĻ āϞā§āϝāĻŧāĻžāϰ
āĻāĻā§āύā§āĻ āϞā§āϝāĻŧāĻžāϰāĻāĻŋ āĻŦā§āĻĻā§āϧāĻŋāĻŽāϤā§āϤāĻž āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰ⧠â āĻāĻ āĻāĻā§āύā§āĻāĻā§āϞ⧠āĻŦāĻŋāĻāĻŋāύā§āύ āĻā§āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻžāĻ āϏāĻŽā§āĻĒāύā§āύ āĻāϰā§āĨ¤ āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāĻā§āύā§āĻā§āϰ āĻāĻāĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻā§āĻŽāĻŋāĻāĻž āĻĨāĻžāĻā§ āĻāĻŦāĻ āĻāĻāĻŋ āĻĒāϰāĻŦāϰā§āϤ⧠āĻāĻā§āύā§āĻā§āϰ āĻāĻžāĻā§ āĻĒā§āϰāĻžāϏāĻā§āĻāĻŋāĻ āϤāĻĨā§āϝ āĻĒā§āϰā§āϰāĻŖ āĻāϰā§āĨ¤ āύāĻŋāĻā§ āĻāĻāĻāĻŋ āĻŽāĻžāϞā§āĻāĻŋāĻāĻā§āύā§āĻ āϏāĻŋāϏā§āĻā§āĻŽā§āϰ āĻāϰā§āĻāĻŋāĻā§āĻāĻāĻžāϰ āĻĄāĻžāϝāĻŧāĻžāĻā§āϰāĻžāĻŽ āĻĻā§āĻāϝāĻŧāĻž āĻšāϞā§āĨ¤

ā§§. āĻāĻā§āύā§āĻ āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ
đđģ level_2/backend/agent/multimedia_agent.py āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ āĻ
āĻĨāĻŦāĻž āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ⧠āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāĻŽāĻžāύā§āĻĄāĻāĻŋ āĻāĻžāĻāĻĒ āĻāϰā§āύāĨ¤ āĻāĻāĻāĻŋ āύāϤā§āύ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻā§āϞā§āύāĨ¤ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞā§, āĻā§āϞāĻžāĻāĻĄ āĻļā§āϞ āĻāĻĄāĻŋāĻāϰ-āĻ āĻĢāĻžāĻāϞāĻāĻŋ āĻā§āϞā§āύ:
cloudshell edit ~/way-back-home/level_2/backend/agent/multimedia_agent.py
⧍. āĻāĻĒāϞā§āĻĄ āĻāĻā§āύā§āĻ āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰā§āύ
āĻāĻ āĻāĻā§āύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰ āĻŦāĻžāϰā§āϤāĻž āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻĢāĻžāĻāϞ āĻĒāĻžāĻĨ āϏāĻāĻā§āϰāĻš āĻāϰ⧠āĻāĻŦāĻ āϤāĻž GCS-āĻ āĻāĻĒāϞā§āĻĄ āĻāϰā§āĨ¤
multimedia_agent.py āĻĢāĻžāĻāϞ⧠āύāĻŋāĻā§āϰ āĻā§āĻĄāĻāĻŋāϰ āϏāĻžāĻšāĻžāϝā§āϝ⧠upload_agent āϤā§āϰāĻŋ āĻāϰāĻž āĻšāϝāĻŧ, āϝāĻž GCS-āĻ āĻāĻĒāϞā§āĻĄ āĻāϰā§:
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 āĻĢāĻžāĻāϞ⧠āύāĻŋāĻā§āϰ āĻā§āĻĄāĻāĻŋ extraction_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 āĻĢāĻžāĻāϞ⧠āύāĻŋāĻā§āϰ āĻā§āĻĄāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠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_agent āĻāύā§āϝ āĻĒā§āϰāĻŽā§āĻĒāĻ āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰāĻž āĻšāϝāĻŧ, āϝāĻž āĻĢāϞāĻžāĻĢāϞā§āϰ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āĻāϰā§:
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 (āĻāĻā§āύā§āĻ āĻĄā§āĻā§āϞāĻĒāĻŽā§āύā§āĻ āĻāĻŋāĻ) āĻĨā§āĻā§ āϏāĻŋāĻā§āϝāĻŧā§āύāĻļāĻŋāϝāĻŧāĻžāϞ āĻāĻā§āύā§āĻ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĨ¤
ā§§. āĻā§āύ āĻ āύā§āĻā§āϰāĻŽāĻŋāĻ?
āĻāĻāĻāĻŋ āĻāĻĒāϞā§āĻĄ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻžāĻāϰāĻŖ āĻāĻāĻāĻŋ āϰā§āĻāĻŋāĻ āύāĻŋāϰā§āĻāϰāĻļā§āϞāϤāĻžāϰ āĻļā§āĻā§āĻāϞ:
- āĻĢāĻžāĻāϞāĻāĻŋ (āĻāĻĒāϞā§āĻĄ) āύāĻž āĻāϰāĻž āĻĒāϰā§āϝāύā§āϤ āĻāĻĒāύāĻŋ āĻĄā§āĻāĻž āĻŦā§āϰ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āύāĻžāĨ¤
- āĻĄā§āĻāĻž āĻāĻā§āϏāĻā§āϰā§āϝāĻžāĻā§āĻ (Extraction) āύāĻž āĻāϰāĻž āĻĒāϰā§āϝāύā§āϤ āĻāĻĒāύāĻŋ āϤāĻž āϏā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āύāĻžāĨ¤
- āĻĢāϞāĻžāĻĢāϞ āύāĻž āĻĒāĻžāĻāϝāĻŧāĻž āĻĒāϰā§āϝāύā§āϤ āĻāĻĒāύāĻŋ āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āύāĻž (āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āύ)āĨ¤
āĻāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ SequentialAgent āĻāĻāĻĻāĻŽ āĻāĻĒāϝā§āĻā§āϤāĨ¤ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻāĻā§āύā§āĻā§āϰ āĻāĻāĻāĻĒā§āĻāĻā§ āĻĒāϰāĻŦāϰā§āϤ⧠āĻāĻā§āύā§āĻā§āϰ āĻāύāĻā§āĻā§āϏāĻ/āĻāύāĻĒā§āĻ āĻšāĻŋāϏā§āĻŦā§ āĻĒā§āϰā§āϰāĻŖ āĻāϰā§āĨ¤
⧍. āĻāĻā§āύā§āĻā§āϰ āϏāĻāĻā§āĻāĻž
āĻāϞā§āύ āĻĻā§āĻā§ āύā§āĻāϝāĻŧāĻž āϝāĻžāĻ 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
Locate the comment # TODO: REPLACE_ADD_SUBAGENT . Replace this whole line with the following code:
sub_agents=[multimedia_agent],
This single object effectively bundles four "experts" into one callable entity.
4. Data Flow Between Agents
Each agent stores its output in a shared context that subsequent agents can access:

5. Open application (skip if app is still running)
đđģ Start App:
cd ~/way-back-home/level_2/
./start_app.sh
đ Click Local: http://localhost:5173/ from the terminal.
6. Test Image Upload
đ In the chat interface, choose any of the photo here and upload to the UI:
In the chat interface, tell the agent about your specific context:
Here is the survivor note
And then attach the image here.


đđģ In the terminal, when you finished testing, press "Ctrl+C" to end the process.
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. âī¸ [Optional] 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
)
13. âī¸ [Optional] Attach Agent with Agent Engine
1. 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.
Verify Memory Bank
Now you can verify that the memory bank is working by teaching the agent a preference and checking if it persists across sessions.
Step One. Open the application
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.
Step Two. 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.
Step Three. 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?"
Step Four. 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:
Step Five. 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. âī¸ [Optional] 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.
(OPTIONAL) 4. 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