Skip to main content
Users author placeholders with an explicit namespace prefix: [[inputs.X]] / [[outputs.X]] / [[tools.X]]. The SDK rewrites them on Agent.new / Agent.save to the backend-canonical \{\{inputs.X\}\} / \{\{outputs.X\}\} / \{\{tools.\<tool_id>\}\} forms that the engine expects. Why the [[ ]] brackets: \{\{ and \}\} are reserved escape sequences in Python f-strings — authoring in \{\{ \}\} would force awkward f"\{\{\{\{topic\}\}\}\}" boilerplate. [[ ]] has no special meaning in f-strings so placeholders drop into normal interpolation cleanly. Why the required namespace prefix: if an input, output, and tool all share a name (say brief), a bare [[brief]] would be ambiguous. The v2 SDK rejects bare placeholders outright and asks the author to write [[inputs.brief]] / [[outputs.brief]] / [[tools.brief]] explicitly. What this demonstrates:
  • Input reference: [[inputs.topic]] -> {{inputs.topic}}
  • Output reference: [[outputs.brief]] -> {{outputs.brief}}
  • Tool by name: [[tools.google_search]] -> {{tools.<tool_id>}}
  • Tool by raw id: [[tools.<tool_id>]] -> {{tools.<tool_id>}}
  • Already-canonical {{inputs.topic}} content passes through unchanged
  • Bare [[topic]] is rejected with a TemplateReferenceError
This is a functional agent (type=FUNCTIONAL). Conversational agents bypass placeholder resolution — for those, use str(kb) / str(pipeline) etc. (see Example 17 / vs-context).
Source: examples/agents/19_template_placeholders.py in the SDK repo.