agency-context.mdx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. ---
  2. title: "Agency Context"
  3. description: "Sharing data and state across tools and agents using agency context."
  4. icon: "database"
  5. ---
  6. `Agency Context` is a centralized data store accessible by all tools and agents within an agency. It allows you to share data between agents, control execution flow, and maintain state across tool calls without passing large data structures in messages.
  7. <Note>
  8. Agency context is available when tools are deployed together with agents. If tools are deployed as separate APIs, they won't share the same context, and you'll need to implement your own state management solution.
  9. </Note>
  10. ## Understanding Agency Context
  11. Agency context is particularly useful when your agents interact with multiple tools that need to exchange information. Here's why:
  12. - **Without Agency Context**: Suppose `Tool A` collects data that `Tool B` needs. The agent must explicitly pass this data as a parameter to `Tool B`, consuming tokens and potentially hitting message limits.
  13. ![Without Agency Context](/images/shared-state-without.png)
  14. - **With Agency Context**: `Tool A` can store the required data in the agency context, and `Tool B` can retrieve it without needing direct parameter passing. This approach reduces complexity, saves tokens, and enables additional workflows.
  15. ![With Agency Context](/images/shared-state-with.png)
  16. ## Using Agency Context
  17. The agency context is accessible in both FunctionTools and BaseTools using `.get` and `.set`, which let you access and modify the MasterContext passed during execution.
  18. Below is an example of how it can be used across tools.
  19. In this example, calling the Query Database tool stores database context, which is later retrieved by the Answer Question tool.
  20. <Tabs>
  21. <Tab title="BaseTool">
  22. For BaseTools, access the agency context using `self.context`.
  23. ```python
  24. from agency_swarm.tools import BaseTool
  25. from pydantic import Field
  26. class QueryDatabase(BaseTool):
  27. """
  28. Retrieves data from the database and stores it in the agency context.
  29. """
  30. question: str = Field(..., description="The query to execute.")
  31. async def run(self):
  32. # Fetch data based on the question
  33. context = query_database_api(self.question)
  34. # Store the context in the agency context
  35. assert self.context is not None
  36. self.context.set('database_context', context)
  37. self.context.set('last_query', self.question)
  38. return "Database context has been retrieved and stored successfully."
  39. class AnswerQuestion(BaseTool):
  40. """
  41. Provides answers based on the context stored in the agency context.
  42. """
  43. async def run(self):
  44. # Access the stored context
  45. assert self.context is not None
  46. context = self.context.get('database_context')
  47. if not context:
  48. return "Database context is missing. Please call the query_database tool first."
  49. # Generate an answer using the context
  50. answer = f"Answer derived from context: {context}"
  51. return answer
  52. ```
  53. </Tab>
  54. <Tab title="Function Tool">
  55. For FunctionTools, access the context using the following methods:
  56. - **Setting** a value: `ctx.context.set('key', value)`
  57. - **Getting** a value: `ctx.context.get('key', default_value)`
  58. ```python
  59. from agency_swarm import MasterContext, RunContextWrapper, function_tool
  60. @function_tool
  61. async def query_database(ctx: RunContextWrapper[MasterContext], question: str) -> str:
  62. """
  63. Retrieves data from the database and stores it in the agency context.
  64. """
  65. # Fetch data based on the question
  66. context = query_database_api(question)
  67. # Store the context in the agency context
  68. ctx.context.set('database_context', context)
  69. ctx.context.set('last_query', question)
  70. return "Database context has been retrieved and stored successfully."
  71. @function_tool
  72. async def answer_question(ctx: RunContextWrapper[MasterContext]) -> str:
  73. """
  74. Provides answers based on the context stored in the agency context.
  75. """
  76. # Access the stored context
  77. context = ctx.context.get('database_context')
  78. if not context:
  79. return "Database context is missing. Please call the query_database tool first."
  80. # Generate an answer using the context
  81. answer = f"Answer derived from context: {context}"
  82. return answer
  83. ```
  84. </Tab>
  85. </Tabs>
  86. ## Advanced Agency Context Patterns
  87. ### Complex Data Structures
  88. Agency context can store any Python object, making it perfect for complex workflows:
  89. ```python
  90. @function_tool
  91. async def analyze_market_data(ctx: RunContextWrapper[MasterContext], symbols: str) -> str:
  92. """Analyzes multiple stocks and stores data."""
  93. symbol_list = symbols.split(',')
  94. market_analysis = {
  95. 'timestamp': datetime.now().isoformat(),
  96. 'symbols': {},
  97. 'summary': {},
  98. 'analyst': ctx.context.current_agent_name
  99. }
  100. for symbol in symbol_list:
  101. # Simulate market data fetch
  102. market_analysis['symbols'][symbol] = {
  103. 'price': 150.0,
  104. 'volume': 1000000,
  105. 'trend': 'bullish'
  106. }
  107. # Store in agency context
  108. ctx.context.set('market_analysis', market_analysis)
  109. ctx.context.set('analysis_complete', True)
  110. return f"Market analysis complete for {len(symbol_list)} symbols"
  111. ```
  112. ### Workflow Coordination
  113. Use agency context to coordinate multi-step workflows:
  114. ```python
  115. @function_tool
  116. async def step_1_data_collection(ctx: RunContextWrapper[MasterContext], params: str) -> str:
  117. """First step in a multi-step workflow."""
  118. # Perform step 1
  119. result = collect_data(params)
  120. # Store progress in agency context
  121. ctx.context.set('workflow_step_1', result)
  122. ctx.context.set('workflow_status', 'step_1_complete')
  123. return "Step 1 complete. Ready for step 2."
  124. @function_tool
  125. async def step_2_data_processing(ctx: RunContextWrapper[MasterContext]) -> str:
  126. """Second step that depends on first step."""
  127. # Check if step 1 is complete
  128. if ctx.context.get('workflow_status') != 'step_1_complete':
  129. return "Error: Step 1 must be completed first"
  130. # Get data from step 1
  131. step_1_data = ctx.context.get('workflow_step_1')
  132. # Process the data
  133. result = process_data(step_1_data)
  134. # Update progress
  135. ctx.context.set('workflow_step_2', result)
  136. ctx.context.set('workflow_status', 'step_2_complete')
  137. return "Step 2 complete. Workflow finished."
  138. ```
  139. ### Session Management
  140. Agency context is perfect for maintaining session state:
  141. ```python
  142. # Initialize agency with session context
  143. agency = Agency(
  144. entry_agent,
  145. communication_flows=[(entry_agent, worker_agent)],
  146. user_context={
  147. 'session_id': 'user_123',
  148. 'user_preferences': {
  149. 'language': 'en',
  150. 'timezone': 'UTC',
  151. 'risk_tolerance': 'moderate'
  152. },
  153. 'session_start': datetime.now().isoformat()
  154. }
  155. )
  156. ```
  157. ## Best Practices
  158. ### Use Descriptive Keys
  159. Use clear, descriptive keys to avoid conflicts between different agents and workflows:
  160. ```python
  161. # Good: Descriptive keys
  162. ctx.context.set('user_portfolio_analysis_2024', data)
  163. ctx.context.set('market_data_AAPL_realtime', market_data)
  164. # Avoid: Generic keys that might conflict
  165. ctx.context.set('data', data)
  166. ctx.context.set('result', result)
  167. ```
  168. ### Provide Default Values
  169. Always provide sensible defaults when retrieving data:
  170. ```python
  171. # Good: Provides default
  172. user_prefs = ctx.context.get('user_preferences', {})
  173. risk_level = ctx.context.get('risk_tolerance', 'moderate')
  174. # Risky: No default, might return None
  175. risk_level = ctx.context.get('risk_tolerance')
  176. ```
  177. ### Clean Up Unneeded Data
  178. For long-running sessions, clean up temporary data to avoid memory issues:
  179. ```python
  180. @function_tool
  181. async def cleanup_temporary_data(ctx: RunContextWrapper[MasterContext]) -> str:
  182. """Cleans up temporary analysis data."""
  183. temp_keys = ['temp_calculation_1', 'temp_calculation_2', 'scratch_data']
  184. for key in temp_keys:
  185. if key in ctx.context.user_context:
  186. del ctx.context.user_context[key]
  187. return "Temporary data cleaned up successfully"
  188. ```
  189. ## Migrating tools
  190. If you're migrating from Agency Swarm v0.x, and want to use new FunctionTool instead of BaseTool, here's how you can do that:
  191. **BaseTool Pattern:**
  192. ```python
  193. class MyTool(BaseTool):
  194. async def run(self):
  195. assert self.context is not None
  196. self.context.set("key", "value")
  197. data = self.context.get("key", "default")
  198. return "Done"
  199. ```
  200. **FunctionTool Pattern:**
  201. ```python
  202. @function_tool
  203. async def my_tool(ctx: RunContextWrapper[MasterContext], param: str) -> str:
  204. """Updated tool using agency context."""
  205. ctx.context.set("key", "value")
  206. data = ctx.context.get("key", "default")
  207. return "Done"
  208. ```
  209. ## Example: Complete Workflow
  210. For a full example showing agency context in action, see the [Agency Context Workflow Example](https://github.com/VRSEN/agency-swarm/blob/main/examples/agency_context.py) which demonstrates:
  211. - Multi-step data collection and analysis
  212. - Cross-agent data sharing
  213. - Session management
  214. - Workflow coordination
  215. - Context monitoring and debugging
  216. Agency context eliminates the need for complex parameter passing and enables multi-agent workflows while maintaining clean separation of concerns.