Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,64 @@ async def analyze_call_feedback(input: CallFeedbackInput) -> CallFeedbackOutput:
> a newer version of the same model with the same or a lower price so calling the api with
> a retired model will always work.

### Using templated instructions

You can use [Jinja2](https://jinja.palletsprojects.com/)-style templating in your agent's instructions (docstring) to make them dynamic based on input values. The template variables are automatically populated from the fields in your input model.

```python
class CodeReviewInput(BaseModel):
language: str = Field(description="Programming language of the code")
style_guide: str = Field(description="Style guide to follow")
is_production: bool = Field(description="Whether this is a production review")
focus_areas: list[str] = Field(description="Areas to focus on during review", default_factory=list)

class CodeReviewOutput(BaseModel):
"""Output from a code review."""
issues: list[str] = Field(
default_factory=list,
description="List of identified issues or suggestions for improvement"
)
compliments: list[str] = Field(
default_factory=list,
description="List of positive aspects and good practices found in the code"
)
summary: str = Field(
description="A brief summary of the code review findings"
)

@workflowai.agent(id="code-review")
async def review_code(review_input: CodeReviewInput) -> CodeReviewOutput:
"""
You are a code reviewer for {{ language }} code.
Please review according to the {{ style_guide }} style guide.

{% if is_production %}
This is a PRODUCTION review - be extra thorough and strict.
{% else %}
This is a development review - focus on maintainability.
{% endif %}

{% if focus_areas %}
Key areas to focus on:
{% for area in focus_areas %}
{{ loop.index }}. {{ area }}
{% endfor %}
{% endif %}
"""
...
```

The template uses [Jinja2](https://jinja.palletsprojects.com/) syntax and supports common templating features including:

- Variable substitution: `{{ variable }}`
- Conditionals: `{% if condition %}...{% endif %}`
- Loops: `{% for item in items %}...{% endfor %}`
- Loop indices: `{{ loop.index }}`

See the [Jinja2 documentation](https://jinja.palletsprojects.com/) for the full template syntax and capabilities.

We recommend using ChatGPT or CursorAI to help generate the template.

### Version from code or deployments

Setting a docstring or a model in the agent decorator signals the client that the agent parameters are
Expand Down
180 changes: 180 additions & 0 deletions examples/14_templated_instructions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
"""
This example demonstrates how to use templated instructions that adapt based on input variables.
The template variables are automatically populated from the input model's fields.

The templating uses Jinja2 syntax (server-side rendering):
- {{ variable }} for variable substitution
- {% if condition %} ... {% endif %} for conditionals
- {% for item in items %} ... {% endfor %} for loops
- {{ loop.index }} for loop indices

For full Jinja2 template syntax documentation, see:
https://jinja.palletsprojects.com/en/stable/

It showcases:
1. Simple variable substitution
2. Conditional logic
3. Loops
4. Nested conditionals
"""

import asyncio

from pydantic import BaseModel, Field

import workflowai
from workflowai import Model, Run


class CodeReviewInput(BaseModel):
"""Input model for the code review agent."""

language: str = Field(
description="The programming language of the code to review",
examples=["python", "javascript", "typescript"],
)
code: str = Field(
description="The code to review",
)
style_guide: str = Field(
description="The style guide to follow",
examples=["PEP 8", "Google Style", "Airbnb"],
)
is_production: bool = Field(
description="Whether this is a production code review",
default=False,
)
required_checks: list[str] = Field(
description="List of specific checks to perform",
default=["code style", "performance", "maintainability"],
)
security_level: str = Field(
description="Required security level",
default="standard",
examples=["standard", "high"],
)


class CodeReviewOutput(BaseModel):
"""Output model containing the code review results."""

overall_assessment: str = Field(
description="Overall assessment of the code quality",
)
style_violations: list[str] = Field(
description="List of style guide violations",
)
security_issues: list[str] = Field(
description="List of security concerns",
default_factory=list,
)
suggested_improvements: list[str] = Field(
description="List of suggested improvements",
)


@workflowai.agent(
id="templated-code-reviewer",
model=Model.CLAUDE_3_5_SONNET_LATEST,
)
async def review_code(review_input: CodeReviewInput) -> Run[CodeReviewOutput]:
"""
Review code based on specified parameters and guidelines.

You are a code reviewer for {{ language }} code.
Please review the code according to the {{ style_guide }} style guide.

{% if is_production %}
This is a PRODUCTION code review - please be extra thorough and strict about best practices.
{% else %}
This is a development code review - focus on maintainability and clarity.
{% endif %}

Required checks to perform:
{% for check in required_checks %}{{ loop.index }}. {{ check }}
{% endfor %}

{% if security_level == "high" %}
Additional security requirements:
- Must follow secure coding practices
- Check for potential security vulnerabilities
- Ensure all inputs are properly sanitized
{% endif %}

Guidelines:
1. Check for adherence to {{ style_guide }} conventions
2. Look for potential bugs and performance issues
3. Suggest improvements while keeping the {{ language }} best practices in mind

{% if language == "python" %}
Python-specific checks:
- Type hints usage
- PEP 8 compliance
- Docstring format
{% elif language == "javascript" or language == "typescript" %}
JavaScript/TypeScript-specific checks:
- ESLint rules compliance
- Modern ES6+ features usage
- Browser compatibility
{% endif %}

Please analyze the following code and provide:
1. An overall assessment
2. Style guide violations
3. Security issues (if any)
4. Suggested improvements

The code is:
{{ code }}
"""
...


async def main():
# Example 1: Python code review for development
print("\nExample 1: Python Development Code Review")
print("-" * 50)
python_code = """
def calculate_sum(numbers):
result = 0
for n in numbers:
result = result + n
return result
"""

run = await review_code(
CodeReviewInput(
language="python",
code=python_code,
style_guide="PEP 8",
required_checks=["type hints", "docstring", "performance"],
),
)
print(run)

# Example 2: TypeScript production code with high security
print("\nExample 2: TypeScript Production Code Review (High Security)")
print("-" * 50)
typescript_code = """
function processUserData(data: any) {
const userId = data.id;
const query = `SELECT * FROM users WHERE id = ${userId}`;
return executeQuery(query);
}
"""

run = await review_code(
CodeReviewInput(
language="typescript",
code=typescript_code,
style_guide="Airbnb",
is_production=True,
security_level="high",
required_checks=["security", "type safety", "SQL injection"],
),
)
print(run)


if __name__ == "__main__":
asyncio.run(main())