AgentOS 依赖传递机制深度解读

1. 什么是 AgentOS 依赖传递?

AgentOS 依赖传递是一种强大的机制,允许在运行时向 Agent 注入动态上下文和参数。通过这种方式,您可以创建更加灵活、可配置的 Agent 系统,适应各种复杂的业务场景。


友情链接: 借一步  背多分   ACEJoy


 

2. 核心概念

2.1 依赖(Dependencies)

依赖是指在 Agent 执行过程中需要的动态参数或上下文信息。依赖可以是:
– 基本数据类型(字符串、数字、布尔值等)
– 复杂数据类型(字典、列表等)
– 可调用对象(函数、方法等)
– 协程函数(仅在异步环境中支持)

2.2 模板变量

模板变量是指在 Agent 指令或用户消息中使用的占位符,格式为 {variable_name}。这些变量会在运行时被依赖中的对应值替换。

2.3 运行上下文(RunContext)

运行上下文是存储依赖和其他运行时信息的对象,贯穿整个 Agent 运行过程。

3. 示例代码分析

让我们详细分析 pass_dependencies_to_agent.py 示例代码:

3.1 代码结构

"""Example for AgentOS to show how to pass dependencies to an agent."""

from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.os import AgentOS

Setup the database


db = PostgresDb(id="basic-db", db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

Setup basic agents, teams and workflows


story_writer = Agent(
id="story-writer-agent",
name="Story Writer Agent",
db=db,
markdown=True,
instructions="You are a story writer. You are asked to write a story about a robot. Always name the robot {robot_name}",
)

Setup our AgentOS app


agent_os = AgentOS(
description="Example AgentOS to show how to pass dependencies to an agent",
agents=[story_writer],
)
app = agent_os.get_app()


if __name__ == "__main__":
"""Run your AgentOS.

Test passing dependencies to an agent:
curl --location 'http://localhost:7777/agents/story-writer-agent/runs'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'message=Write me a 5 line story.'
--data-urlencode 'dependencies={"robot_name": "Anna"}'
"""
agent_os.serve(app="pass_dependencies_to_agent:app", reload=True)

3.2 关键组件解析

#### 3.2.1 数据库设置

db = PostgresDb(id="basic-db", db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

– 创建了一个 Postgres 数据库实例,用于存储 Agent 的运行数据
id 参数用于标识数据库实例
db_url 参数指定了数据库连接 URL

#### 3.2.2 Agent 创建

story_writer = Agent(
id="story-writer-agent",
name="Story Writer Agent",
db=db,
markdown=True,
instructions="You are a story writer. You are asked to write a story about a robot. Always name the robot {robot_name}",
)

– 创建了一个故事编写 Agent
idname 参数用于标识和命名 Agent
db 参数指定了 Agent 使用的数据库
markdown=True 表示 Agent 的输出将使用 Markdown 格式
instructions 参数包含了 Agent 的核心指令,其中 {robot_name} 是一个模板变量,将在运行时被替换

#### 3.2.3 AgentOS 应用设置

agent_os = AgentOS(
description="Example AgentOS to show how to pass dependencies to an agent",
agents=[story_writer],
)
app = agent_os.get_app()

– 创建了一个 AgentOS 应用实例
description 参数描述了应用的功能
agents 参数指定了应用中包含的 Agent 列表
get_app() 方法返回一个 FastAPI 应用实例,用于启动 Web 服务

#### 3.2.4 启动服务

if __name__ == "__main__":
agent_os.serve(app="pass_dependencies_to_agent:app", reload=True)

– 启动 AgentOS 服务
app 参数指定了要启动的应用
reload=True 表示在开发模式下自动重载代码

4. 依赖传递流程

4.1 API 调用示例

curl --location 'http://localhost:7777/agents/story-writer-agent/runs' 
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'message=Write me a 5 line story.'
--data-urlencode 'dependencies={"robot_name": "Anna"}'

这个 curl 命令演示了如何通过 API 向 Agent 传递依赖:
message 参数包含了用户请求
dependencies 参数包含了要传递的依赖,这里是 {"robot_name": "Anna"}

4.2 依赖传递的完整流程

1. 接收请求:AgentOS 接收 API 请求,包含用户消息和依赖
2. 创建运行上下文:为当前运行创建一个 RunContext 对象
3. 传递依赖:将 dependencies 中的值存储到 RunContext
4. 解析依赖:如果依赖是可调用对象,执行它们并将结果存储到 RunContext
5. 模板替换:使用 RunContext 中的依赖值替换 Agent 指令和用户消息中的模板变量
– 替换前:"You are a story writer. You are asked to write a story about a robot. Always name the robot {robot_name}"
– 替换后:"You are a story writer. You are asked to write a story about a robot. Always name the robot Anna"
6. 模型调用:将处理后的消息发送给 LLM 模型
7. 返回结果:将模型生成的结果返回给用户

5. 依赖的类型和使用

5.1 基本数据类型依赖

最常见的依赖类型是基本数据类型,如字符串、数字等:

# API 调用示例
dependencies={"robot_name": "Anna", "story_length": 5}

对应的 Agent 指令


instructions="You are a story writer. Write a {story_length} line story about a robot named {robot_name}"

5.2 复杂数据类型依赖

依赖也可以是复杂数据类型,如字典或列表:

# API 调用示例
dependencies={
"robot": {
"name": "Anna",
"type": "service robot",
"color": "blue"
},
"story_elements": ["adventure", "friendship", "discovery"]
}

对应的 Agent 指令


instructions="You are a story writer. Write a story about a {robot.type} named {robot.name} with the following elements: {story_elements}"

5.3 可调用对象依赖

依赖可以是函数或方法,这些函数会在运行时被执行,其结果会被用作依赖值:

# 定义一个依赖函数
def get_current_time(run_context):
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

代码调用示例


agent.run(
"Write a story about a robot created on {creation_date}",
dependencies={"creation_date": get_current_time}
)

当依赖是可调用对象时,Agent 会根据其签名自动注入以下参数:
agent:当前 Agent 实例
run_context:当前运行上下文对象

6. 依赖的作用域

6.1 全局依赖

全局依赖是在 Agent 初始化时定义的,对所有运行有效:

story_writer = Agent(
id="story-writer-agent",
instructions="You are a story writer. Always name the robot {robot_name}",
dependencies={"robot_name": "DefaultRobot"} # 全局依赖
)

6.2 局部依赖

局部依赖是在运行时传递的,仅对当前运行有效,会覆盖全局依赖:

# API 调用示例,局部依赖会覆盖全局依赖
dependencies={"robot_name": "Anna"}

7. 技术实现细节

7.1 依赖解析机制

Agent 提供了两种依赖解析方法:
同步解析_resolve_run_dependencies – 用于同步执行场景
异步解析_aresolve_run_dependencies – 用于异步执行场景

依赖解析过程包括以下步骤:
1. 验证依赖是否为字典类型
2. 逐个处理依赖项
3. 如果值是可调用对象,执行它并获取结果
4. 将结果更新到 RunContext
5. 如果值是普通值,直接存储到 RunContext

7.2 模板替换机制

模板替换是通过 Python 的字符串格式化功能实现的,使用 str.format(**dependencies) 方法将模板变量替换为实际值。

7.3 依赖的注入参数

当依赖是可调用对象时,Agent 会使用反射机制分析其签名,并自动注入以下参数:
agent:当前 Agent 实例
run_context:当前运行上下文对象

8. 最佳实践

8.1 使用明确的依赖键名

选择清晰、描述性的键名,便于理解和维护:

# 好的做法
dependencies={"robot_name": "Anna", "story_genre": "science fiction"}

不好的做法


dependencies={"rn": "Anna", "sg": "scifi"}

8.2 避免依赖之间的相互依赖

依赖的解析顺序是不确定的,因此不建议在依赖函数中引用其他依赖项:

# 不推荐的做法
dependencies={
"robot_name": "Anna",
"story_title": lambda run_context: f"The Adventures of {run_context.dependencies['robot_name']}" # 依赖其他依赖项
}

8.3 合理使用全局和局部依赖

– 全局依赖用于通用配置
– 局部依赖用于动态值

# 全局依赖用于通用配置
story_writer = Agent(
instructions="You are a {role} writing {genre} stories",
dependencies={"role": "story writer", "genre": "science fiction"} # 全局依赖
)

局部依赖用于动态值


agent.run(
"Write a story about a robot",
dependencies={"robot_name": "Anna"} # 局部依赖
)

8.4 处理依赖解析错误

依赖函数可能会抛出异常,确保有适当的错误处理:

def get_robot_name(run_context):
try:
# 可能会失败的操作
return get_robot_name_from_external_service()
except Exception as e:
# 提供默认值或处理错误
return "DefaultRobot"

8.5 使用类型注解

为依赖函数添加类型注解,提高代码可读性和可维护性:

def get_current_time(run_context: RunContext) -> str:
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

9. 常见问题和解决方案

9.1 依赖不生效

问题:模板变量没有被正确替换

解决方案
1. 检查依赖键名是否与模板变量名匹配
2. 检查依赖是否正确传递
3. 检查依赖值是否为预期类型

9.2 依赖函数执行失败

问题:依赖函数抛出异常

解决方案
1. 在依赖函数中添加适当的错误处理
2. 确保依赖函数的签名正确
3. 检查依赖函数所需的外部资源是否可用

9.3 依赖解析顺序问题

问题:依赖之间存在相互依赖,导致解析失败

解决方案
1. 避免依赖之间的相互依赖
2. 如果必须依赖其他依赖项,可以将它们合并到一个依赖函数中

10. 扩展应用场景

10.1 多 Agent 协作

在多 Agent 协作场景中,可以使用依赖传递机制在 Agent 之间共享上下文:

# 创建多个 Agent
story_writer = Agent(
id="story-writer-agent",
instructions="You are a story writer. Write a story about {topic}",
)

story_editor = Agent(
id="story-editor-agent",
instructions="You are a story editor. Edit the following story: {story}",
)

在工作流中传递依赖


workflow = Workflow(
id="story-creation-workflow",
steps=[
Step(agent=story_writer, output_key="story"),
Step(agent=story_editor, dependencies={"story": "{{steps.story.output}}"})
]
)

10.2 动态配置 Agent 行为

可以使用依赖传递机制动态配置 Agent 的行为:

# 创建一个可配置的 Agent
configurable_agent = Agent(
id="configurable-agent",
instructions="You are a {role}. {additional_instructions}",
)

根据不同场景传递不同的配置


agent.run(
"Perform the requested task",
dependencies={
"role": "customer service representative",
"additional_instructions": "Be polite and helpful"
}
)

agent.run(
"Perform the requested task",
dependencies={
"role": "technical support engineer",
"additional_instructions": "Provide detailed technical information"
}
)

11. 总结

AgentOS 依赖传递机制是一个强大的工具,允许您创建灵活、可配置的 Agent 系统。通过合理使用依赖传递,您可以:

1. 动态配置 Agent 行为
2. 在运行时注入上下文信息
3. 实现 Agent 之间的协作
4. 创建更加灵活和可扩展的应用

掌握依赖传递机制对于构建复杂的 AgentOS 应用至关重要。希望本文能帮助您深入理解 AgentOS 依赖传递的工作原理和最佳实践,为您的 Agent 开发之旅提供指导。

12. 进一步学习资源

AgentOS 官方文档
FastAPI 文档
PostgreSQL 文档

通过不断学习和实践,您将能够充分利用 AgentOS 依赖传递机制,构建出更加智能、灵活和强大的 Agent 应用。

留下评论

人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 借一步网 沪ICP备2024052574号-1