谷歌ADK:让AI智能体组队写剧本,多智能体协作的黑科技揭秘

一、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]
)

工作流程

  1. 先让writers_room(循环智能体)完成大纲打磨;
  2. 再让preproduction_team(并行智能体)做票房分析和选角;
  3. 最后让file_writer把所有结果写成剧本文件。

这种模式适合有明确先后依赖的任务——没有打磨好的大纲,票房分析和选角就成了无的放矢。

2. 并行智能体(ParallelAgent):多线程同步,节省时间

像团队里的不同部门同时推进工作,互不干扰,最后汇总结果。案例中的preproduction_team

preproduction_team = ParallelAgent(
    sub_agents=[box_office_researcher, casting_agent]
)

工作逻辑

  • 票房分析和选角推荐不需要互相等待,同时进行;
  • 两个智能体都从全局状态读取PLOT_OUTLINE,各自输出box_office_reportcasting_report
  • 最后同步将结果存入状态,供后续file_writer使用。

这种模式直接解决了「串行执行耗时过长」的问题——如果先等票房分析再做选角,整体时间会翻倍,而并行模式能让效率最大化。

3. 循环智能体(LoopAgent):迭代优化,直到达标

这是ADK最强大的协作模式之一,适合需要「反复打磨、持续优化」的任务。案例中的writers_room(写作室)就是核心:

writers_room = LoopAgent(
    sub_agents=[researcher, screenwriter, critic],
    max_iterations=2  # 最多迭代2次,避免无限循环
)

工作闭环(像极了真实的编剧团队磨合)

  1. 第一轮:研究员查资料 → 编剧写大纲 → 评论家提反馈;
  2. 第二轮:研究员根据反馈补充资料 → 编剧优化大纲 → 评论家再审核;
  3. 终止条件:要么评论家认为大纲合格(调用exit_loop工具),要么达到最大迭代次数。

这个循环完美复刻了「研究-创作-评审」的迭代流程,让大纲从「粗糙初稿」逐渐打磨成「合格剧本」,而这一切都是ADK自动完成的——不需要人工介入协调。

四、案例完整流程:从用户输入到剧本产出的全链路

现在我们把所有环节串起来,看看ADK是如何让「用户说一个历史人物」变成「完整剧本文件」的:

  1. 用户触发root_agent(迎宾智能体)问候用户,询问想写哪个历史人物;
  2. 状态初始化:用户回复后,root_agentappend_to_state将人物名称存入PROMPT状态,然后启动film_concept_team
  3. 大纲打磨(LoopAgent)
    • researcherPROMPT读取人物,查维基百科,存入research
    • screenwriter结合PROMPTresearch,写出初始大纲,存入PLOT_OUTLINE
    • critic审核大纲,提出修改意见(如「缺乏第二幕的冲突升级」),存入CRITICAL_FEEDBACK
    • 第二轮迭代:researcher补充冲突相关的历史细节,screenwriter优化大纲,critic最终通过;
  4. 前期筹备(ParallelAgent)box_office_researchercasting_agent同时工作,产出票房报告和选角建议;
  5. 最终输出file_writer读取PLOT_OUTLINE、票房报告、选角建议,在movie_pitches目录下生成以电影名为文件名的txt文件。

整个过程中,开发者只需要定义「谁来做、做什么、怎么配合」,ADK自动处理信息传递、状态管理、协作调度——这就是多智能体框架的魅力:把复杂任务拆解给专业AI,让它们自动组队完成。

五、ADK的核心优势:为什么选择它?

  1. 协作逻辑内置:不需要手动编写智能体间的通信、状态同步代码,三大协作模式覆盖80%+复杂任务场景;
  2. 工具生态灵活:支持自定义工具(如write_file)、Langchain工具(如维基百科)、谷歌云工具,无缝扩展智能体能力;
  3. 状态管理优雅:通过ToolContext实现全局状态共享,解决了多智能体数据传递的痛点;
  4. 代码直观易维护:面向对象设计,智能体和协作模式都是独立类,修改某个角色或流程不影响整体架构。

六、趣味总结: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],
)

### 实现使用 ADK 与 DeepSeek 运维大模型的流式输出智能体代码 Google ADKAgent Development Kit)是一个用于构建智能体的开发工具包,支持流式输出、状态更新和步骤处理[^4]。结合 DeepSeek 运维大模型,可以实现高效的运维场景交互,例如实时问题诊断、自动化脚本生成等任务。 以下是一个基于 Python 的示例代码,展示如何使用 ADK 和 DeepSeek 模型实现流式输出的智能体逻辑。该示例使用了 `langchain` 框架,并通过流式回调机制实现逐字输出: ```python from langchain.chat_models import ChatOllama from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.prompts import PromptTemplate from langchain.chains import LLMChain # 配置 Ollama 模型,使用 DeepSeek 模型并启用流式输出 llm = ChatOllama( model="deepseek-r1:32b", base_url="http://192.168.0.120:11434", callbacks=[StreamingStdOutCallbackHandler()] ) # 定义提示模板 prompt = PromptTemplate.from_template("你是一个运维助手,请回答以下问题:{question}") # 构建 LLM Chain chain = LLMChain(llm=llm, prompt=prompt) # 启动交互式问答 while True: question = input("请输入运维问题: ") if not question.strip(): print("问题不能为空,请重新输入!") continue print("\nDeepSeek 运维助手: \n") response = chain.run(question) print("\n-----------------------------------------") ``` ### 关键功能说明 - **流式输出支持**:通过 `StreamingStdOutCallbackHandler` 实现流式响应,用户在输入问题后可以立即看到模型的输出内容,而不是等待整个响应生成完毕。 - **ADK 集成**:Google ADK 提供了状态更新和步骤处理能力,可以用于构建更复杂的智能体流程,例如文件解析、API 调用、状态跟踪等[^4]。 - **运维场景适配**:DeepSeek 模型具备强大的自然语言理解和轮对话能力,适用于运维场景中的问题解答、故障诊断、命令推荐等任务。 ### 应用场景 - 实时运维助手:用户输入问题后,模型即时返回诊断建议,并通过流式输出提升交互体验。 - 自动化脚本生成:根据用户描述生成相应的运维脚本,并逐步展示生成过程。 - 步骤流程处理:结合 ADK 的状态更新功能,实现阶段任务处理,例如文件上传、解析、分析和输出。 ### 优化建议 - **提升响应速度**:可以调整 Ollama 的模型参数(如 `temperature`、`max_tokens`)来优化响应速度,确保流式输出的流畅性。 - **本地部署优化**:确保 Ollama 服务部署在高性能硬件上,并使用 GPU 加速推理过程,以减少延迟。 - **智能体状态管理**:使用 ADK 的状态管理功能,记录用户交互历史,提升上下文理解能力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jacky_wxl(微信同号)

喜欢作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值