Global Context
RailTracks includes a concept of global context, letting you store and retrieve shared information across the lifecycle of a run. This makes it easy to coordinate data like config settings, environment flags, or shared resources.
What is Global Context?
The context system gives you a simple and clear API for interacting with shared values. It's scoped to the duration of a run, so everything is neatly contained within that execution lifecycle. One of the key features of the context system is that it can be accessed from within any node in your workflow, making it ideal for sharing data between different parts of your application.
Core Functions
You can use the context with the following main functions:
rt.context.get(key, default=None)
- Retrieves a value from the contextrt.context.put(key, value)
- Stores a value in the contextrt.context.update(dict)
- Updates multiple values in the context at oncert.context.delete(key)
- Removes a value from the context
Quick Start
Here’s how you can use context during a run:
import railtracks as rt
# Set up some context data
data = {"var_1": "value_1"}
with rt.Session(context=data):
rt.context.get("var_1") # Outputs: value_1
rt.context.get("var_2", "default_value") # Outputs: default_value
rt.context.put("var_2", "value_2") # Sets var_2 to value_2
rt.context.put("var_1", "new_value_1") # Replaces var_1 with new_value_1
Context in a Node
The context can be accessed from within any node in your RailTracks workflow, regardless of where the node is defined or how it's called:
Warning
The context only exists while the run is active. After that, it's gone.
Real-World Examples
Prevent Hallucinations in Agentic Systems
In agentic systems, you can use context to store important facts or constraints that agents will need to use. This helps reduce hallucinations by providing a reliable source of truth.
Example
import railtracks as rt
# Define a tool that uses context
@rt.function_node
def find_issue(input: str) -> str:
issue = get_issue_from_input(input) # Assume this function finds an issue number from the inpu
rt.context.put("issue_number", issue)
return issue
@rt.function_node
def comment_on_issue(comment: str):
try:
issue = rt.context.get("issue_number")
except KeyError:
return "No relevant issue is available."
comment_on_github_issue(issue, comment) # Assume this function comments on the issue
# Define the agent with the tool
GitHubAgent = rt.agent_node(
tool_nodes=[find_issue, comment_on_issue],
llm=rt.llm.OpenAILLM("gpt-4o"),
system_message="You are an agent that provides information based on important facts.",
)
# Run the agent
@rt.session()
async def gh_agent():
response = await rt.call(
GitHubAgent,
"What is the last issue created? Please write a comment on it."
)
Prompt Injection
One of the most powerful features built on top of the context system is "prompt injection" (also called "context injection"). This allows dynamically inserting values from the global context into prompts for LLMs:
Tip
For more details on prompt injection, see the Prompts and Context Injection documentation.
Benefits of Using Context
Why use the context system?
The context system provides several advantages over alternatives like global variables
- Safer and clearer way to manage shared values
- Makes runs more predictable
- Makes data easier to reason about
- Reduces repetitive code
- Keeps sensitive information out of LLM inputs
- Provides clean scoping tied to execution lifecycle