Agno Agent 运行时依赖注入与动态工具实战:dependencies、RunContext 与动态工具全解析 Agno Agent 运行时依赖注入与动态工具实战dependencies、RunContext 与动态工具全解析【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno本篇技术指南聚焦 Agno Agent 平台中的运行时依赖注入Runtime Dependency Injection与动态运行时输入机制。围绕 cookbook/02_agents/15_dependencies 目录下的三个可运行示例你将学会通过dependencies参数把数据源、函数与用户上下文注入 Agent 使其自动解析并拼入提示词让工具函数通过RunContext读取同一份依赖以及利用运行时会话状态session_state动态生成工具。读完你可以在不重写 Agent 与工具代码的前提下把任意实时数据、用户档案与上下文灵活接入自己的 Agno 应用。一、为什么需要运行时依赖注入在常规 Agent 编程中开发者容易陷入两难如果把数据如当前时间、用户档案、实时新闻直接写死在代码或系统提示词里Agent 每次运行都无法感知变化无法复用于不同用户与场景如果让 Agent 自行去抓取数据则每次对话都会引入多余的工具调用与延迟也难以控制数据来源与安全边界。Agno 给出的答案是运行时依赖注入把数据源、函数与上下文打包成一个dependencies字典交给 AgentAgent 在每次运行run时才去解析其中值——如果值是函数就调用它获取最新结果——并把解析结果注入上下文供提示词或工具使用。与常见的静态配置不同这种机制把数据与代码的绑定延迟到运行时让同一个 Agent 定义可以服务多个用户、多个项目、多种实时数据源。目录中三个示例分别演示了该能力的三种典型用法文件演示主题关键手法dependencies_in_context.pyDependencies In Context把函数字典经add_dependencies_to_context注入用户消息上下文dependencies_in_tools.pyDependencies In Tools工具函数通过RunContext.dependencies读取注入的数据源dynamic_tools.pyDynamic Tools依据session_state在运行时动态返回工具集二、把依赖注入上下文HackerNews 实时榜单第一个示例 dependencies_in_context.py 解决的是典型需求让 Agent 讨论今天 HackerNews 上发生了什么。作者没有给 Agent 配搜索工具而是把一个获取实时数据的 Python 函数作为依赖传进去。先看数据获取函数它使用httpx请求 HackerNews 公开 API拉取前 N 条 top stories并剔除kids评论线程字段以精简体积def get_top_hackernews_stories(num_stories: int 5) - str: Fetch and return the top stories from HackerNews. Args: num_stories: Number of top stories to retrieve (default: 5) Returns: JSON string containing story details (title, url, score, etc.) # Get top stories stories [ { k: v for k, v in httpx.get( fhttps://hacker-news.firebaseio.com/v0/item/{id}.json ) .json() .items() if k ! kids # Exclude discussion threads } for id in httpx.get( https://hacker-news.firebaseio.com/v0/topstories.json ).json()[:num_stories] ] return json.dumps(stories, indent4)接着创建 Agent 时把函数放进dependencies字典并打开add_dependencies_to_contextagent Agent( modelOpenAIResponses(idgpt-5.2), # Each function in the dependencies is resolved when the agent is run, # think of it as dependency injection for Agents dependencies{top_hackernews_stories: get_top_hackernews_stories}, # We can add the entire dependencies dictionary to the user message add_dependencies_to_contextTrue, markdownTrue, )启动后用户只需说一句agent.print_response( Summarize the top stories on HackerNews and identify any interesting trends., streamTrue, )关键原理可结合源码验证在 agent.py 中Agent的核心字段为dependencies: Optional[Dict[str, Any]] None与add_dependencies_to_context: bool False。当启用了add_dependencies_to_contextAgno 在拼装本轮用户消息时会遍历dependencies字典逐项把可调用对象调用一次、以字符串化结果写入上下文函数返回值便实时出现在模型面前——不需要任何工具调用模型直接看见最新的榜单 JSON。这正是代码注释中think of it as dependency injection for Agents的含义每次run都重新解析数据始终新鲜。三、让工具读取依赖RunContext 注入第一个示例解决了让模型看到数据但若工具自身需要访问用户档案、当前时间等上下文呢Agno 提供了RunContext机制只要工具签名里声明一个run_context: RunContext参数运行时 Agno 就会自动注入本次运行的完整上下文对象其中就包括dependencies字段。见 dependencies_in_tools.py。在 run/base.py 中RunContext携带了dependencies: Optional[Dict[str, Any]]等字段是 run 与工具之间传递运行态信息的统一载体。3.1 定义一个当前上下文生产函数def get_current_context() - dict: Get current contextual information like time, weather, etc. return { current_time: datetime.now().strftime(%Y-%m-%d %H:%M:%S), timezone: PST, day_of_week: datetime.now().strftime(%A), }注意它同样是普通函数——当它被放进dependencies时会在每次运行时被求值从而保证时间戳总是当下。3.2 工具通过 run_context.dependencies 取数据analyze_user是一个常规工具函数第一个参数user_id由模型生成但额外声明了run_context: RunContextdef analyze_user(user_id: str, run_context: RunContext) - str: Analyze a specific users profile and provide insights. ... Args: user_id: The user ID to analyze (e.g., john_doe, jane_smith) run_context: The run context containing dependencies (automatically provided) dependencies run_context.dependencies if not dependencies: return No data sources available for analysis. print(f-- Tool received data sources: {list(dependencies.keys())}) results [f USER ANALYSIS FOR {user_id.upper()} ] # Use user profile data if available if user_profile in dependencies: profile_data dependencies[user_profile] results.append(fProfile Data: {profile_data}) # Add analysis based on the profile if profile_data.get(role): results.append( fProfessional Analysis: {profile_data[role]} with expertise in {, .join(profile_data.get(preferences, []))} ) # Use current context data if available if current_context in dependencies: context_data dependencies[current_context] results.append(fCurrent Context: {context_data}) results.append( fTime-based Analysis: Analysis performed on {context_data[day_of_week]} at {context_data[current_time]} ) print(f-- Tool returned results: {results}) return \n\n.join(results)工具里通过run_context.dependencies拿到整个依赖字典再按键去取user_profile结构化数据或current_context这里存的是函数Agno 会自动先求值再注入。这正是依赖注入的精髓工具源码完全不写死数据只声明我需要什么 key数据从外部喂入因而同一套工具可服务不同数据源。3.3 在 run 调用时注入依赖Agent 定义只需声明工具与指令不携带任何数据agent Agent( modelOpenAIResponses(idgpt-5.2), tools[analyze_user], nameUser Analysis Agent, descriptionAn agent specialized in analyzing users using integrated data sources., instructions[ You are a user analysis expert with access to user analysis tools., When asked to analyze any user, use the analyze_user tool., This tool has access to user profiles and current context through integrated data sources., After getting tool results, provide additional insights and recommendations based on the analysis., Be thorough in your analysis and explain what the tool found., ], )数据在每次agent.run(...)时按需传入同时还可用session_id固定会话response agent.run( inputPlease analyze user john_doe and provide insights about their professional background and preferences., dependencies{ user_profile: { name: John Doe, preferences: [AI/ML, Software Engineering, Finance], location: San Francisco, CA, role: Senior Software Engineer, }, current_context: get_current_context, }, session_idtest_tool_dependencies, ) print(f\nAgent Response: {response.content})注意这里的dependencies混合了静态字典user_profile与可调用函数current_context说明 Agno 在运行时对二者都能正确解析。这也是多用户场景的推荐写法user_profile随每个请求变化不同用户不同档案而current_context保持同一份函数定义。3.4 与构造函数注入的对比细心的读者会发现dependencies既出现在Agent(...)构造函数agent.py也出现在run()方法签名中agent.py。二者语义如下构造时注入全局、对 Agent 的所有 run 都生效适合相对稳定的依赖如默认数据源run 时注入按次调用覆盖/补充适合随请求变化的依赖如当前用户、本次请求参数是实现一个 Agent 服务多用户的关键。_run.py中的实现见 agent/_run.py会遍历run_context.dependencies.items()做解析与格式化说明无论来自哪一层最终都会汇聚到RunContext.dependencies统一处理。四、动态工具随会话状态生成工具集第三种模式更进一步——工具本身也可以动态化。日常开发中工具列表常是固定的但多租户或按项目区分的场景下不同会话应该暴露不同的工具。Agno 支持把返回工具列表的函数传给toolsAgno 会携带RunContext调用它依据**会话状态session_state**决定暴露哪些工具。示例见 dynamic_tools.py。4.1 依据 session_state 返回工具def get_runtime_tools(run_context: RunContext): Return tools dynamically based on session state. def get_time() - str: return datetime.now(timezone.utc).isoformat() def get_project() - str: project (run_context.session_state or {}).get(project, unknown) return fCurrent project: {project} return [get_time, get_project]该函数的关键点通过run_context.session_state读取本次运行的会话状态在函数内部定义并返回新工具闭包天然捕获外层作用域可访问run_contextget_project的返回值随session_state中project字段变化实现面向项目的定制工具。4.2 把动态工具交给 Agentagent Agent( nameDynamic Tools Agent, modelOpenAIResponses(idgpt-5.2), toolsget_runtime_tools, # -- 传入函数而非列表 )注意这里tools接收的是get_runtime_tools这个函数本身而不是工具列表。运行时由 Agno 调用它、获得[get_time, get_project]再注册为模型可见的工具。4.3 运行时传入会话状态agent.print_response( Use available tools to report current context., session_state{project: cookbook-restructure}, streamTrue, )每次运行时传入不同的session_state动态工具就会给出不同的当前项目从而让工具具备项目感知能力。当模型询问当前项目get_project会返回Current project: cookbook-restructure。适用场景同一套 Agent 部署到多个团队/项目却希望各项目只暴露自己的工具与上下文或者需要根据用户权限、订阅等级裁剪工具面避免无权限的工具暴露给模型。五、三种模式的选型与组合三者并非互斥而是针对不同注入目标的分工可以灵活组合模式注入目标传入位置典型场景代表示例Dependencies in Context模型提示词Agent(dependencies..., add_dependencies_to_contextTrue)让模型直接看见实时数据零工具调用dependencies_in_context.pyDependencies in Tools工具函数agent.run(dependencies...) 工具声明run_context: RunContext工具需要用户档案/当前时间等上下文dependencies_in_tools.pyDynamic Tools工具集合本身Agent(tools返回工具的函数)run(session_state...)按项目/会话裁剪工具面dynamic_tools.py实际项目中的常见组合打法静态的全局数据公司知识库地址、默认区域放Agent(...)构造函数随请求变化的用户数据放每次run(dependencies...)工具用RunContext.dependencies消费想省去工具调用成本的实时榜单/行情用add_dependencies_to_contextTrue直接注入提示词按项目/租户差异用动态工具函数 session_state暴露不同工具。六、运行环境与前提在深入使用前先确保满足运行前提详见 README.md加载环境变量在项目根目录执行direnv allow其中需包含OPENAI_API_KEY示例默认使用 OpenAIResponses 模型创建演示虚拟环境运行仓库根目录下的./scripts/demo_setup.sh之后统一使用.venvs/demo/bin/python解释器依赖组件示例代码用到httpxHackerNews 拉取与 Agno 本体含 openai 相关模型包目录对应的依赖清单可参考同 cookbook 惯例的requirements.in/requirements.txt。个别 cookbook 还依赖本地服务如 pgvector或各家模型厂商的专属 API Key但本节三个示例无需外部数据库。运行单个示例的统一命令格式为.venvs/demo/bin/python cookbook/02_agents/15_dependencies/file.py例如分别执行三个示例.venvs/demo/bin/python cookbook/02_agents/15_dependencies/dependencies_in_context.py .venvs/demo/bin/python cookbook/02_agents/15_dependencies/dependencies_in_tools.py .venvs/demo/bin/python cookbook/02_agents/15_dependencies/dynamic_tools.py三个示例都带if __name__ __main__:入口可直接作为脚本运行其中dependencies_in_tools.py与dependencies_in_context.py分别演示同步run()与流式print_response(..., streamTrue)两种调用方式。关于模型的说明示例代码以OpenAIResponses(idgpt-5.2)编写属于展示性配置。依赖注入、RunContext与动态工具是 Agno Agent 层的通用能力与具体模型无关——若你没有对应模型凭据可替换为仓库 cookbook/90_models 中你已具备 key 的模型实现例如本地 Ollama 或其它 OpenAI 兼容模型机制完全一致。七、小结从写死上下文到运行时注入围绕 cookbook/02_agents/15_dependencies 的三个示例本指南覆盖了 Agno 运行时依赖注入的完整能力面依赖进入提示词dependenciesadd_dependencies_to_contextTrue让模型直接读到每次运行时新鲜解析的数据依赖进入工具RunContext.dependencies自动注入工具参数数据源与工具实现解耦工具本身动态化把返回工具的函数传给tools依据session_state决定暴露内容。这套机制把数据绑定从编码期推迟到运行期让一个 Agent 定义可以横向复用于不同用户、项目与实时数据源。更深层的上下文机制RunContext除dependencies外还承载会话状态等运行态信息可继续阅读 agent/_run.py 与 run/base.py 中对应实现理解 Agno 在每次运行时如何构建与传递上下文对象。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考