1. ภาพรวม
โลกของ AI และเทคโนโลยีเปลี่ยนแปลงเร็วกว่าที่ใครๆ จะตามทัน โมเดล งานวิจัย และผลิตภัณฑ์ใหม่ๆ จะเปิดตัวทุกวัน เอเจนต์สรุปข่าวที่ดึงพาดหัวข่าวของวันนี้ เขียนสรุปที่กระชับ และสร้าง PDF ทุกเช้าจะช่วยแก้ปัญหานี้ได้ แต่การสร้างเอเจนต์ดังกล่าวต้องเลือกเฟรมเวิร์ก กำหนดเครื่องมือใน Python เขียนลูปการจัดระเบียบ แพ็กเกจคอนเทนเนอร์ และติดตั้งใช้งานใน Cloud Run ทั้งหมดนี้เกิดขึ้นก่อนที่เอเจนต์จะส่งคำขอเว็บแม้แต่รายการเดียว
Agent ที่ได้รับการจัดการใน Gemini API จะเปลี่ยนสมการ คุณเขียนไฟล์การกำหนดค่า Markdown 2 ไฟล์และสคริปต์ตัวแสดงผลที่สร้างไว้ล่วงหน้า ทำการเรียก API 1 ครั้ง และแซนด์บ็อกซ์ Ubuntu จริงจะบูต เรียกดูเว็บ เขียนข้อมูลสรุป และสร้าง PDF ไม่มีคอนเทนเนอร์ ไม่มีการทำให้ใช้งานได้ ไม่ต้องเขียนโค้ดการจัดการเป็นกลุ่ม
ใน Codelab นี้ คุณจะได้สร้าง Agent ดังกล่าว ตั้งแต่ฟังก์ชันว่างไปจนถึงสรุปประจำวันที่ใช้งานได้ โดยทีละแนวคิด
สิ่งที่คุณจะสร้าง
- สร้างและเรียกใช้เอเจนต์ที่มีการจัดการตัวแรกในแซนด์บ็อกซ์ Linux จริง
- ปรับแต่งเอเจนต์ด้วยวิธีการโดยละเอียด
- ดาวน์โหลดเอาต์พุต PDF ของเอเจนต์
- สนทนาต่อเพื่อปรับแต่งสรุปโดยไม่ต้องดึงข้อมูลเว็บอีกครั้ง
- บันทึกการกำหนดค่าเอเจนต์และเรียกใช้ตามรหัสในการเรียกใช้ในอนาคต
สิ่งที่คุณต้องมี
- Python 3.10 ขึ้นไป
- คีย์ Gemini API ที่เปิดใช้การเรียกเก็บเงิน: aistudio.google.com/api-keys
- เครดิต API ประมาณ$1 (การเรียกใช้แต่ละครั้งมีค่าใช้จ่าย $0.30-$1.30)
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="",
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 ไปก่อน — TODO เหล่านี้มีไว้สำหรับขั้นตอนถัดไป):
from google import genai
client = genai.Client()
stream = client.interactions.create(
agent=BASE_AGENT,
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.5 Flash โดยมาพร้อมเครื่องมือในตัว 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การสตรีมช่วยให้คุณเห็นเหตุผลของตัวแทนและดำเนินการได้ทันที การสตรีมไม่ใช่ฟีเจอร์ขั้นสูงในที่นี้ แต่เป็นค่าเริ่มต้นที่เหมาะสม เนื่องจากกล่องดำ 90 วินาทีไม่ได้ให้สัญญาณใดๆ เกี่ยวกับว่าตัวแทนกำลังทำงานหรือติดขัด
สิ่งที่คุณเพิ่งจัดสรร: การเรียกใช้ interactions.create() ทุกครั้งจะเริ่มต้นแซนด์บ็อกซ์เฉพาะ
ส่วนประกอบ | ข้อมูลจำเพาะ |
ระบบปฏิบัติการ | สภาพแวดล้อม Ubuntu Linux ที่แยกต่างหาก |
รันไทม์ที่ติดตั้งไว้ล่วงหน้า | Python 3.12, Node.js 22, Bash |
Compute | CPU 4 แกน, RAM 16 GB |
การจัดการบริบท | การบีบอัดอัตโนมัติจะทริกเกอร์ที่โทเค็นประมาณ 135,000 รายการ |
เครือข่าย | การเข้าถึงเว็บขาออกผ่านพร็อกซีขาออก |
เอเจนต์สามารถติดตั้งแพ็กเกจใดก็ได้ที่มี pip หรือ npm อ่านและเขียนไฟล์ รวมถึงส่งคำขอเว็บขาออก เราจะไม่แตะต้องเครื่องและข้อมูลเข้าสู่ระบบของคุณ
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 เป็น "":
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}") ทันที
set_key(".env", "ENVIRONMENT_ID", environment_id)
set_key(".env", "INTERACTION_ID", interaction_id)
(set_key นำเข้าที่ด้านบนของ 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. ดาวน์โหลด 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 ในไดเรกทอรีเดียวกัน ซึ่งมีข้อมูลสรุปที่จัดรูปแบบแล้วซึ่งเอเจนต์สร้างจากหน้าเว็บที่ใช้งานจริง
7. สานต่อการสนทนา
คุณมี digest.pdf อยู่แล้ว หากต้องการเพียงแค่ไฟล์ ก็ถือว่าเสร็จสิ้น ขั้นตอนนี้เกี่ยวข้องกับสิ่งอื่น นั่นคือการขอให้ Agent เปลี่ยนข้อมูลสรุปโดยไม่ต้องดึงข้อมูลเว็บอีกครั้ง
Sandbox ยังคงใช้งานได้ เอเจนต์ยังคงมี /workspace/digest.pdf และจดจำทุกเรื่องราวที่สรุป การinteractions.create()เรียกใช้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 จะให้ประวัติการสนทนาแก่เอเจนต์ ไม่มีการเปลี่ยนแปลงอื่นใดจากการโทรครั้งแรก
TODO 3: คงค่า interaction_id ใหม่ไว้ใน .env หลังจากวนรอบเหตุการณ์
set_key(".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 ตอนนี้แต่ละเรื่องควรมีบรรทัด "ทำไมถึงสำคัญ" เพิ่มเข้ามาแล้ว
8. คงการกำหนดค่า 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,
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,
},
],
},
)
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="",
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-...
9. ล้าง
Sandbox จะหมดอายุโดยอัตโนมัติหลังจากไม่มีการใช้งานเป็นเวลา 7 วัน ไม่มีเซิร์ฟเวอร์ที่จะหยุด ไม่มีคอนเทนเนอร์ที่จะลบ
หากบันทึกการกำหนดค่าเอเจนต์ไว้ ให้ลบออกโดยทำดังนี้
uv run python delete_agent.py
10. สรุป
คุณสร้าง Agent ที่มีการจัดการตั้งแต่เริ่มต้นทีละแนวคิด แบบฝึกหัดแต่ละแบบสอนอะไรบ้าง
การออกกำลังกาย | แนวคิด | คีย์ API |
โทรครั้งแรก | จัดสรรแซนด์บ็อกซ์ Linux จริงและสตรีมเหตุการณ์แบบสด |
|
ปรับแต่ง Agent | ต่อเชื่อมไฟล์การกำหนดค่าและคงรหัสไว้ใน |
|
ดาวน์โหลด PDF | ดาวน์โหลด PDF โดยไม่ต้องเรียกใช้ Agent อีกครั้ง | Gemini Files API |
สนทนาต่อ | สานต่อการสนทนาโดยไม่ต้องดึงข้อมูลเว็บอีกครั้ง |
|
คงการกำหนดค่า Agent | คงการกำหนดค่าตัวแทน เรียกใช้ตามรหัส ไม่ต้องระบุแหล่งที่มา |
|
รูปแบบสำคัญ
- การเรียกใช้ครั้งเดียว แซนด์บ็อกซ์เดียว:
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"โดยไม่มีแหล่งที่มา
ADK + Cloud Run กับ Agent ที่ได้รับการจัดการ: ความแตกต่างโดยย่อ
ความสามารถ | ADK + Cloud Run | Agent ที่ได้รับการจัดการใน Gemini API |
จัดสรรแซนด์บ็อกซ์ |
|
|
กำหนดเครื่องมือ | ฟังก์ชัน Python ที่ลงทะเบียนกับเอเจนต์ | ในตัว: การท่องเว็บ การเรียกใช้โค้ด ระบบไฟล์ |
ติดตั้งแพ็กเกจ |
| Agent ทำงาน |
สตรีมกิจกรรม | โครงสร้างพื้นฐาน SSE ที่กำหนดเอง |
|
ดำเนินการต่อในเซสชัน | ฐานข้อมูลเซสชัน + การแทรกบริบท |
|
ไฟล์การกำหนดค่า | ฝังไว้ใน Agent หรือแทรกเมื่อเริ่มต้น | ติดตั้งผ่าน |
โครงสร้างพื้นฐานที่จะจัดการ | คอนเทนเนอร์, Cloud Run, IAM, ข้อมูลลับ | ไม่มี |