Genkit Python Agent Artifacts(Beta)实战指南:让 Agent 在会话中产出报告、文件与代码
【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills
导读
本篇指南围绕 Genkit Python 的 Agent Artifacts(Beta)功能展开,讲解如何让 Agent 在一次多轮会话(session)中产出带名字的交付物——报告、文件、代码片段,并通过chat.artifacts与res.artifacts随时读取。你将掌握三种核心用法:通过Artifacts()中间件给模型挂上write_artifact/read_artifact工具、在自定义 Agent 中直接调用sess.add_artifacts注入交付物,以及从TextPart中正确提取文本内容。本文以 agents-artifacts.md 为主干,并结合本仓库中 agents.md、agents-sessions.md、agents-custom.md、agents-state.md 等姊妹文档做纵深解读。
Artifacts 是什么:会话上的命名交付物
在 Genkit Python 的 Agent 模型中,一次会话(session)携带三层数据:消息历史(messages)、自定义状态(custom state,对应state_schema)、以及 Artifacts(详见 agents-state.md 开篇)。
Artifacts 是挂载在会话上的带名字的交付物——一份报告、一个文件、一段代码都可以成为 artifact。它可以从两个位置读取:
chat.artifacts:当前会话累积的所有 artifacts;res.artifacts:某次发送(chat.send)返回的响应中携带的 artifacts。
其典型语义是:Agent 在回答问题的同时,把"可复用的产出"(例如生成的poem.txt、report.md、补丁代码)以独立命名的实体沉淀下来,供后续轮次或宿主程序使用,而不是混在纯文本回复里。
方式一:通过Artifacts()中间件启用工具
Genkit 的中间件机制(Middleware)允许你为 Agent 组合文件系统、工具审批、技能加载、重试等能力(参考 agents.md 的 Middleware 一节)。其中Artifacts()中间件会为模型提供两个工具:
write_artifact:写入一个 artifact;read_artifact:读取已存在的 artifact。
一个关键语义是:写入同名 artifact 会覆盖旧版本。这意味着 artifact 的命名空间是"以名字为准"的,非常适合迭代式生成(先写草稿,再覆盖为最终版)。
官方示例(来自 agents-artifacts.md):
from genkit_google_genai import GoogleAI from genkit_middleware import Artifacts, Middleware from genkit import Genkit from genkit.agent import InMemorySessionStore ai = Genkit(plugins=[GoogleAI(), Middleware()]) agent = ai.define_agent( name='workspaceAgent', model='googleai/gemini-flash-latest', system='Use write_artifact for files. Use read_artifact to review them.', use=[Artifacts()], store=InMemorySessionStore(), ) chat = agent.chat() await chat.send('Write poem.txt with a short poem about Python agents.') print([a.name for a in chat.artifacts])拆解这段代码的要点:
- 插件组合:
Genkit(plugins=[GoogleAI(), Middleware()])—— 先注册Middleware()插件(一次性注册),再在use=[...]中传入Artifacts()实例(参考 agents.md 中"RegisterMiddleware()once, then pass instances inuse=[...]"的约定)。 - 系统提示引导:
system明确指示模型"用write_artifact写文件、用read_artifact复查",让模型在工具选择时优先使用 artifact 工具。 - 会话存储:传入
InMemorySessionStore(),让服务端拥有历史记录(该 Store 重启即失效,生产场景可换用 FileSessionStore)。 - 读取结果:
chat.send(...)之后,chat.artifacts即为模型本轮(以及此前各轮)写出的 artifact 列表,[a.name for a in chat.artifacts]即可列出所有交付物的名字。
重要限制:使用 Store 的 Agent(store-backed)不能在创建会话时用
chat(artifacts=...)预置 artifacts。官方文档给出的替代方案是二选一:让模型在第一轮对话中主动写出 artifact,或者在自定义 Agent 中调用add_artifacts(见下文方式二)。
方式二:在自定义 Agent 中直接注入 Artifacts
如果不想依赖模型自主调用工具,你可以通过自定义 Agent(define_custom_agent)手动管理 artifacts。Genkit 的SessionRunner暴露了get_artifacts/add_artifacts两个方法(见 agents-custom.md 的 "Fromsess" 一节),其中add_artifacts接收的是一个列表。
官方示例:
from genkit import Part, TextPart from genkit.agent import Artifact await sess.add_artifacts( [Artifact(name='report.md', parts=[Part(TextPart(text=body))])] )关键对象说明:
Artifact:一个命名的交付物,核心字段是name(名字)与parts(内容分片列表);Part:artifact 内容的载体;TextPart:承载纯文本的分片类型,text=body传入实际文本内容。
这种方式适合在自定义编排逻辑中(例如在handle_turn里完成多步骤处理后)把计算结果固化为 artifact 持久化到会话。注意add_artifacts与add_messages一样都要求传入list,即使只有一个 artifact 也要包一层列表。
方式三:无 Store 模式下的 Artifacts 往返传递
当你的应用自己管理历史(省略store参数)时,chat的 ids 保持为None,需要手动把 messages、state、artifacts 传给下一次chat(...)完成上下文衔接。这在 agents.md 的 "Without a store" 一节中有明确示范:
chat = agent.chat() await chat.send('My name is Ada. Remember it.') resumed = agent.chat( messages=chat.messages, state=chat.state, artifacts=chat.artifacts ) await resumed.send('What is my name? One word.')在这种模式下,artifacts 与 messages、state 处于同一往返协议:上一轮产生的chat.artifacts必须显式回传给新的chat(...),下一轮才能看到。这与 Store-backed 模式(服务端持有历史、按snapshot_id恢复)形成鲜明对比——后者不需要手动往返,这也是 agents-sessions.md 中"With a store, the server owns history"所强调的职责划分。
读取 Artifact 中的文本内容
Artifact 的parts使用 Pydantic 的RootModel结构:Part的根对象(.root)才是真正的分片内容。因此读取文本时必须判断根对象是否为TextPart,再从.root.text取值。官方给出的辅助函数:
from genkit import TextPart def artifact_text(artifact) -> str: return ''.join( p.root.text for p in (artifact.parts or []) if isinstance(p.root, TextPart) )要点:
artifact.parts or []:对可能为空的parts做了兜底,避免None遍历报错;isinstance(p.root, TextPart):仅收集文本分片,跳过其他类型的分片;p.root.text:RootModel 包装下,真正的文本位于.root.text,这也是该 API 在 Beta 阶段与普通 Pydantic 模型最大的使用差异。
与工具审批(ToolApproval)的联动
在启用ToolApproval中间件的场景中(参见 agents-human-in-the-loop.md),allowed_tools之外的工具会触发人机确认中断。当同时挂载Filesystem或Artifacts中间件时,需要特别注意:
- 若
write_artifact/read_artifact不在allowed_tools白名单中,模型的每次 artifact 写入都会暂停等待审批; - 官方建议:只自动放行读取类工具(如
read_file、read_artifact),对写入类工具(write_file、edit_file、write_artifact)要么显式加入白名单,要么有意让它们触发人工确认。
这与 agents.md 中 coding-agent 示例的配置哲学一致:ToolApproval(allowed_tools=['list_files', 'read_file', 'use_skill'])—— 默认只信任读取与技能加载。
组合场景:从"生成交付物"到"人工审批"再到"分叉迭代"
结合本仓库的 agents 文档体系,Artifacts 可以与其他能力无缝组合:
- 生成:
Artifacts()中间件 + 系统提示引导模型调用write_artifact,生成报告/文件; - 审批:若
write_artifact未列入ToolApproval.allowed_tools,写入前会触发INTERRUPTED,宿主可用resume(restart=[...])或resume(respond=[...])决定放行或拒绝; - 迭代/分叉:Store-backed 模式下每个快照(
snapshot_id)不可变,可以从同一检查点 fork 出多条分支(见 agents-branching.md),每条分支独立产出不同版本的 artifact 交付物; - 后台化:需要长时间产出报告时,可用
chat.detach(...)把任务交给服务端,拿到snapshot_id后随时回来取结果(见 agents-background.md)。
常见坑位小结
| 场景 | 正确做法 | 易错点 |
|---|---|---|
| Store-backed Agent 预置 artifacts | 让模型第一轮写出,或自定义 Agent 里add_artifacts | chat(artifacts=...)不生效 |
| 自定义 Agent 注入 artifacts | sess.add_artifacts([...])传list | 传单个Artifact而非列表 |
| 读取文本分片 | 判断isinstance(p.root, TextPart)后取p.root.text | 直接从p.text取值拿不到内容 |
| 无 Store 模式跨轮传递 | agent.chat(messages=..., state=..., artifacts=...)显式回传 | 忘记回传导致上下文丢失 |
| 工具审批与 artifact 写入 | 将write_artifact显式加入allowed_tools或有意中断 | 默认全部工具都需要人工确认 |
结语
Artifacts 是 Genkit Python Agent 中"会话交付物"的第一等公民:它让模型的产出不再是易失的纯文本,而是可命名、可覆盖、可跨轮引用的实体。无论是借助Artifacts()中间件让模型自主管理文件,还是在自定义 Agent 中程序化注入交付物,抑或在无 Store 场景下手动往返,本文给出的三种模式与代码均可直接复制运行(运行前提:Python 3.10+、uv、GEMINI_API_KEY环境变量,参见 SKILL.md 的前置条件)。需要更完整的 Agent 能力图谱时,可继续阅读 agents.md 及其链接的 sessions、HITL、branching、background、state、custom、HTTP 系列文档。
【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考