一、ADK是什么?谷歌的「智能体协作工具箱」

想象一下:如果让你搭建一个AI团队完成复杂任务,不需要从零编写协作逻辑,只需定义每个AI的角色、工具和工作流程,它们就能自动分工、传递信息、高效产出——这就是Google ADK(Agent Development Kit)的核心价值。
ADK是谷歌推出的多智能体开发框架,主打「代码优先、面向对象」的设计理念,让开发者通过实例化类的方式快速构建智能体(Agent),并通过内置的协作模式(顺序/并行/循环)实现智能体间的高效联动。它既深度集成Google Cloud、Vertex AI等谷歌生态,又支持通过LiteLLM连接100+主流LLM模型,兼顾了基础设施优化与模型灵活性。
最妙的是ADK的状态管理机制:所有智能体共享一个「全局状态池」(通过ToolContext实现),像一个团队共享的工作台,谁需要数据都能取,谁产出结果都能存——这正是剧本创作案例能顺畅流转的关键。
二、基础单元:LLM智能体(Agent)—— 每个角色都有专属技能
在ADK中,「智能体」是执行具体任务的最小单元,就像电影制作团队里的编剧、研究员、制片人,每个都有明确的「人设」和「技能包」。我们从剧本案例中拆解智能体的核心构成:
1. 智能体的「三要素」
Agent(
name="screenwriter", # 角色名称(如"编剧")
model=model_name, # 背后的LLM模型(如Gemini)
description="写传记片的大纲和logline", # 角色定位
instruction="...", # 具体工作指令(核心)
tools=[append_to_state], # 可调用的工具(技能)
generate_content_config=... # LLM生成配置(如温度)
)
- 名称与描述:明确智能体的身份,让其他智能体知道「该找谁帮忙」;
- 指令(instruction):最核心的「工作手册」,定义了智能体的任务目标、输入数据(如
{PLOT_OUTLINE?}表示读取状态中的大纲)、输出要求; - 工具(tools):智能体的「能力扩展」,可以是自定义函数(如
write_file写文件)、第三方工具(如案例中通过LangchainTool集成维基百科查询)。
2. 案例中的「明星智能体天团」
剧本案例里的5个基础智能体,完美复刻了电影前期制作的核心岗位:
- researcher(研究员):维基百科工具使用者,负责挖掘历史人物的真实细节,把资料存入「research」状态;
- screenwriter(编剧):根据用户需求(PROMPT)、研究资料(research)和反馈(CRITICAL_FEEDBACK),撰写/优化三幕式大纲;
- critic(评论家):质量把关人,检查大纲的结构、吸引力、历史真实性,合格就终止循环,不合格就提修改意见;
- box_office_researcher(票房分析师):预测影片市场潜力,输出票房报告;
- casting_agent(选角导演):根据大纲角色特点,推荐合适的演员。
每个智能体都「术业有专攻」,且通过append_to_state工具将产出存入全局状态,实现信息共享——这正是ADK智能体的核心优势:分工明确、数据互通。
三、协作模式:三大智能体编排术,让团队高效运转
如果只有单个智能体,顶多是个「AI工具人」;但ADK的精髓在于「协作」——通过SequentialAgent(顺序)、ParallelAgent(并行)、LoopAgent(循环)三种编排模式,让多个智能体像专业团队一样配合。剧本案例完美展示了这三种模式的应用:
1. 顺序智能体(SequentialAgent):流水线式传递,一步接一步
就像工厂流水线,智能体按顺序执行,前一个的输出是后一个的输入。案例中的film_concept_team就是典型:
film_concept_team = SequentialAgent(
sub_agents=[writers_room, preproduction_team, file_writer]
)
工作流程:
- 先让
writers_room(循环智能体)完成大纲打磨; - 再让
preproduction_team(并行智能体)做票房分析和选角; - 最后让
file_writer把所有结果写成剧本文件。
这种模式适合有明确先后依赖的任务——没有打磨好的大纲,票房分析和选角就成了无的放矢。
2. 并行智能体(ParallelAgent):多线程同步,节省时间
像团队里的不同部门同时推进工作,互不干扰,最后汇总结果。案例中的preproduction_team:
preproduction_team = ParallelAgent(
sub_agents=[box_office_researcher, casting_agent]
)
工作逻辑:
- 票房分析和选角推荐不需要互相等待,同时进行;
- 两个智能体都从全局状态读取
PLOT_OUTLINE,各自输出box_office_report和casting_report; - 最后同步将结果存入状态,供后续
file_writer使用。
这种模式直接解决了「串行执行耗时过长」的问题——如果先等票房分析再做选角,整体时间会翻倍,而并行模式能让效率最大化。
3. 循环智能体(LoopAgent):迭代优化,直到达标
这是ADK最强大的协作模式之一,适合需要「反复打磨、持续优化」的任务。案例中的writers_room(写作室)就是核心:
writers_room = LoopAgent(
sub_agents=[researcher, screenwriter, critic],
max_iterations=2 # 最多迭代2次,避免无限循环
)
工作闭环(像极了真实的编剧团队磨合):
- 第一轮:研究员查资料 → 编剧写大纲 → 评论家提反馈;
- 第二轮:研究员根据反馈补充资料 → 编剧优化大纲 → 评论家再审核;
- 终止条件:要么评论家认为大纲合格(调用
exit_loop工具),要么达到最大迭代次数。
这个循环完美复刻了「研究-创作-评审」的迭代流程,让大纲从「粗糙初稿」逐渐打磨成「合格剧本」,而这一切都是ADK自动完成的——不需要人工介入协调。
四、案例完整流程:从用户输入到剧本产出的全链路
现在我们把所有环节串起来,看看ADK是如何让「用户说一个历史人物」变成「完整剧本文件」的:
- 用户触发:
root_agent(迎宾智能体)问候用户,询问想写哪个历史人物; - 状态初始化:用户回复后,
root_agent用append_to_state将人物名称存入PROMPT状态,然后启动film_concept_team; - 大纲打磨(LoopAgent):
researcher从PROMPT读取人物,查维基百科,存入research;screenwriter结合PROMPT和research,写出初始大纲,存入PLOT_OUTLINE;critic审核大纲,提出修改意见(如「缺乏第二幕的冲突升级」),存入CRITICAL_FEEDBACK;- 第二轮迭代:
researcher补充冲突相关的历史细节,screenwriter优化大纲,critic最终通过;
- 前期筹备(ParallelAgent):
box_office_researcher和casting_agent同时工作,产出票房报告和选角建议; - 最终输出:
file_writer读取PLOT_OUTLINE、票房报告、选角建议,在movie_pitches目录下生成以电影名为文件名的txt文件。
整个过程中,开发者只需要定义「谁来做、做什么、怎么配合」,ADK自动处理信息传递、状态管理、协作调度——这就是多智能体框架的魅力:把复杂任务拆解给专业AI,让它们自动组队完成。
五、ADK的核心优势:为什么选择它?
- 协作逻辑内置:不需要手动编写智能体间的通信、状态同步代码,三大协作模式覆盖80%+复杂任务场景;
- 工具生态灵活:支持自定义工具(如
write_file)、Langchain工具(如维基百科)、谷歌云工具,无缝扩展智能体能力; - 状态管理优雅:通过
ToolContext实现全局状态共享,解决了多智能体数据传递的痛点; - 代码直观易维护:面向对象设计,智能体和协作模式都是独立类,修改某个角色或流程不影响整体架构。
六、趣味总结:ADK就像「AI团队的项目经理」
如果把每个智能体比作「有技能的员工」,ADK就是那个「懂业务、会调度的项目经理」:
- 它知道谁适合做什么(智能体角色定义);
- 它知道任务的先后顺序(SequentialAgent);
- 它知道哪些任务可以同时做(ParallelAgent);
- 它知道什么时候需要反复打磨(LoopAgent);
- 它还会管理团队的「共享文件柜」(状态管理)。
而剧本创作案例,就是这个「AI项目经理」成功操盘的一个项目——从用户的一个简单需求,到最终产出完整的剧本文件,全程自动化、专业化,让人不得不感叹:多智能体协作的时代,已经来了!
七、多智能体写剧本的代码
import os
import logging
import google.cloud.logging
from callback_logging import log_query_to_model, log_model_response
from dotenv import load_dotenv
from google.adk import Agent
from google.adk.agents import SequentialAgent, LoopAgent, ParallelAgent
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.langchain_tool import LangchainTool # import
from google.genai import types
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from google.adk.tools import exit_loop
cloud_logging_client = google.cloud.logging.Client()
cloud_logging_client.setup_logging()
load_dotenv()
model_name = os.getenv("MODEL")
print(model_name)
# Tools
def append_to_state(
tool_context: ToolContext, field: str, response: str
) -> dict[str, str]:
"""Append new output to an existing state key.
Args:
field (str): a field name to append to
response (str): a string to append to the field
Returns:
dict[str, str]: {"status": "success"}
"""
existing_state = tool_context.state.get(field, [])
tool_context.state[field] = existing_state + [response]
logging.info(f"[Added to {field}] {response}")
return {"status": "success"}
def write_file(
tool_context: ToolContext,
directory: str,
filename: str,
content: str
) -> dict[str, str]:
target_path = os.path.join(directory, filename)
os.makedirs(os.path.dirname(target_path), exist_ok=True)
with open(target_path, "w") as f:
f.write(content)
return {"status": "success"}
# Agents
file_writer = Agent(
name="file_writer",
model=model_name,
description="Creates marketing details and saves a pitch document.",
instruction="""
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
INSTRUCTIONS:
- Create a marketable, contemporary movie title suggestion for the movie described in the PLOT_OUTLINE. If a title has been suggested in PLOT_OUTLINE, you can use it, or replace it with a better one.
- Use your 'write_file' tool to create a new txt file with the following arguments:
- for a filename, use the movie title
- Write to the 'movie_pitches' directory.
- For the 'content' to write, include:
- The PLOT_OUTLINE
- The BOX_OFFICE_
""",
generate_content_config=types.GenerateContentConfig(
temperature=0,
),
tools=[write_file],
)
screenwriter = Agent(
name="screenwriter",
model=model_name,
description="As a screenwriter, write a logline and plot outline for a biopic about a historical character.",
instruction="""
INSTRUCTIONS:
Your goal is to write a logline and three-act plot outline for an inspiring movie about the historical character(s) described by the PROMPT: { PROMPT? }
- If there is CRITICAL_FEEDBACK, use those thoughts to improve upon the outline.
- If there is RESEARCH provided, feel free to use details from it, but you are not required to use it all.
- If there is a PLOT_OUTLINE, improve upon it.
- Use the 'append_to_state' tool to write your logline and three-act plot outline to the field 'PLOT_OUTLINE'.
- Summarize what you focused on in this pass.
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
RESEARCH:
{ research? }
CRITICAL_FEEDBACK:
{ CRITICAL_FEEDBACK? }
""",
generate_content_config=types.GenerateContentConfig(
temperature=0,
),
tools=[append_to_state],
)
researcher = Agent(
name="researcher",
model=model_name,
description="Answer research questions using Wikipedia.",
instruction="""
PROMPT:
{ PROMPT? }
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
CRITICAL_FEEDBACK:
{ CRITICAL_FEEDBACK? }
INSTRUCTIONS:
- If there is a CRITICAL_FEEDBACK, use your wikipedia tool to do research to solve those suggestions
- If there is a PLOT_OUTLINE, use your wikipedia tool to do research to add more historical detail
- If these are empty, use your Wikipedia tool to gather facts about the person in the PROMPT
- Use the 'append_to_state' tool to add your research to the field 'research'.
- Summarize what you have learned.
Now, use your Wikipedia tool to do research.
""",
generate_content_config=types.GenerateContentConfig(
temperature=0,
),
tools=[
LangchainTool(tool=WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())),
append_to_state,
],
)
critic = Agent(
name="critic",
model=model_name,
description="Reviews the outline so that it can be improved.",
instruction="""
INSTRUCTIONS:
Consider these questions about the PLOT_OUTLINE:
- Does it meet a satisfying three-act cinematic structure?
- Do the characters' struggles seem engaging?
- Does it feel grounded in a real time period in history?
- Does it sufficiently incorporate historical details from the RESEARCH?
If the PLOT_OUTLINE does a good job with these questions, exit the writing loop with your 'exit_loop' tool.
If significant improvements can be made, use the 'append_to_state' tool to add your feedback to the field 'CRITICAL_FEEDBACK'.
Explain your decision and briefly summarize the feedback you have provided.
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
RESEARCH:
{ research? }
""",
before_model_callback=log_query_to_model,
after_model_callback=log_model_response,
tools=[append_to_state, exit_loop]
)
writers_room = LoopAgent(
name="writers_room",
description="Iterates through research and writing to improve a movie plot outline.",
sub_agents=[
researcher,
screenwriter,
critic
],
max_iterations=2,
)
box_office_researcher = Agent(
name="box_office_researcher",
model=model_name,
description="Considers the box office potential of this film",
instruction="""
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
INSTRUCTIONS:
Write a report on the box office potential of a movie like that described in PLOT_OUTLINE based on the reported box office performance of other recent films.
""",
output_key="box_office_report"
)
casting_agent = Agent(
name="casting_agent",
model=model_name,
description="Generates casting ideas for this film",
instruction="""
PLOT_OUTLINE:
{ PLOT_OUTLINE? }
INSTRUCTIONS:
Generate ideas for casting for the characters described in PLOT_OUTLINE
by suggesting actors who have received positive feedback from critics and/or
fans when they have played similar roles.
""",
output_key="casting_report"
)
preproduction_team = ParallelAgent(
name="preproduction_team",
sub_agents=[
box_office_researcher,
casting_agent
]
)
film_concept_team = SequentialAgent(
name="film_concept_team",
description="Write a film plot outline and save it as a text file.",
sub_agents=[
writers_room,
preproduction_team,
file_writer
],
)
root_agent = Agent(
name="greeter",
model=model_name,
description="Guides the user in crafting a movie plot.",
instruction="""
- Let the user know you will help them write a pitch for a hit movie. Ask them for
a historical figure to create a movie about.
- When they respond, use the 'append_to_state' tool to store the user's response
in the 'PROMPT' state key and transfer to the 'film_concept_team' agent
""",
generate_content_config=types.GenerateContentConfig(
temperature=0,
),
tools=[append_to_state],
sub_agents=[film_concept_team],
)
1700

被折叠的 条评论
为什么被折叠?



