From 036b032ab65ab9c2ea5ab14750b16e8b226b75fb Mon Sep 17 00:00:00 2001
From: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
Date: Wed, 10 Jun 2026 17:52:53 -0700
Subject: [PATCH] handle supporting both custom prompts (#6108)
* handle supporting both custom prompts
* handle translations
* handle deprecation warnings better
---
.../guides/advanced/customizing-prompts.mdx | 14 ++++++
.../guides/advanced/customizing-prompts.mdx | 14 ++++++
.../guides/advanced/customizing-prompts.mdx | 16 ++++++-
.../guides/advanced/customizing-prompts.mdx | 14 ++++++
.../crewai/agents/agent_builder/base_agent.py | 10 ++++
lib/crewai/tests/agents/test_agent.py | 46 +++++++++++++++++++
6 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/docs/ar/guides/advanced/customizing-prompts.mdx b/docs/ar/guides/advanced/customizing-prompts.mdx
index c760f828c..b16c3b0b0 100644
--- a/docs/ar/guides/advanced/customizing-prompts.mdx
+++ b/docs/ar/guides/advanced/customizing-prompts.mdx
@@ -161,6 +161,18 @@ crew = Crew(
)
```
+
+يُحتفظ بـ `agent.i18n` للتوافق مع الإصدارات السابقة فقط، وقد تم إهماله. لتخصيص المطالبات أثناء التشغيل، مرّر `prompt_file` إلى `Crew`. وللوصول البرمجي المباشر إلى شرائح المطالبات، استخدم أداة i18n مباشرة:
+
+
+```python
+from crewai.utilities.i18n import get_i18n
+
+i18n = get_i18n("custom_prompts.json")
+format_slice = i18n.slice("format")
+tool_prompt = i18n.tools("ask_question")
+```
+
#### الخيار 3: تعطيل مطالبات النظام لنماذج o1
```python
agent = Agent(
@@ -208,6 +220,8 @@ agent = Agent(
يدمج CrewAI بعد ذلك تخصيصاتك مع الإعدادات الافتراضية، فلا تحتاج لإعادة تعريف كل مطالبة. إليك الطريقة:
+بالنسبة للكود الذي يحتاج إلى قراءة شرائح المطالبات مباشرة، استخدم `crewai.utilities.i18n.get_i18n()` مع ملف المطالبات نفسه بدلًا من قراءة `agent.i18n`.
+
### مثال: تخصيص أساسي للمطالبات
أنشئ ملف `custom_prompts.json` بالمطالبات التي تريد تعديلها. تأكد من إدراج جميع المطالبات عالية المستوى التي يجب أن يحتويها، وليس فقط تغييراتك:
diff --git a/docs/en/guides/advanced/customizing-prompts.mdx b/docs/en/guides/advanced/customizing-prompts.mdx
index 80fc4eff1..00132b5b1 100644
--- a/docs/en/guides/advanced/customizing-prompts.mdx
+++ b/docs/en/guides/advanced/customizing-prompts.mdx
@@ -161,6 +161,18 @@ crew = Crew(
)
```
+
+`agent.i18n` is maintained only for backward compatibility and is deprecated. For runtime prompt customization, pass `prompt_file` to `Crew`. For programmatic access to prompt slices, use the i18n utility directly:
+
+
+```python
+from crewai.utilities.i18n import get_i18n
+
+i18n = get_i18n("custom_prompts.json")
+format_slice = i18n.slice("format")
+tool_prompt = i18n.tools("ask_question")
+```
+
#### Option 3: Disable System Prompts for o1 Models
```python
agent = Agent(
@@ -208,6 +220,8 @@ One straightforward approach is to create a JSON file for the prompts you want t
CrewAI then merges your customizations with the defaults, so you don't have to redefine every prompt. Here's how:
+For code that needs to read prompt slices directly, use `crewai.utilities.i18n.get_i18n()` with the same prompt file instead of reading `agent.i18n`.
+
### Example: Basic Prompt Customization
Create a `custom_prompts.json` file with the prompts you want to modify. Ensure you list all top-level prompts it should contain, not just your changes:
diff --git a/docs/ko/guides/advanced/customizing-prompts.mdx b/docs/ko/guides/advanced/customizing-prompts.mdx
index e157c9e95..c65b86abe 100644
--- a/docs/ko/guides/advanced/customizing-prompts.mdx
+++ b/docs/ko/guides/advanced/customizing-prompts.mdx
@@ -161,6 +161,18 @@ crew = Crew(
)
```
+
+`agent.i18n`은 이전 버전과의 호환성을 위해서만 유지되며 사용이 중단될 예정입니다. 런타임 프롬프트 커스터마이징에는 `Crew`에 `prompt_file`을 전달하세요. 프롬프트 슬라이스를 코드에서 직접 읽어야 한다면 i18n 유틸리티를 직접 사용하세요:
+
+
+```python
+from crewai.utilities.i18n import get_i18n
+
+i18n = get_i18n("custom_prompts.json")
+format_slice = i18n.slice("format")
+tool_prompt = i18n.tools("ask_question")
+```
+
#### 옵션 3: o1 모델에 대한 시스템 프롬프트 비활성화
```python
agent = Agent(
@@ -208,6 +220,8 @@ agent = Agent(
그러면 CrewAI가 기본값과 사용자가 지정한 내용을 병합하므로, 모든 프롬프트를 다시 정의할 필요가 없습니다. 방법은 다음과 같습니다:
+프롬프트 슬라이스를 코드에서 직접 읽어야 하는 경우에는 `agent.i18n`을 읽는 대신 동일한 프롬프트 파일로 `crewai.utilities.i18n.get_i18n()`을 사용하세요.
+
### 예시: 기본 프롬프트 커스터마이징
수정하고 싶은 프롬프트를 포함하는 `custom_prompts.json` 파일을 생성하세요. 변경 사항만이 아니라 포함해야 하는 모든 최상위 프롬프트를 반드시 나열해야 합니다:
@@ -314,4 +328,4 @@ CrewAI에서의 저수준 prompt 커스터마이제이션은 매우 맞춤화되
이제 CrewAI에서 고급 prompt 커스터마이징을 위한 기초를 갖추었습니다. 모델별 구조나 도메인별 제약에 맞춰 적용하든, 이러한 저수준 접근 방식은 agent 상호작용을 매우 전문적으로 조정할 수 있게 해줍니다.
-
\ No newline at end of file
+
diff --git a/docs/pt-BR/guides/advanced/customizing-prompts.mdx b/docs/pt-BR/guides/advanced/customizing-prompts.mdx
index b91d5540d..ad1d7b096 100644
--- a/docs/pt-BR/guides/advanced/customizing-prompts.mdx
+++ b/docs/pt-BR/guides/advanced/customizing-prompts.mdx
@@ -161,6 +161,18 @@ crew = Crew(
)
```
+
+`agent.i18n` é mantido apenas para compatibilidade retroativa e está obsoleto. Para customização de prompts em tempo de execução, passe `prompt_file` para `Crew`. Para acesso programático aos slices de prompt, use diretamente o utilitário de i18n:
+
+
+```python
+from crewai.utilities.i18n import get_i18n
+
+i18n = get_i18n("custom_prompts.json")
+format_slice = i18n.slice("format")
+tool_prompt = i18n.tools("ask_question")
+```
+
#### Opção 3: Desativar Prompts de Sistema para Modelos o1
```python
agent = Agent(
@@ -208,6 +220,8 @@ Uma abordagem direta é criar um arquivo JSON para os prompts que deseja sobresc
O CrewAI então mescla suas customizações com os padrões, assim você não precisa redefinir todos os prompts. Veja como:
+Para código que precisa ler slices de prompt diretamente, use `crewai.utilities.i18n.get_i18n()` com o mesmo arquivo de prompts em vez de ler `agent.i18n`.
+
### Exemplo: Customização Básica de Prompt
Crie um arquivo `custom_prompts.json` com os prompts que deseja modificar. Certifique-se de listar todos os prompts de nível superior que ele deve conter, não apenas suas alterações:
diff --git a/lib/crewai/src/crewai/agents/agent_builder/base_agent.py b/lib/crewai/src/crewai/agents/agent_builder/base_agent.py
index 8b5e36ff4..8792ed753 100644
--- a/lib/crewai/src/crewai/agents/agent_builder/base_agent.py
+++ b/lib/crewai/src/crewai/agents/agent_builder/base_agent.py
@@ -46,6 +46,7 @@ from crewai.state.checkpoint_config import CheckpointConfig, _coerce_checkpoint
from crewai.tools.base_tool import BaseTool, Tool
from crewai.types.callback import SerializableCallable
from crewai.utilities.config import process_config
+from crewai.utilities.i18n import I18N, get_i18n
from crewai.utilities.logger import Logger
from crewai.utilities.rpm_controller import RPMController
from crewai.utilities.string_utils import interpolate_only
@@ -186,6 +187,7 @@ class BaseAgent(BaseModel, ABC, metaclass=AgentMeta):
tools (list[Any] | None): Tools at the agent's disposal.
max_iter (int): Maximum iterations for an agent to execute a task.
agent_executor: An instance of the CrewAgentExecutor class.
+ i18n (I18N): Internationalization settings.
llm (Any): Language model that will run the agent.
crew (Any): Crew to which the agent belongs.
@@ -265,6 +267,14 @@ class BaseAgent(BaseModel, ABC, metaclass=AgentMeta):
_serialize_executor_ref, return_type=dict | None, when_used="json"
),
] = Field(default=None, description="An instance of the CrewAgentExecutor class.")
+ i18n: I18N = Field(
+ default_factory=get_i18n,
+ description="Internationalization settings.",
+ deprecated=(
+ "Agent.i18n is deprecated and will be removed in a future release. "
+ "Use crewai.utilities.i18n.get_i18n() or Crew(prompt_file=...) instead."
+ ),
+ )
llm: Annotated[
str | BaseLLM | None,
diff --git a/lib/crewai/tests/agents/test_agent.py b/lib/crewai/tests/agents/test_agent.py
index 89c1689cf..86e525b63 100644
--- a/lib/crewai/tests/agents/test_agent.py
+++ b/lib/crewai/tests/agents/test_agent.py
@@ -4,6 +4,7 @@ import os
import threading
from unittest import mock
from unittest.mock import MagicMock, patch
+import warnings
from crewai.agents.crew_agent_executor import AgentFinish, CrewAgentExecutor
from crewai.constants import DEFAULT_LLM_MODEL
@@ -77,6 +78,51 @@ def test_agent_creation():
assert agent.backstory == "test backstory"
+def test_agent_exposes_i18n_for_backward_compatibility():
+ from crewai.utilities.i18n import I18N_DEFAULT
+
+ agent = Agent(role="test role", goal="test goal", backstory="test backstory")
+
+ with pytest.warns(DeprecationWarning, match="Agent.i18n is deprecated"):
+ i18n = agent.i18n
+
+ assert i18n is I18N_DEFAULT
+ assert isinstance(i18n.slice("role_playing"), str)
+
+
+def test_agent_accepts_custom_i18n():
+ from crewai.utilities.i18n import I18N
+
+ prompt_file = os.path.join(
+ os.path.dirname(__file__), "..", "utilities", "prompts.json"
+ )
+ i18n = I18N(prompt_file=prompt_file)
+ agent = Agent(
+ role="test role",
+ goal="test goal",
+ backstory="test backstory",
+ i18n=i18n,
+ )
+
+ with pytest.warns(DeprecationWarning, match="Agent.i18n is deprecated"):
+ agent_i18n = agent.i18n
+
+ assert agent_i18n is i18n
+ assert agent_i18n.slice("role_playing") == "Lorem ipsum dolor sit amet"
+
+
+def test_agent_copy_does_not_emit_i18n_deprecation_warning():
+ agent = Agent(role="test role", goal="test goal", backstory="test backstory")
+
+ with warnings.catch_warnings(record=True) as caught_warnings:
+ warnings.simplefilter("always", DeprecationWarning)
+ agent.copy()
+
+ assert not any(
+ "Agent.i18n is deprecated" in str(w.message) for w in caught_warnings
+ )
+
+
def test_agent_with_only_system_template():
"""Test that an agent with only system_template works without errors."""
agent = Agent(