1. ภาพรวม
โลกของ AI และเทคโนโลยีเปลี่ยนแปลงเร็วกว่าที่ใครๆ จะตามทัน โมเดล งานวิจัย และผลิตภัณฑ์ใหม่ๆ จะเปิดตัวทุกวัน Agent สรุปที่ดึงพาดหัวข่าวของวันนี้ เขียนสรุปที่กระชับ และสร้าง PDF ทุกเช้าจะช่วยแก้ปัญหานี้ได้ แต่การสร้าง Agent ดังกล่าวต้องเลือกเฟรมเวิร์ก กำหนดเครื่องมือใน Python เขียนลูปการจัดการเป็นกลุ่ม แพ็กเกจคอนเทนเนอร์ และทำให้ใช้งานได้ใน Cloud Run ทั้งหมดนี้เกิดขึ้นก่อนที่เอเจนต์จะส่งคำขอเว็บแม้แต่รายการเดียว
Agent ที่ได้รับการจัดการใน Gemini API จะเปลี่ยนสมการ คุณเขียนไฟล์การกำหนดค่า Markdown 2 ไฟล์และสคริปต์ตัวแสดงผลที่สร้างไว้ล่วงหน้า ทำการเรียก API 1 ครั้ง และแซนด์บ็อกซ์ Ubuntu จริงจะบูต เรียกดูเว็บ เขียนข้อมูลสรุป และสร้าง PDF ไม่มีคอนเทนเนอร์ ไม่มีการทำให้ใช้งานได้ ไม่ต้องใช้โค้ดการจัดการเป็นกลุ่ม
ใน Codelab นี้ คุณจะได้สร้าง Agent ดังกล่าวตั้งแต่ฟังก์ชันว่างเปล่าไปจนถึงสรุปประจำวันที่ใช้งานได้จริง โดยจะทีละแนวคิด
สิ่งที่คุณจะสร้าง
- สร้างและเรียกใช้เอเจนต์ที่มีการจัดการตัวแรกในแซนด์บ็อกซ์ Linux จริง
- ปรับแต่ง Agent ด้วยสไตล์การบรรณาธิการ แหล่งข้อมูลบนเว็บ และทักษะ PDF
- เพิ่มฮุกความปลอดภัยเพื่อบล็อกคำสั่งที่เป็นอันตรายก่อนที่จะเรียกใช้
- ดาวน์โหลด PDF ที่ตัวแทนสร้างขึ้น
- ปรับแต่งเนื้อหาโดยรวมในการสนทนาไปมาโดยไม่ต้องดึงข้อมูลเว็บอีกครั้ง
- บันทึกการกำหนดค่าเอเจนต์และเรียกใช้ตามรหัสในการเรียกใช้ในอนาคต
- ส่งข้อมูลสรุปไปยังกล่องจดหมายผ่าน Gmail API
- ตั้งเวลาให้ Agent ทำงานและส่งโดยอัตโนมัติทุกวัน
สิ่งที่คุณต้องมี
- Python 3.10 ขึ้นไป
- คีย์ Gemini API: aistudio.google.com/api-keys (รวมระดับฟรีแล้ว ขอแนะนำให้ใช้การเรียกเก็บเงินเพื่อให้รันได้อย่างต่อเนื่อง)
2. Agent ที่ได้รับการจัดการใน Gemini API คืออะไร
ระบบ AI 3 ระดับ
ก่อนที่จะเจาะลึกเรื่องโค้ด มาดูตำแหน่งของ Agent ที่ได้รับการจัดการ เมื่อเทียบกับทางเลือกอีก 2 ทางกัน
ระดับ | คืออะไร | ใครเป็นผู้จัดการโครงสร้างพื้นฐาน |
LLM มาตรฐาน | คุณป้อนพรอมต์ แล้ว Gemini จะตอบกลับด้วยข้อความ ไม่มีมือ ไม่มีหน่วยความจำ ไม่มีอินเทอร์เน็ต | ไม่มี: ไม่สามารถทำอะไรได้ด้วยตัวเอง |
เอเจนต์ที่โฮสต์ด้วยตนเอง | คุณเชื่อมต่อ ADK/LangChain/AutoGen + Docker + เครื่องมือ + หน่วยความจำ | คุณ: ทั้งหมด (หรือแพลตฟอร์มที่มีการจัดการ เช่น Agent Engine) |
Agent ที่ได้รับการจัดการ | คุณกำหนดเป้าหมายให้ Google จัดสรรแซนด์บ็อกซ์ที่ปลอดภัย Agent จะเขียนโค้ด เรียกใช้โค้ด อ่านข้อผิดพลาด ค้นหาในเว็บ และแก้ไขข้อบกพร่องได้โดยอัตโนมัติ | Google: ทั้งหมด |
Codelab นี้เกี่ยวกับแถวที่ 3 คุณจัดเตรียมไฟล์งานและการกำหนดค่า Google จะจัดการส่วนที่เหลือให้
สิ่งที่คุณจะสร้างด้วย ADK + Cloud Run
หากต้องการสร้างเอเจนต์สรุปข่าวที่เรียกดูเว็บ เรียกใช้ Python และสร้าง PDF คุณจะต้องมีสิ่งต่อไปนี้ด้วย ADK + Cloud Run
# agent.py: define tools and wire up the agent
from google.adk.agents import LlmAgent
from google.adk.tools import google_search, built_in_code_execution
agent = LlmAgent(
name="digest-agent",
model=MODEL,
instruction=AGENTS_MD, # your editorial voice and rules
tools=[google_search, built_in_code_execution],
)
# app.py: serve the agent over HTTP
from google.adk.runners import FastApiRunner
runner = FastApiRunner(agent=agent)
app = runner.app
# pdf_tool.py: custom tool, install reportlab, render PDF
# scraper.py: custom tool, fetch each news source
# streaming.py: wire agent events to your SSE endpoint
# Dockerfile: package everything
FROM python:3.12
COPY . /app
RUN pip install google-adk reportlab requests
CMD ["uvicorn", "app:app", "--host", "0.0.0.0"]
# Deploy to Cloud Run
gcloud run deploy digest-agent \
--image gcr.io/your-project/digest-agent \
--set-secrets GEMINI_API_KEY=gemini-key:latest \
--memory 2Gi
ซึ่งเป็นช่วงก่อนที่ Agent จะทำงาน คุณยังคงเป็นเจ้าของการแยกแซนด์บ็อกซ์ (ดังนั้นเอเจนต์จึงไม่สามารถทำให้เซิร์ฟเวอร์เสียหายได้) การติดตั้งแพ็กเกจ การจัดการสถานะระหว่างการเรียกใช้เครื่องมือ และโครงสร้างพื้นฐานการสตรีมเพื่อรับเหตุการณ์ไปยังไคลเอ็นต์
สิ่งที่ Agent ที่ได้รับการจัดการจะแทนที่
from google import genai
client = genai.Client()
stream = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Generate the digest.",
stream=True,
environment={
"type": "remote",
"sources": [ # your config files, mounted at startup
{
"type": "inline",
"target": ".agents/AGENTS.md",
"content": AGENTS_MD,
},
{
"type": "inline",
"target": ".agents/skills/digest-pdf/SKILL.md",
"content": SKILL_MD,
},
{
"type": "inline",
"target": ".agents/skills/digest-pdf/scripts/generate_pdf.py",
"content": GENERATE_PDF_PY,
},
],
},
)
สิ่งที่ ADK + Cloud Run ต้องการ | สิ่งที่ Agent ที่ได้รับการจัดการจะจัดการให้คุณ |
อิมเมจคอนเทนเนอร์ + Dockerfile + CI/CD | แซนด์บ็อกซ์ Ubuntu ที่มีการจัดการเต็มรูปแบบ (Python 3.12, Node 22, 4 CPU / 16 GB RAM) |
การติดตั้งใช้งานและการปรับขนาด Cloud Run | จัดสรรต่อการโต้ตอบ 1 ครั้ง และจะหมดอายุโดยอัตโนมัติหลังจากไม่มีการใช้งานเป็นเวลา 7 วัน |
การแยกแซนด์บ็อกซ์ | แยกตามการโต้ตอบ |
เครื่องมือ PDF ที่กำหนดเอง + | Agent ติดตั้งแพ็กเกจภายในแซนด์บ็อกซ์ |
โครงสร้างพื้นฐานการสตรีม SSE |
|
คำจำกัดความของเครื่องมือใน Python | เครื่องมือที่มีในตัว: การท่องเว็บ การเรียกใช้โค้ด ระบบไฟล์ |
การจัดการสถานะระหว่างการเรียกใช้เครื่องมือ | รวมไว้ในลูปการให้เหตุผลของ Agent |
คุณเขียนไฟล์การกำหนดค่า (AGENTS.md, SKILL.md, สคริปต์ที่สร้างไว้ล่วงหน้า) และทำการเรียก API 1 ครั้ง Google จะจัดการส่วนที่เหลือให้
วิธีการทำงานของแซนด์บ็อกซ์
interactions.create() call
│
▼
Google provisions Ubuntu sandbox (Python 3.12, Node 22, 4 CPU / 16 GB RAM)
│
▼
Agent reasoning loop:
plan → fetch URLs → run Python → write files → reason → repeat
│
▼
Events stream back in real time: tool calls, text chunks, completion
│
▼
interaction.completed → environment_id + interaction_id
Sandbox จะยังคงอยู่เป็นเวลา 7 วันหากไม่มีการใช้งาน คุณสามารถกลับมาทำงานต่อด้วย environment_id เพื่อปรับแต่งเอาต์พุต เรียกใช้งานติดตาม หรือฟอร์กเป็นเอเจนต์ที่มีชื่อที่บันทึกไว้
3. ตั้งค่า
ตัวเลือก ก: Cloud Shell (แนะนำ)
คลิกปุ่มด้านล่างเพื่อเปิด Codelab นี้ใน Google Cloud Shell ระบบจะติดตั้งการขึ้นต่อกันทั้งหมดไว้ล่วงหน้า
ตัวเลือก ข: การตั้งค่าในพื้นที่
git clone https://github.com/Saoussen-CH/tech-digest-managed-agent.git
cd tech-digest-managed-agent
ติดตั้ง uv หากจำเป็น
curl -LsSf https://astral.sh/uv/install.sh | sh
กำหนดค่าคีย์ API
cp .env.example .env
cloudshell edit .env
ตั้งค่าคีย์ดังนี้
GEMINI_API_KEY=your-key-here
ติดตั้งการอ้างอิง
uv sync
4. โทรหา Agent ครั้งแรก
เปิดไฟล์เริ่มต้น
cloudshell edit run_digest.py
run_digest() มี TODO 1 รายการที่ต้องกรอกตอนนี้ และอีก 3 รายการสำหรับขั้นตอนถัดไป ระบบจะกรอกข้อมูลผู้ช่วย 2 คนไว้ให้แล้วที่ด้านบน
load_source(path): อ่านไฟล์จาก.agents/ที่สัมพันธ์กับสคริปต์ คุณจะใช้ข้อมูลนี้ในแบบฝึกหัดถัดไปเพื่อต่อเชื่อมสไตล์การบรรณาธิการ เพลย์บุ๊ก PDF และโปรแกรมแสดงผลลงในแซนด์บ็อกซ์run_stream(stream): ประมวลผลสตรีมเหตุการณ์และแสดงผล(environment_id, interaction_id)คุณไม่จำเป็นต้องเขียน Event Loop ด้วยตนเอง
สิ่งที่ต้องเพิ่ม
TODO 1: แทนที่ pass ด้วย (ข้าม TODO 3, 4 ไปก่อน เนื่องจากเป็นขั้นตอนถัดไป)
from google import genai
client = genai.Client()
stream = client.interactions.create(
agent=BASE_AGENT,
agent_config={"type": "antigravity", "model": "gemini-3.7-flash"},
input="Fetch the Hacker News front page and list the top 5 stories.",
stream=True,
environment="remote",
)
environment_id, interaction_id = run_stream(stream)
print(f"\nDone. environment_id={environment_id}")
หน้าที่ของแต่ละส่วน
genai.Client()อ่านGEMINI_API_KEYจากสภาพแวดล้อม ส่วนอื่นๆ ทั้งหมดจะผ่านไคลเอ็นต์นี้
interactions.create() คือการเรียกหลัก โดยมีพารามิเตอร์ 4 รายการที่ทำให้การทำงานเป็นไปได้ ดังนี้
agent=BASE_AGENT: เลือก Agent ของ Antigravity (antigravity-preview-05-2026) ซึ่งเป็น Agent ที่ได้รับการจัดการแบบอเนกประสงค์ที่ขับเคลื่อนโดย Gemini 3.7 Flash โดยค่าเริ่มต้น คุณสามารถกำหนดค่าโมเดลพื้นฐานได้โดยใช้agent_config(ตัวเลือก:gemini-3.7-flash,gemini-3.6-flash,gemini-3.5-flash,gemini-3.5-flash-lite) ซึ่งมาพร้อมกับเครื่องมือในตัว 3 อย่างที่เปิดใช้โดยค่าเริ่มต้น ได้แก่code_execution(เรียกใช้ Bash, Python, Node.js),google_searchและurl_context(ดึงและอ่านหน้าเว็บ) ระบบจะเปิดใช้เครื่องมือระบบไฟล์ (read_file,write_file,list_files) โดยอัตโนมัติเมื่อคุณส่งพารามิเตอร์environmentการเรียกใช้ครั้งเดียวจะจัดสรรสภาพแวดล้อม Ubuntu ที่มีการจัดการเต็มรูปแบบพร้อม Python 3.12, Node.js 22, git, pip และ curl ที่ติดตั้งไว้ล่วงหน้า ไม่ต้องสร้างคอนเทนเนอร์ ไม่ต้องทำให้ใช้งานได้input: งานสำหรับการเรียกใช้ครั้งนี้ เอเจนต์จะเรียกดู Hacker News และให้เหตุผลเกี่ยวกับผลลัพธ์environment="remote": จัดสรรแซนด์บ็อกซ์ระบบคลาวด์ใหม่สำหรับการโต้ตอบนี้stream=True: แสดงผลตัววนซ้ำของเหตุการณ์แทนการบล็อก หากไม่มีพารามิเตอร์นี้ ระบบจะรอ 30-90 วินาทีและแสดงผลลัพธ์ทั้งหมดพร้อมกันเป็นinteraction.output_textการสตรีมช่วยให้คุณเห็นเหตุผลของ Agent และดำเนินการได้ทันที การสตรีมไม่ใช่ฟีเจอร์ขั้นสูงในที่นี้ แต่เป็นค่าเริ่มต้นที่เหมาะสม เนื่องจากกล่องดำ 90 วินาทีไม่ได้ให้สัญญาณใดๆ เกี่ยวกับว่าตัวแทนกำลังทำงานหรือติดขัด
environment_id คือแฮนเดิลของแซนด์บ็อกซ์ที่เพิ่งเรียกใช้ หลังจาก interaction.completed แซนด์บ็อกซ์จะไม่ปิดตัวลง แต่จะยังคงใช้งานได้นานสูงสุด 7 วัน environment_id คือวิธีกลับไปที่หน้าดังกล่าว ส่งไปยังการโทร interactions.create() ครั้งที่ 2 แล้วตัวแทนจะกลับมาทำงานต่อในระบบไฟล์เดิม โดยมีไฟล์และแพ็กเกจที่ติดตั้งไว้เหมือนเดิมราวกับว่าไม่เคยหยุดทำงาน ขั้นตอนถัดไปจะใช้ข้อมูลนี้เพื่อดาวน์โหลด PDF โดยไม่ต้องเรียกใช้ตัวแทนอีกครั้ง และขั้นตอนหลังจากนั้นจะใช้ข้อมูลนี้เพื่อสนทนาต่อ
interaction_id คือแฮนเดิลของรอบการสนทนาที่เพิ่งเสร็จสมบูรณ์ ส่งเป็น previous_interaction_id ในการเรียกใช้ครั้งถัดไป แล้วตัวแทนจะมีข้อมูลทั้งหมดเกี่ยวกับสิ่งที่พูดและทำในเทิร์นนี้
ยืนยัน
uv run python run_digest.py
คุณควรเห็นเอาต์พุตแบบเรียลไทม์ขณะที่เอเจนต์ทำงาน
[agent started]
[tool] run_code
Here are the top 5 stories currently on the Hacker News front page, retrieved via the official Hacker News API:
1. **Qwen 3.6 27B is the sweet spot for local development** (471 points)
2. **.self: A new top-level domain designed to support self-hosting** (116 points)
...
Done. environment_id=e3de58774073f75a6ef42924c6ce2e88
API จะแสดงผล environment_id จริงแม้จะมี environment="remote" แซนด์บ็อกซ์ทำงานแล้ว สิ่งที่ขาดหายไปคือการกำหนดค่า ซึ่งไม่มีเสียง ไม่มีทักษะ และไม่มีเครื่องมือสร้าง PDF เอเจนต์เพียงแค่พิมพ์เรื่องราวเป็นข้อความแล้วก็หยุด ขั้นตอนถัดไปคือการเพิ่มข้อมูลเหล่านั้น
เอาต์พุตแต่ละบรรทัดจะแมปกับเหตุการณ์จาก run_stream() ดังนี้
| คำอธิบาย | สิ่งที่ |
| ตัวแทนดึงข้อมูล URL |
|
| Agent ที่รันโค้ดในแซนด์บ็อกซ์ |
|
| เอเจนต์ค้นหาในเว็บ |
|
| เครื่องมือไฟล์และอื่นๆ |
|
| ตัวแทนเขียนข้อความ | สตรีมไปยัง stdout โดยตรง |
5. ปรับแต่ง Agent
ตัวแทนไม่มีคำสั่ง ไม่ว่าจะเป็นเสียง ทักษะ หรือเครื่องมือสร้าง PDF ในขั้นตอนนี้ คุณจะโหลดไฟล์การกำหนดค่าจาก .agents/ และติดตั้งไฟล์เหล่านั้นลงในแซนด์บ็อกซ์
สิ่งที่ต้องเปลี่ยน
ทำการเปลี่ยนแปลง 4 อย่างใน run_digest.py ดังนี้
TODO 2: ใต้ load_source() ให้เพิ่มค่าคงที่ระดับโมดูล 3 รายการ (ค่าคงที่เหล่านี้อยู่นอก run_digest() ที่ด้านบนของไฟล์)
AGENTS_MD = load_source(".agents/AGENTS.md")
SKILL_MD = load_source(".agents/skills/digest-pdf/SKILL.md")
GENERATE_PDF_PY = load_source(".agents/skills/digest-pdf/scripts/generate_pdf.py")
เปิดแต่ละไฟล์เพื่อดูสิ่งที่คุณกำลังโหลด AGENTS.md กำหนดสไตล์การบรรณาธิการและกฎเวิร์กโฟลว์ SKILL.md คือเพลย์บุ๊ก PDF แบบทีละขั้นตอน generate_pdf.py คือโปรแกรมแสดงผลที่สร้างไว้ล่วงหน้าซึ่งตัวแทนจะเรียกใช้
ตอนนี้ให้ทำการเปลี่ยนแปลงอีก 2 รายการภายใน run_digest() ดังนี้
TODO 3: เปลี่ยน environment จาก "remote" เป็นพจนานุกรมแหล่งที่มา และตั้งค่า input เป็น "Generate the digest.":
environment={
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/AGENTS.md",
"content": AGENTS_MD,
},
{
"type": "inline",
"target": ".agents/skills/digest-pdf/SKILL.md",
"content": SKILL_MD,
},
{
"type": "inline",
"target": ".agents/skills/digest-pdf/scripts/generate_pdf.py",
"content": GENERATE_PDF_PY,
},
],
},
สิ่งที่ต้องทำ 4: เพิ่มบรรทัดนี้หลัง print(f"\nDone. environment_id={environment_id}") ทันที
save_env(ENVIRONMENT_ID=environment_id, INTERACTION_ID=interaction_id)
มีการกำหนด save_env ไว้ใน run_digest.py แล้ว โดยจะเขียนทั้ง 2 รหัสไปยัง .env เพื่อให้ขั้นตอนถัดไปดาวน์โหลด PDF ได้โดยไม่ต้องเรียกใช้ตัวแทนอีกครั้ง
การทำงานของแต่ละแหล่งที่มา
แต่ละแหล่งที่มาคือไฟล์ที่ติดตั้งในระบบไฟล์แซนด์บ็อกซ์เมื่อเริ่มต้นระบบก่อนที่เอเจนต์จะทำงาน target เส้นทางจะตรงกับตำแหน่งที่สายรัด Antigravity คาดว่าจะพบไฟล์
.agents/
├── AGENTS.md ← auto-loaded as global instructions
└── skills/
└── digest-pdf/
├── SKILL.md ← auto-discovered and registered as a skill
└── scripts/
└── generate_pdf.py ← pre-built renderer the agent can run
| ตัวแปร | สิ่งที่สายรัดทำกับอุปกรณ์ |
|
| โหลดอัตโนมัติเป็นคำสั่งถาวร: สไตล์การบรรณาธิการ เวิร์กโฟลว์ กฎการดำเนินการ |
|
| ค้นพบและลงทะเบียนโดยอัตโนมัติเป็นทักษะที่มีชื่อ โดยเอเจนต์จะเรียกใช้ตามชื่อ |
|
| ตัวแสดงผล PDF ที่สร้างไว้ล่วงหน้า โดยเอเจนต์จะเขียน |
ยืนยัน
uv run python run_digest.py
การเรียกใช้จะใช้เวลา 1-3 นาที คุณควรเห็นเอเจนต์อ่านไฟล์การกำหนดค่า เขียนข้อมูลสรุป และบันทึก PDF ดังนี้
[agent started]
[tool] read_file (/.agents/skills/digest-pdf/SKILL.md)
[tool] list_files (/.agents/skills/digest-pdf/scripts)
[tool] read_file (/.agents/skills/digest-pdf/scripts/generate_pdf.py)
[tool] run_code
[tool] write_file (/workspace/summaries.json)
[tool] run_code
[tool] delete_file (/tmp/test_scrape.py)
I have successfully generated today's tech news digest and saved the formatted document to /workspace/digest.pdf.
Done. environment_id=4129ffd75574e308748e9425d7ec828f
environment_id ตอนนี้เป็นค่าจริงแล้ว Sandbox ทำงานกับไฟล์การกำหนดค่าของคุณ และ Agent สร้าง digest.pdf ขั้นตอนถัดไปจะเพิ่มการตรวจสอบความปลอดภัยก่อนดาวน์โหลด
6. เพิ่ม Safety Hook
Hook ช่วยให้คุณเรียกใช้สคริปต์ภายในแซนด์บ็อกซ์ก่อนหรือหลังการเรียกใช้เครื่องมือแต่ละครั้ง เอเจนต์สรุปใช้ code_execution เพื่อเรียกใช้สคริปต์ Python ดังนั้นฮุก pre_tool_execution จึงสามารถสกัดกั้นการเรียกเหล่านั้นและบล็อกคำสั่งเชลล์ที่เป็นอันตรายก่อนที่จะดำเนินการได้
โดยรันไทม์จะอ่าน .agents/hooks.json จากแซนด์บ็อกซ์ ก่อนการเรียกใช้เครื่องมือจับคู่แต่ละครั้ง ระบบจะส่งรายละเอียดการโทรไปยังสคริปต์เกตบน stdin สคริปต์จะพิมพ์ {"decision": "allow"} หรือ {"decision": "deny", "reason": "..."} ไปยัง stdout การปฏิเสธจะยกเลิกการเรียกใช้เครื่องมือ และตัวแทนจะเห็นเหตุผลของคุณและแก้ไขตัวเอง
สิ่งที่ต้องเพิ่ม
TODO 5: ใน run_digest.py ให้เพิ่มค่าคงที่ 2 รายการนี้ไว้ใกล้ด้านบนหลังจากเรียกใช้ load_source ที่มีอยู่
import json
HOOKS_JSON = json.dumps({
"safety-gate": {
"pre_tool_execution": [
{
"matcher": "code_execution",
"hooks": [
{
"type": "command",
"command": "python3 /.agents/hooks-scripts/gate.py",
"timeout": 10,
}
],
}
]
}
}, indent=2)
GATE_PY = """\
#!/usr/bin/env python3
import sys, json
data = json.load(sys.stdin)
cmd = str(data.get("tool_call", {}).get("args", {}))
if "rm -rf" in cmd:
print(json.dumps({"decision": "deny", "reason": "Destructive command blocked by safety gate."}))
else:
print(json.dumps({"decision": "allow"}))
"""
สิ่งที่ต้องทำ 6: เพิ่มรายการอีก 2 รายการลงในรายการ sources ภายใน interactions.create() ดังนี้
{"type": "inline", "target": ".agents/hooks.json", "content": HOOKS_JSON},
{"type": "inline", "target": ".agents/hooks-scripts/gate.py", "content": GATE_PY},
วิธีที่ฮุกทำงานในการเรียกใช้ข้อมูลสรุป
ทุกครั้งที่เอเจนต์เรียกใช้ code_execution เพื่อเรียกใช้สคริปต์ Python หรือคำสั่งเชลล์ รันไทม์จะส่งรายละเอียดการโทรไปยัง gate.py ก่อน หากคำสั่งมี rm -rf ฮุกจะแสดง deny และ Agent จะได้รับเหตุผลการปฏิเสธและลองอีกครั้งด้วยตัวเลือกที่ปลอดภัย ส่วนการเรียกใช้โค้ดอื่นๆ ทั้งหมดจะผ่านไปโดยไม่มีการเปลี่ยนแปลง
ยืนยัน
uv run python run_digest.py
เอาต์พุตจะเหมือนเดิมทุกประการ โดยเกตเวย์ความปลอดภัยจะอนุญาตคำสั่งการสร้าง PDF ปกติทั้งหมด หากต้องการยืนยันว่าฮุกทำงาน ให้เปลี่ยนอินพุตของเอเจนต์ชั่วคราวเพื่อขอให้เรียกใช้ rm -rf /tmp/test คุณจะเห็นรายงานของเอเจนต์ที่ระบุว่าระบบบล็อกคำสั่งและเลือกคำสั่งอื่น
7. ดาวน์โหลด PDF
ตัวแทนเขียน digest.pdf ถึง /workspace/digest.pdf ภายในแซนด์บ็อกซ์ ภาพรวมสภาพแวดล้อมพร้อมใช้งานเป็นไฟล์เก็บถาวร tar ผ่าน Gemini Files API
ติดตั้ง requests หากจำเป็น
uv pip install requests
สิ่งที่ต้องกรอก
เปิด download_pdf.py โดยมีสิ่งที่ต้องทำ 2 รายการ
สิ่งที่ต้องทำ 1: กรอกข้อมูลในrequests.get() call:
r = requests.get(
f"https://generativelanguage.googleapis.com/v1beta/files/environment-{environment_id}:download",
params={"alt": "media"},
headers={"x-goog-api-key": api_key},
allow_redirects=True,
)
r.raise_for_status()
URL จะระบุภาพรวมของแซนด์บ็อกซ์ params={"alt": "media"} จะแสดงผลไบต์ดิบแทนข้อมูลเมตา GEMINI_API_KEYที่มีอยู่จะตรวจสอบสิทธิ์ Files API ด้วย
TODO 2: ค้นหาและแยกไฟล์ PDF จากที่เก็บถาวร tar
member = next(m for m in tar.getmembers() if m.name.endswith("workspace/digest.pdf"))
tar.extract(member, path=tmp, filter="data")
คำนำหน้าเส้นทาง tar จะแตกต่างกันไปในแต่ละการเรียกใช้ ดังนั้นให้ค้นหาตามคำต่อท้ายแทนที่จะเขียนโค้ดเส้นทางที่แน่นอน filter="data" จะไม่แสดงคำเตือนการเลิกใช้งาน Python 3.13 เกี่ยวกับการแยกไฟล์ tar ที่ไม่ปลอดภัย
ยืนยัน
uv run python download_pdf.py
Saved digest.pdf (48,231 bytes)
เปิด digest.pdf ในไดเรกทอรีเดียวกัน ซึ่งมีข้อมูลสรุปที่จัดรูปแบบแล้วซึ่งตัวแทนสร้างจากหน้าเว็บที่ใช้งานจริง
8. สานต่อการสนทนา
คุณมี digest.pdf อยู่แล้ว หากต้องการเพียงแค่ไฟล์ ก็ถือว่าเสร็จสิ้น ขั้นตอนนี้เกี่ยวข้องกับเรื่องอื่น นั่นคือการขอให้ตัวแทนเปลี่ยนข้อมูลสรุปโดยไม่ต้องดึงข้อมูลเว็บอีกครั้ง
Sandbox ยังคงใช้งานได้ Agent ยังคงมี/workspace/digest.pdfและจดจำทุกเรื่องราวที่สรุป การเรียกใช้interactions.create()ครั้งที่ 2 จะส่งข้อความติดตามผลไปยังแซนด์บ็อกซ์เดียวกัน ในที่นี้ คุณขอให้เพิ่มหมายเหตุ "เหตุผลที่เรื่องนี้สำคัญ" ใต้แต่ละเรื่อง และอัปเดต PDF ในตำแหน่งเดิมโดยไม่ต้องดึงข้อมูลหรือสรุปใหม่
สิ่งที่ต้องกรอก
เปิด refine_digest.py มีสิ่งที่ต้องทำ 3 รายการ
สิ่งที่ต้องทำ 1 และ 2: กรอกพารามิเตอร์การสนทนาไปมา 2 รายการภายใน interactions.create()
environment=environment_id,
previous_interaction_id=interaction_id,
environment=environment_id จะกลับมาใช้แซนด์บ็อกซ์เดิมพร้อมกับไฟล์และแพ็กเกจ previous_interaction_id=interaction_id ให้ประวัติการสนทนาแก่ Agent รายละเอียดส่วนอื่นๆ ยังคงเดิมจากครั้งแรก
TODO 3: คงค่า interaction_id ใหม่กลับไปที่ .env หลังจากวนรอบเหตุการณ์
save_env(INTERACTION_ID=interaction_id)
interactions.create() ทุกครั้งที่โทรออกจะสร้าง interaction_id ใหม่ การเขียนกลับหมายความว่าการเรียกใช้ครั้งถัดไปจะส่งการปรับแต่งนี้เป็น previous_interaction_id และการเชื่อมโยงจะทำงานอย่างถูกต้อง รหัสแซนด์บ็อกซ์จะไม่เปลี่ยนแปลง ENVIRONMENT_ID จึงไม่ต้องอัปเดต
พารามิเตอร์ 2 รายการที่ทำให้การสนทนาไปมาทำงานได้
รหัส | สิ่งที่ยังคงอยู่ | การเปรียบเทียบ |
| ไฟล์ แพ็กเกจที่ติดตั้ง สถานะระบบ: ทุกอย่างในระบบไฟล์ Linux | การใช้โต๊ะทำงานเดียวกันระหว่างการประชุม |
| ประวัติการสนทนา: สิ่งที่ Agent พูดและทำในรอบก่อนหน้า | จดจำเนื้อหาที่พูดคุยกันในการประชุมครั้งล่าสุด |
คุณจะส่งบัตรประจำตัวอย่างใดอย่างหนึ่งแยกกันได้
environment_idเท่านั้น: ใช้ไฟล์และแพ็กเกจซ้ำ แต่เริ่มการสนทนาใหม่ มีประโยชน์สำหรับงานใหม่ในพื้นที่ทำงานเดียวกันprevious_interaction_idเท่านั้น: ดำเนินบริบทการสนทนาต่อ แต่ในแซนด์บ็อกซ์ใหม่ (ไฟล์จะหายไป)- ทั้ง 2 อย่าง: ความต่อเนื่องเต็มรูปแบบ ซึ่งเป็นสิ่งที่ขั้นตอนนี้ใช้
ไม่มี environment_id: แซนด์บ็อกซ์เปล่า ไม่มี PDF หากไม่มี previous_interaction_id: ไม่มีบริบท ตัวแทนจะปรับแต่งส่วนที่เฉพาะเจาะจงไม่ได้
ยืนยัน
uv run python refine_digest.py
สตรีมควรจะรวดเร็ว เนื่องจาก Agent ไม่ได้ดึงข้อมูลใดๆ อีก หลังจากดำเนินการเสร็จแล้ว ให้ทำดังนี้
Refinement done.
Saved digest_v2.pdf (52,418 bytes)
เปิด digest_v2.pdf แล้วเปรียบเทียบกับ digest.pdf ตอนนี้แต่ละเรื่องควรมีบรรทัด "เหตุผลที่เรื่องนี้สำคัญ" เพิ่มเข้ามาแล้ว
9. คงการกำหนดค่า Agent ที่มีการจัดการ
การโทรทุกครั้งที่ผ่านมาผ่าน AGENTS.md, SKILL.md และ generate_pdf.py ในบรรทัด วิธีนี้ใช้ได้ แต่โค้ดที่เรียกใช้จะนำเนื้อหาไฟล์ทั้งหมดไปในการเรียกใช้ทุกครั้ง agents.create() จะฝังการกำหนดค่าลงในเอเจนต์ที่มีชื่อที่บันทึกไว้ในฝั่งของ Google การเรียกใช้ครั้งถัดไปจะส่งเฉพาะรหัสตัวแทน
Inline calls: send sources on every call
Named agent: bake once → invoke by ID, no sources
สิ่งที่ต้องกรอก
เปิด save_agent.py มีรายการสิ่งที่ต้องทำ 1 รายการ (สิ่งที่ต้องทำ 1)
โปรดทราบว่าค่าคงที่จะนำเข้าจาก run_digest.py โดยตรง (ไม่มีการทำซ้ำ)
from run_digest import BASE_AGENT, AGENTS_MD, SKILL_MD, GENERATE_PDF_PY
สิ่งที่ต้องทำ 1: กรอกข้อมูลในagents.create() call:
agent = client.agents.create(
id="my-digest",
base_agent=BASE_AGENT,
agent_config={
"type": "antigravity",
"model": "gemini-3.7-flash",
},
description="Daily tech digest with editorial voice and PDF generation.",
base_environment={
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/AGENTS.md",
"content": AGENTS_MD,
},
{
"type": "inline",
"target": ".agents/skills/digest-pdf/SKILL.md",
"content": SKILL_MD,
},
{
"type": "inline",
"target": ".agents/skills/digest-pdf/scripts/generate_pdf.py",
"content": GENERATE_PDF_PY,
},
],
},
)
agent_config จะตั้งค่าโมเดลพื้นฐาน gemini-3.7-flash เป็นค่าเริ่มต้นและเป็นตัวเลือกที่ดีที่สุดสำหรับเวิร์กโฟลว์นี้ ส่วน gemini-3.6-flash, gemini-3.5-flash และ gemini-3.5-flash-lite จะพร้อมใช้งานหากคุณต้องการรันที่มีน้ำหนักเบาหรือต้นทุนต่ำกว่า
base_environment (ไม่ใช่ environment) คือความแตกต่างที่สำคัญจากการเรียกใช้แบบอินไลน์ในขั้นตอนก่อนหน้า โดยแหล่งข้อมูลจะจัดเก็บไว้ที่ฝั่งของ Google และจะติดตั้งโดยอัตโนมัติในการเรียกใช้ครั้งต่อๆ ไป เรียกใช้เพียงครั้งเดียว ไม่ใช่ทุกครั้งที่เรียกใช้ข้อมูลสรุป
ยืนยัน: บันทึก Agent
uv run python save_agent.py
Saved: my-digest
my-digest: Daily tech digest with editorial voice and PDF generation.
เรียกใช้ Agent ที่บันทึกไว้
เปิด invoke_agent.py โดยจะเรียกใช้เอเจนต์ที่บันทึกไว้ตามรหัสโดยไม่มีแหล่งที่มา
stream = client.interactions.create(
agent="my-digest",
input="Generate the digest.",
stream=True,
environment="remote",
)
เปรียบเทียบกับคำสั่งเรียกใช้แบบอินไลน์: agent=BASE_AGENT จะแทนที่ด้วย "my-digest" และบล็อก environment แบบเต็มที่มีแหล่งที่มาแบบอินไลน์ 3 รายการจะแทนที่ด้วย environment="remote" การกำหนดค่าจะฝังไว้ในฝั่งของ Google อยู่แล้ว
ยืนยัน: เรียกใช้เอเจนต์ที่บันทึกไว้
uv run python invoke_agent.py
คุณควรเห็นไลฟ์สดเดียวกันกับการเรียกใช้แบบอินไลน์ แต่การเรียกใช้จะไม่มีไฟล์ต้นฉบับ หลังจากเรียกใช้แล้ว ระบบจะอัปเดต ENVIRONMENT_ID และ INTERACTION_ID ใน .env เพื่อให้คุณใช้ refine_digest.py ต่อไปได้เหมือนเดิม
[agent started]
[tool] read_file
[tool] write_file
[tool] run_code
I have successfully created today's tech news digest.
Done. environment_id=9a1c3e02-...
10. ส่งผ่าน Gmail
เอเจนต์ได้สร้างข้อมูลสรุปและบันทึกไว้ใน /workspace/digest.pdf แล้ว ตอนนี้คุณได้ดาวน์โหลดไฟล์นี้ไว้ในเครื่องแล้ว ขั้นตอนนี้จะส่งอีเมลไปยังกล่องจดหมายของคุณโดยตรงด้วยการให้ตัวแทนเรียก Gmail REST API จากภายในแซนด์บ็อกซ์
แนวทางคือคุณจะได้รับโทเค็นเพื่อการเข้าถึง OAuth 2.0 ในเครื่องและส่งไปยังเอเจนต์ในพรอมต์ input Agent ใช้ code_execution เพื่อสร้างอีเมล MIME ที่มีไฟล์ PDF แนบมาและ POST ไปยัง Gmail API ไม่มีเครื่องมือที่กำหนดเอง ไม่มีการลงทะเบียนเซิร์ฟเวอร์ MCP
ข้อกำหนดเบื้องต้น
เปิดใช้ Gmail API ในโปรเจ็กต์ GCP และสร้างรหัสไคลเอ็นต์ OAuth 2.0 โดยทำดังนี้
- ไปที่ console.cloud.google.com/apis/library/gmail.googleapis.com แล้วเปิดใช้ Gmail API
- ไปที่ API และบริการ > ข้อมูลเข้าสู่ระบบ > สร้างข้อมูลเข้าสู่ระบบ > รหัสไคลเอ็นต์ OAuth 2.0
- ประเภทแอปพลิเคชัน: แอปเดสก์ท็อป ดาวน์โหลด JSON และบันทึกเป็น
credentials.jsonในรูทของโปรเจ็กต์
เพิ่มอีเมลผู้รับใน .env ดังนี้
RECIPIENT_EMAIL=you@gmail.com
ติดตั้งไลบรารีการตรวจสอบสิทธิ์หากจำเป็น
uv sync
สิ่งที่ต้องกรอก
เปิด send_digest.py โดยมีสิ่งที่ต้องทำ 2 รายการ
TODO 1: โหลดหรือรีเฟรชโทเค็นเพื่อการเข้าถึง OAuth 2.0
creds = None
if TOKEN_FILE.exists():
creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
TOKEN_FILE.write_text(creds.to_json())
else:
flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
creds = flow.run_local_server(port=8080, open_browser=False)
TOKEN_FILE.write_text(creds.to_json())
นำบรรทัด raise NotImplementedError ออกหลังจากเพิ่มแล้ว เมื่อเรียกใช้เป็นครั้งแรก ระบบจะเปิดเบราว์เซอร์สำหรับหน้าจอขอความยินยอม OAuth ระบบจะแคชโทเค็นใน .gmail_token.json เพื่อการเรียกใช้ในอนาคต
TODO 2: แทนที่ input="" ด้วยวิธีการทางอีเมล โทเค็นอยู่ในขอบเขตอยู่แล้วในฐานะ creds.token
input=(
"Use the Gmail REST API to send an email:\n"
f" To: {recipient}\n"
" Subject: Tech Digest - <today's date in YYYY-MM-DD format>\n"
" Attachment: /workspace/digest.pdf attached as digest.pdf\n\n"
"For the body, read /workspace/summaries.json and format it as a "
"human-readable newsletter, NOT raw JSON. Use this structure:\n"
" Tech Digest - <date>\n\n"
" === <source name> ===\n"
" 1. <title>\n"
" <summary>\n\n"
"Steps:\n"
"1. Parse /workspace/summaries.json and build the formatted body text above.\n"
"2. Read /workspace/digest.pdf as bytes.\n"
"3. Build a MIME multipart message using Python's email library.\n"
"4. Base64url-encode the raw message.\n"
"5. POST to https://gmail.googleapis.com/gmail/v1/users/me/messages/send "
"with Authorization header using this token: "
f"{creds.token}"
),
หน้าที่ของแต่ละส่วน
การโต้ตอบจะกลับมาทำงานต่อในแซนด์บ็อกซ์เดียวกันกับที่ Agent สร้าง digest.pdf และ summaries.json ไว้แล้ว previous_interaction_id ให้ประวัติการสนทนากับเอเจนต์
ระบบจะส่งโทเค็นเพื่อการเข้าถึงในสตริง input Agent จะอ่านจากพรอมต์และใช้ในส่วนหัว Authorization: Bearer เมื่อเรียกใช้ Gmail API โดยจะไม่แตะต้องเครื่องหรือระบบไฟล์ในเครื่องของคุณ
เอเจนต์ใช้ code_execution เพื่อเขียนและเรียกใช้สคริปต์ Python ภายในแซนด์บ็อกซ์ โดยจะอ่าน summaries.json จัดรูปแบบเป็นจดหมายข่าว อ่าน digest.pdf สร้างข้อความ MIME แบบหลายส่วน เข้ารหัส base64url และ POST ไปยัง https://gmail.googleapis.com/gmail/v1/users/me/messages/send
ยืนยัน
uv run python send_digest.py
Sending digest...
[agent started]
[tool] read_file (/workspace/summaries.json)
[tool] run_code
[tool] run_code
Email sent successfully.
Email sent. Check your inbox.
โปรดตรวจสอบกล่องจดหมาย คุณจะได้รับอีเมลที่มีเนื้อหาในรูปแบบจดหมายข่าวและไฟล์ digest.pdf แนบมา
11. กำหนดเวลาการเรียกใช้รายวัน
ทุกขั้นตอนที่ผ่านมาเป็นการทริกเกอร์ด้วยตนเอง ทริกเกอร์ช่วยให้คุณกำหนดเวลาให้ Agent ที่ตั้งชื่อไว้ทำงานโดยอัตโนมัติตามนิพจน์ Cron ได้ Agent จะเริ่มทำงานตามเวลาที่กำหนด เรียกใช้เวิร์กโฟลว์สรุปข้อมูลทั้งหมด และสภาพแวดล้อมจะยังคงอยู่ระหว่างการดำเนินการเพื่อให้แพ็กเกจที่ติดตั้งในการเรียกใช้ครั้งแรกพร้อมใช้งานในการเรียกใช้ครั้งต่อๆ ไป
Manual: python run_digest.py → runs once, now
Trigger: client.triggers.create() → runs every morning, automatically
สิ่งที่ต้องกรอก
เปิด create_trigger.py มีสิ่งที่ต้องทำ 1 รายการ
สิ่งที่ต้องทำ 1: กรอกข้อมูลในtriggers.create()โทร ทริกเกอร์จะเรียกใช้เวิร์กโฟลว์ทั้งหมดในแต่ละวัน ได้แก่ สร้างสรุปและส่งไปยังกล่องจดหมาย เนื่องจากโทเค็นเพื่อการเข้าถึงจะหมดอายุใน 1 ชั่วโมง จึงจะแทรกโทเค็นการรีเฟรชจาก .gmail_token.json เป็นแหล่งที่มาแบบอินไลน์เพื่อให้ตัวแทนสามารถแลกเปลี่ยนเป็นโทเค็นใหม่ได้ในแต่ละครั้งที่เรียกใช้
trigger = client.triggers.create(
schedule="0 9 * * *",
time_zone="UTC",
display_name="daily-tech-digest",
max_consecutive_failures=3,
execution_timeout_seconds=600,
interaction={
"agent": "my-digest",
"input": (
f"Generate the daily tech digest following AGENTS.md instructions. "
f"Then send an email to {recipient}:\n"
"- Subject: Tech Digest - <today's date in YYYY-MM-DD format>\n"
"- Body: the content of /workspace/summaries.json formatted as a readable "
"newsletter (NOT raw JSON).\n"
"- Attachment: /workspace/digest.pdf\n\n"
"For Gmail auth: read /workspace/.gmail_creds.json, POST to "
"https://oauth2.googleapis.com/token with grant_type=refresh_token "
"and the client_id, client_secret, refresh_token from the file to get an "
"access_token. Then POST to "
"https://gmail.googleapis.com/gmail/v1/users/me/messages/send "
"with Authorization: Bearer <access_token>."
),
"environment": {
"type": "remote",
"sources": [
{
"type": "inline",
"target": "/workspace/.gmail_creds.json",
"content": gmail_creds,
}
],
},
},
)
execution_timeout_seconds=600 คือระยะหมดเวลาเริ่มต้น max_consecutive_failures=3 จะหยุดทริกเกอร์ชั่วคราวโดยอัตโนมัติหลังจากเรียกใช้ไม่สำเร็จ 3 ครั้งติดต่อกัน (ค่าเริ่มต้นของ API คือ 5 แต่ 3 จะระมัดระวังมากกว่าสำหรับเวิร์กช็อป)
sources จะแทรก .gmail_creds.json ลงในแซนด์บ็อกซ์ที่ /workspace/.gmail_creds.json Agent จะอ่านโทเค็นการรีเฟรช แลกเปลี่ยนเป็นโทเค็นเพื่อการเข้าถึงใหม่ และเรียกใช้ Gmail API โทเค็นเพื่อการรีเฟรชจะไม่มีวันหมดอายุ ดังนั้นจึงใช้ได้กับการเรียกใช้ที่กำหนดเวลาไว้ทุกครั้งโดยไม่ต้องรีเฟรชโทเค็นด้วยตนเอง
นำบรรทัด raise NotImplementedError ออกหลังจากเพิ่มการโทร
ยืนยัน
uv run python create_trigger.py
Trigger created: trig_abc123
Next run: 2026-07-23T09:00:00Z
create_trigger.py จะบันทึกรหัสทริกเกอร์ไปยัง .env โดยอัตโนมัติ
วิธีตรวจสอบประวัติการดำเนินการหลังการเรียกใช้
uv run python check_trigger.py
หากต้องการทริกเกอร์ทันทีโดยไม่ต้องรอเวลาที่กำหนดไว้ครั้งถัดไป ให้ทำดังนี้
uv run python fire_trigger.py
วิธีหยุดชั่วคราวหรือลบทริกเกอร์
uv run python pause_trigger.py
12. ล้าง
Sandbox จะหมดอายุโดยอัตโนมัติหลังจากไม่มีการใช้งานเป็นเวลา 7 วัน ไม่มีเซิร์ฟเวอร์ที่จะหยุด ไม่มีคอนเทนเนอร์ที่จะลบ
หากบันทึกการกำหนดค่าเอเจนต์ไว้ ให้ลบออกโดยทำดังนี้
uv run python delete_agent.py
13. สรุป
คุณสร้าง Agent ที่มีการจัดการตั้งแต่เริ่มต้นทีละแนวคิด แบบฝึกหัดแต่ละแบบสอนอะไรบ้าง
การออกกำลังกาย | แนวคิด | คีย์ API |
โทรครั้งแรก | จัดสรรแซนด์บ็อกซ์ Linux จริงและสตรีมเหตุการณ์แบบสด |
|
ปรับแต่ง Agent | ต่อเชื่อมไฟล์การกำหนดค่าและคงรหัสไว้ใน |
|
เพิ่มฮุกความปลอดภัย | ดักการเรียกใช้เครื่องมือก่อนที่จะดำเนินการ ปฏิเสธคำสั่งที่เป็นอันตราย |
|
ดาวน์โหลด PDF | ดาวน์โหลด PDF โดยไม่ต้องเรียกใช้ Agent อีกครั้ง | Gemini Files API |
สนทนาต่อ | สานต่อการสนทนาโดยไม่ต้องดึงข้อมูลเว็บอีกครั้ง |
|
คงการกำหนดค่า Agent | คงการกำหนดค่าเอเจนต์ เรียกใช้ตามรหัส ไม่ต้องใช้แหล่งที่มา |
|
ส่งผ่าน Gmail | รับโทเค็น OAuth ในเครื่อง แล้วส่งไปยังตัวแทน ซึ่งจะเรียกใช้ Gmail REST API ผ่าน | OAuth 2.0, |
ตั้งเวลาเรียกใช้ทุกวัน | เรียกใช้ Agent โดยอัตโนมัติตามกำหนดเวลา Cron |
|
รูปแบบสำคัญ
- การเรียกใช้ครั้งเดียว แซนด์บ็อกซ์เดียว:
interactions.create()จัดการโครงสร้างพื้นฐานทั้งหมด (ไม่ต้องติดตั้งใช้งานคอนเทนเนอร์ ไม่ต้องติดตั้งแพ็กเกจในเครื่อง) - การสตรีมแบบโพรเกรสซีฟ:
stream=Trueเปลี่ยนกล่องดำ 90 วินาทีให้เป็นฟีดสดของการเรียกใช้เครื่องมือและข้อความ - แหล่งข้อมูลในบรรทัด: ติดตั้ง
AGENTS.md,SKILL.mdและสคริปต์ที่สร้างไว้ล่วงหน้าลงในแซนด์บ็อกซ์โดยไม่ต้องอัปโหลดหรือขั้นตอนการติดตั้งใช้งาน - ใช้ประโยชน์จากการค้นหาอัตโนมัติ: ระบบจะเลือกไฟล์ที่วางไว้ใน
.agents/โดยอัตโนมัติ (ไม่ต้องกำหนดค่า SDK) - สถานะ 2 มิติ:
environment_idติดตามไฟล์และแพ็กเกจprevious_interaction_idติดตามบริบทการสนทนา โดยสามารถส่งได้แยกกัน - การดาวน์โหลดสแนปชอต: สภาพแวดล้อมคือไฟล์ tar ของระบบไฟล์แบบเต็ม ซึ่งเข้าถึงได้ผ่าน Gemini Files API
- ตัวแทนที่ระบุชื่อ:
agents.create()จะฝังการกำหนดค่าอย่างถาวร การเรียกในอนาคตจะส่งเฉพาะรหัสตัวแทนและenvironment="remote"โดยไม่มีแหล่งที่มา - Hook:
hooks.json+ สคริปต์เกตจะสกัดกั้นการเรียกใช้เครื่องมือก่อนที่จะดำเนินการdenyการตอบกลับจะยกเลิกการโทรและเจ้าหน้าที่จะแก้ไขด้วยตนเอง - การเรียก API ภายนอก: ส่งข้อมูลเข้าสู่ระบบในพรอมต์
inputเอเจนต์จะเขียนและเรียกใช้โค้ดการผสานรวมภายในแซนด์บ็อกซ์ผ่านcode_execution - ทริกเกอร์: กำหนดเวลา Agent ในนิพจน์ Cron ด้วย
client.triggers.create()สภาพแวดล้อมจะยังคงอยู่ในการดำเนินการต่างๆ
ADK + Cloud Run เทียบกับ Agent ที่ได้รับการจัดการ: ความแตกต่างโดยย่อ
ความสามารถ | ADK + Cloud Run | Agent ที่ได้รับการจัดการใน Gemini API |
จัดสรรแซนด์บ็อกซ์ |
|
|
กำหนดเครื่องมือ | ฟังก์ชัน Python ที่ลงทะเบียนกับเอเจนต์ | ในตัว: การท่องเว็บ การเรียกใช้โค้ด ระบบไฟล์ |
ติดตั้งแพ็กเกจ |
| Agent ทำงาน |
สตรีมกิจกรรม | โครงสร้างพื้นฐาน SSE ที่กำหนดเอง |
|
ดำเนินการต่อในเซสชัน | ฐานข้อมูลเซสชัน + การแทรกบริบท |
|
ไฟล์การกำหนดค่า | ฝังไว้ใน Agent หรือแทรกเมื่อเริ่มต้น | ติดตั้งผ่าน |
โครงสร้างพื้นฐานที่จะจัดการ | คอนเทนเนอร์, Cloud Run, IAM, ข้อมูลลับ | ไม่มี |