From 8e99d490b00890edf98b9e765e34fc102ddd3c1d Mon Sep 17 00:00:00 2001 From: Greyson LaLonde Date: Wed, 10 Dec 2025 14:17:10 -0500 Subject: [PATCH] chore: add translated docs for async * chore: add translated docs for async * chore: add missing pages --- docs/ko/concepts/crews.mdx | 62 ++- docs/ko/learn/kickoff-async.mdx | 248 ++++++++++-- docs/ko/learn/streaming-crew-execution.mdx | 356 ++++++++++++++++++ docs/pt-BR/concepts/crews.mdx | 63 +++- docs/pt-BR/learn/kickoff-async.mdx | 272 ++++++++++--- docs/pt-BR/learn/streaming-crew-execution.mdx | 356 ++++++++++++++++++ 6 files changed, 1267 insertions(+), 90 deletions(-) create mode 100644 docs/ko/learn/streaming-crew-execution.mdx create mode 100644 docs/pt-BR/learn/streaming-crew-execution.mdx diff --git a/docs/ko/concepts/crews.mdx b/docs/ko/concepts/crews.mdx index c22604017..72e43da50 100644 --- a/docs/ko/concepts/crews.mdx +++ b/docs/ko/concepts/crews.mdx @@ -33,6 +33,7 @@ crewAI에서 crew는 일련의 작업을 달성하기 위해 함께 협력하는 | **Planning** *(선택사항)* | `planning` | Crew에 계획 수립 기능을 추가. 활성화하면 각 Crew 반복 전에 모든 Crew 데이터를 AgentPlanner로 전송하여 작업계획을 세우고, 이 계획이 각 작업 설명에 추가됨. | | **Planning LLM** *(선택사항)* | `planning_llm` | 계획 과정에서 AgentPlanner가 사용하는 언어 모델. | | **Knowledge Sources** _(선택사항)_ | `knowledge_sources` | crew 수준에서 사용 가능한 지식 소스. 모든 agent가 접근 가능. | +| **Stream** _(선택사항)_ | `stream` | 스트리밍 출력을 활성화하여 crew 실행 중 실시간 업데이트를 받을 수 있습니다. 청크를 반복할 수 있는 `CrewStreamingOutput` 객체를 반환합니다. 기본값은 `False`. | **Crew Max RPM**: `max_rpm` 속성은 crew가 분당 처리할 수 있는 최대 요청 수를 설정하며, 개별 agent의 `max_rpm` 설정을 crew 단위로 지정할 경우 오버라이드합니다. @@ -306,12 +307,27 @@ print(result) ### Crew를 시작하는 다양한 방법 -crew가 구성되면, 적절한 시작 방법으로 workflow를 시작하세요. CrewAI는 kickoff 프로세스를 더 잘 제어할 수 있도록 여러 방법을 제공합니다: `kickoff()`, `kickoff_for_each()`, `kickoff_async()`, 그리고 `kickoff_for_each_async()`. +crew가 구성되면, 적절한 시작 방법으로 workflow를 시작하세요. CrewAI는 kickoff 프로세스를 더 잘 제어할 수 있도록 여러 방법을 제공합니다. + +#### 동기 메서드 - `kickoff()`: 정의된 process flow에 따라 실행 프로세스를 시작합니다. - `kickoff_for_each()`: 입력 이벤트나 컬렉션 내 각 항목에 대해 순차적으로 task를 실행합니다. -- `kickoff_async()`: 비동기적으로 workflow를 시작합니다. -- `kickoff_for_each_async()`: 입력 이벤트나 각 항목에 대해 비동기 처리를 활용하여 task를 동시에 실행합니다. + +#### 비동기 메서드 + +CrewAI는 비동기 실행을 위해 두 가지 접근 방식을 제공합니다: + +| 메서드 | 타입 | 설명 | +|--------|------|-------------| +| `akickoff()` | 네이티브 async | 전체 실행 체인에서 진정한 async/await 사용 | +| `akickoff_for_each()` | 네이티브 async | 리스트의 각 입력에 대해 네이티브 async 실행 | +| `kickoff_async()` | 스레드 기반 | 동기 실행을 `asyncio.to_thread`로 래핑 | +| `kickoff_for_each_async()` | 스레드 기반 | 리스트의 각 입력에 대해 스레드 기반 async | + + +고동시성 워크로드의 경우 `akickoff()` 및 `akickoff_for_each()`가 권장됩니다. 이들은 작업 실행, 메모리 작업, 지식 검색에 네이티브 async를 사용합니다. + ```python Code # Start the crew's task execution @@ -324,19 +340,53 @@ results = my_crew.kickoff_for_each(inputs=inputs_array) for result in results: print(result) -# Example of using kickoff_async +# Example of using native async with akickoff +inputs = {'topic': 'AI in healthcare'} +async_result = await my_crew.akickoff(inputs=inputs) +print(async_result) + +# Example of using native async with akickoff_for_each +inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}] +async_results = await my_crew.akickoff_for_each(inputs=inputs_array) +for async_result in async_results: + print(async_result) + +# Example of using thread-based kickoff_async inputs = {'topic': 'AI in healthcare'} async_result = await my_crew.kickoff_async(inputs=inputs) print(async_result) -# Example of using kickoff_for_each_async +# Example of using thread-based kickoff_for_each_async inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}] async_results = await my_crew.kickoff_for_each_async(inputs=inputs_array) for async_result in async_results: print(async_result) ``` -이러한 메서드는 crew 내에서 task를 관리하고 실행하는 데 유연성을 제공하며, 동기 및 비동기 workflow 모두 필요에 맞게 사용할 수 있도록 지원합니다. +이러한 메서드는 crew 내에서 task를 관리하고 실행하는 데 유연성을 제공하며, 동기 및 비동기 workflow 모두 필요에 맞게 사용할 수 있도록 지원합니다. 자세한 비동기 예제는 [Crew 비동기 시작](/ko/learn/kickoff-async) 가이드를 참조하세요. + +### 스트리밍 Crew 실행 + +crew 실행을 실시간으로 확인하려면 스트리밍을 활성화하여 출력이 생성되는 대로 받을 수 있습니다: + +```python Code +# 스트리밍 활성화 +crew = Crew( + agents=[researcher], + tasks=[task], + stream=True +) + +# 스트리밍 출력을 반복 +streaming = crew.kickoff(inputs={"topic": "AI"}) +for chunk in streaming: + print(chunk.content, end="", flush=True) + +# 최종 결과 접근 +result = streaming.result +``` + +스트리밍에 대한 자세한 내용은 [스트리밍 Crew 실행](/ko/learn/streaming-crew-execution) 가이드를 참조하세요. ### 특정 Task에서 다시 실행하기 diff --git a/docs/ko/learn/kickoff-async.mdx b/docs/ko/learn/kickoff-async.mdx index 12f0f4038..46292b36e 100644 --- a/docs/ko/learn/kickoff-async.mdx +++ b/docs/ko/learn/kickoff-async.mdx @@ -7,17 +7,28 @@ mode: "wide" ## 소개 -CrewAI는 crew를 비동기적으로 시작할 수 있는 기능을 제공합니다. 이를 통해 crew 실행을 블로킹(blocking) 없이 시작할 수 있습니다. +CrewAI는 crew를 비동기적으로 시작할 수 있는 기능을 제공합니다. 이를 통해 crew 실행을 블로킹(blocking) 없이 시작할 수 있습니다. 이 기능은 여러 개의 crew를 동시에 실행하거나 crew가 실행되는 동안 다른 작업을 수행해야 할 때 특히 유용합니다. -## 비동기 Crew 실행 +CrewAI는 비동기 실행을 위해 두 가지 접근 방식을 제공합니다: -Crew를 비동기적으로 시작하려면 `kickoff_async()` 메서드를 사용하세요. 이 메서드는 별도의 스레드에서 crew 실행을 시작하여, 메인 스레드가 다른 작업을 계속 실행할 수 있도록 합니다. +| 메서드 | 타입 | 설명 | +|--------|------|-------------| +| `akickoff()` | 네이티브 async | 전체 실행 체인에서 진정한 async/await 사용 | +| `kickoff_async()` | 스레드 기반 | 동기 실행을 `asyncio.to_thread`로 래핑 | + + +고동시성 워크로드의 경우 `akickoff()`가 권장됩니다. 이는 작업 실행, 메모리 작업, 지식 검색에 네이티브 async를 사용합니다. + + +## `akickoff()`를 사용한 네이티브 비동기 실행 + +`akickoff()` 메서드는 작업 실행, 메모리 작업, 지식 쿼리를 포함한 전체 실행 체인에서 async/await를 사용하여 진정한 네이티브 비동기 실행을 제공합니다. ### 메서드 시그니처 ```python Code -def kickoff_async(self, inputs: dict) -> CrewOutput: +async def akickoff(self, inputs: dict) -> CrewOutput: ``` ### 매개변수 @@ -28,23 +39,13 @@ def kickoff_async(self, inputs: dict) -> CrewOutput: - `CrewOutput`: crew 실행 결과를 나타내는 객체입니다. -## 잠재적 사용 사례 - -- **병렬 콘텐츠 생성**: 여러 개의 독립적인 crew를 비동기적으로 시작하여, 각 crew가 다른 주제에 대한 콘텐츠 생성을 담당합니다. 예를 들어, 한 crew는 AI 트렌드에 대한 기사 조사 및 초안을 작성하는 반면, 또 다른 crew는 신제품 출시와 관련된 소셜 미디어 게시물을 생성할 수 있습니다. 각 crew는 독립적으로 운영되므로 콘텐츠 생산을 효율적으로 확장할 수 있습니다. - -- **동시 시장 조사 작업**: 여러 crew를 비동기적으로 시작하여 시장 조사를 병렬로 수행합니다. 한 crew는 업계 동향을 분석하고, 또 다른 crew는 경쟁사 전략을 조사하며, 또 다른 crew는 소비자 감정을 평가할 수 있습니다. 각 crew는 독립적으로 자신의 작업을 완료하므로 더 빠르고 포괄적인 인사이트를 얻을 수 있습니다. - -- **독립적인 여행 계획 모듈**: 각각 독립적으로 여행의 다양한 측면을 계획하도록 crew를 따로 실행합니다. 한 crew는 항공편 옵션을, 다른 crew는 숙박을, 세 번째 crew는 활동 계획을 담당할 수 있습니다. 각 crew는 비동기적으로 작업하므로 여행의 다양한 요소를 동시에 그리고 독립적으로 더 빠르게 계획할 수 있습니다. - -## 예시: 단일 비동기 crew 실행 - -다음은 asyncio를 사용하여 crew를 비동기적으로 시작하고 결과를 await하는 방법의 예시입니다: +### 예시: 네이티브 비동기 Crew 실행 ```python Code import asyncio from crewai import Crew, Agent, Task -# Create an agent with code execution enabled +# 에이전트 생성 coding_agent = Agent( role="Python Data Analyst", goal="Analyze data and provide insights using Python", @@ -52,37 +53,165 @@ coding_agent = Agent( allow_code_execution=True ) -# Create a task that requires code execution +# 작업 생성 data_analysis_task = Task( description="Analyze the given dataset and calculate the average age of participants. Ages: {ages}", agent=coding_agent, expected_output="The average age of the participants." ) -# Create a crew and add the task +# Crew 생성 analysis_crew = Crew( agents=[coding_agent], tasks=[data_analysis_task] ) -# Async function to kickoff the crew asynchronously -async def async_crew_execution(): - result = await analysis_crew.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]}) +# 네이티브 비동기 실행 +async def main(): + result = await analysis_crew.akickoff(inputs={"ages": [25, 30, 35, 40, 45]}) print("Crew Result:", result) -# Run the async function -asyncio.run(async_crew_execution()) +asyncio.run(main()) ``` -## 예제: 다중 비동기 Crew 실행 +### 예시: 여러 네이티브 비동기 Crew -이 예제에서는 여러 Crew를 비동기적으로 시작하고 `asyncio.gather()`를 사용하여 모두 완료될 때까지 기다리는 방법을 보여줍니다: +`asyncio.gather()`를 사용하여 네이티브 async로 여러 crew를 동시에 실행: + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +coding_agent = Agent( + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", + allow_code_execution=True +) + +task_1 = Task( + description="Analyze the first dataset and calculate the average age. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +task_2 = Task( + description="Analyze the second dataset and calculate the average age. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +crew_1 = Crew(agents=[coding_agent], tasks=[task_1]) +crew_2 = Crew(agents=[coding_agent], tasks=[task_2]) + +async def main(): + results = await asyncio.gather( + crew_1.akickoff(inputs={"ages": [25, 30, 35, 40, 45]}), + crew_2.akickoff(inputs={"ages": [20, 22, 24, 28, 30]}) + ) + + for i, result in enumerate(results, 1): + print(f"Crew {i} Result:", result) + +asyncio.run(main()) +``` + +### 예시: 여러 입력에 대한 네이티브 비동기 + +`akickoff_for_each()`를 사용하여 네이티브 async로 여러 입력에 대해 crew를 동시에 실행: + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +coding_agent = Agent( + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", + allow_code_execution=True +) + +data_analysis_task = Task( + description="Analyze the dataset and calculate the average age. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +analysis_crew = Crew( + agents=[coding_agent], + tasks=[data_analysis_task] +) + +async def main(): + datasets = [ + {"ages": [25, 30, 35, 40, 45]}, + {"ages": [20, 22, 24, 28, 30]}, + {"ages": [30, 35, 40, 45, 50]} + ] + + results = await analysis_crew.akickoff_for_each(datasets) + + for i, result in enumerate(results, 1): + print(f"Dataset {i} Result:", result) + +asyncio.run(main()) +``` + +## `kickoff_async()`를 사용한 스레드 기반 비동기 + +`kickoff_async()` 메서드는 동기 `kickoff()`를 스레드로 래핑하여 비동기 실행을 제공합니다. 이는 더 간단한 비동기 통합이나 하위 호환성에 유용합니다. + +### 메서드 시그니처 + +```python Code +async def kickoff_async(self, inputs: dict) -> CrewOutput: +``` + +### 매개변수 + +- `inputs` (dict): 작업에 필요한 입력 데이터를 포함하는 딕셔너리입니다. + +### 반환 + +- `CrewOutput`: crew 실행 결과를 나타내는 객체입니다. + +### 예시: 스레드 기반 비동기 실행 + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +coding_agent = Agent( + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", + allow_code_execution=True +) + +data_analysis_task = Task( + description="Analyze the given dataset and calculate the average age of participants. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +analysis_crew = Crew( + agents=[coding_agent], + tasks=[data_analysis_task] +) + +async def async_crew_execution(): + result = await analysis_crew.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]}) + print("Crew Result:", result) + +asyncio.run(async_crew_execution()) +``` + +### 예시: 여러 스레드 기반 비동기 Crew ```python Code import asyncio from crewai import Crew, Agent, Task -# Create an agent with code execution enabled coding_agent = Agent( role="Python Data Analyst", goal="Analyze data and provide insights using Python", @@ -90,7 +219,6 @@ coding_agent = Agent( allow_code_execution=True ) -# Create tasks that require code execution task_1 = Task( description="Analyze the first dataset and calculate the average age of participants. Ages: {ages}", agent=coding_agent, @@ -103,22 +231,76 @@ task_2 = Task( expected_output="The average age of the participants." ) -# Create two crews and add tasks crew_1 = Crew(agents=[coding_agent], tasks=[task_1]) crew_2 = Crew(agents=[coding_agent], tasks=[task_2]) -# Async function to kickoff multiple crews asynchronously and wait for all to finish async def async_multiple_crews(): - # Create coroutines for concurrent execution result_1 = crew_1.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]}) result_2 = crew_2.kickoff_async(inputs={"ages": [20, 22, 24, 28, 30]}) - # Wait for both crews to finish results = await asyncio.gather(result_1, result_2) for i, result in enumerate(results, 1): print(f"Crew {i} Result:", result) -# Run the async function asyncio.run(async_multiple_crews()) -``` \ No newline at end of file +``` + +## 비동기 스트리밍 + +두 비동기 메서드 모두 crew에 `stream=True`가 설정된 경우 스트리밍을 지원합니다: + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +agent = Agent( + role="Researcher", + goal="Research and summarize topics", + backstory="You are an expert researcher." +) + +task = Task( + description="Research the topic: {topic}", + agent=agent, + expected_output="A comprehensive summary of the topic." +) + +crew = Crew( + agents=[agent], + tasks=[task], + stream=True # 스트리밍 활성화 +) + +async def main(): + streaming_output = await crew.akickoff(inputs={"topic": "AI trends in 2024"}) + + # 스트리밍 청크에 대한 비동기 반복 + async for chunk in streaming_output: + print(f"Chunk: {chunk.content}") + + # 스트리밍 완료 후 최종 결과 접근 + result = streaming_output.result + print(f"Final result: {result.raw}") + +asyncio.run(main()) +``` + +## 잠재적 사용 사례 + +- **병렬 콘텐츠 생성**: 여러 개의 독립적인 crew를 비동기적으로 시작하여, 각 crew가 다른 주제에 대한 콘텐츠 생성을 담당합니다. 예를 들어, 한 crew는 AI 트렌드에 대한 기사 조사 및 초안을 작성하는 반면, 또 다른 crew는 신제품 출시와 관련된 소셜 미디어 게시물을 생성할 수 있습니다. + +- **동시 시장 조사 작업**: 여러 crew를 비동기적으로 시작하여 시장 조사를 병렬로 수행합니다. 한 crew는 업계 동향을 분석하고, 또 다른 crew는 경쟁사 전략을 조사하며, 또 다른 crew는 소비자 감정을 평가할 수 있습니다. + +- **독립적인 여행 계획 모듈**: 각각 독립적으로 여행의 다양한 측면을 계획하도록 crew를 따로 실행합니다. 한 crew는 항공편 옵션을, 다른 crew는 숙박을, 세 번째 crew는 활동 계획을 담당할 수 있습니다. + +## `akickoff()`와 `kickoff_async()` 선택하기 + +| 기능 | `akickoff()` | `kickoff_async()` | +|---------|--------------|-------------------| +| 실행 모델 | 네이티브 async/await | 스레드 기반 래퍼 | +| 작업 실행 | `aexecute_sync()`로 비동기 | 스레드 풀에서 동기 | +| 메모리 작업 | 비동기 | 스레드 풀에서 동기 | +| 지식 검색 | 비동기 | 스레드 풀에서 동기 | +| 적합한 용도 | 고동시성, I/O 바운드 워크로드 | 간단한 비동기 통합 | +| 스트리밍 지원 | 예 | 예 | diff --git a/docs/ko/learn/streaming-crew-execution.mdx b/docs/ko/learn/streaming-crew-execution.mdx new file mode 100644 index 000000000..aec56caed --- /dev/null +++ b/docs/ko/learn/streaming-crew-execution.mdx @@ -0,0 +1,356 @@ +--- +title: 스트리밍 Crew 실행 +description: CrewAI crew 실행에서 실시간 출력을 스트리밍하기 +icon: wave-pulse +mode: "wide" +--- + +## 소개 + +CrewAI는 crew 실행 중 실시간 출력을 스트리밍하는 기능을 제공하여, 전체 프로세스가 완료될 때까지 기다리지 않고 결과가 생성되는 대로 표시할 수 있습니다. 이 기능은 대화형 애플리케이션을 구축하거나, 사용자 피드백을 제공하거나, 장시간 실행되는 프로세스를 모니터링할 때 특히 유용합니다. + +## 스트리밍 작동 방식 + +스트리밍이 활성화되면 CrewAI는 LLM 응답과 도구 호출을 실시간으로 캡처하여, 어떤 task와 agent가 실행 중인지에 대한 컨텍스트를 포함한 구조화된 청크로 패키징합니다. 이러한 청크를 실시간으로 반복 처리하고 실행이 완료되면 최종 결과에 접근할 수 있습니다. + +## 스트리밍 활성화 + +스트리밍을 활성화하려면 crew를 생성할 때 `stream` 파라미터를 `True`로 설정하세요: + +```python Code +from crewai import Agent, Crew, Task + +# 에이전트와 태스크 생성 +researcher = Agent( + role="Research Analyst", + goal="Gather comprehensive information on topics", + backstory="You are an experienced researcher with excellent analytical skills.", +) + +task = Task( + description="Research the latest developments in AI", + expected_output="A detailed report on recent AI advancements", + agent=researcher, +) + +# 스트리밍 활성화 +crew = Crew( + agents=[researcher], + tasks=[task], + stream=True # 스트리밍 출력 활성화 +) +``` + +## 동기 스트리밍 + +스트리밍이 활성화된 crew에서 `kickoff()`를 호출하면, 청크가 도착할 때마다 반복 처리할 수 있는 `CrewStreamingOutput` 객체가 반환됩니다: + +```python Code +# 스트리밍 실행 시작 +streaming = crew.kickoff(inputs={"topic": "artificial intelligence"}) + +# 청크가 도착할 때마다 반복 +for chunk in streaming: + print(chunk.content, end="", flush=True) + +# 스트리밍 완료 후 최종 결과 접근 +result = streaming.result +print(f"\n\n최종 출력: {result.raw}") +``` + +### 스트림 청크 정보 + +각 청크는 실행에 대한 풍부한 컨텍스트를 제공합니다: + +```python Code +streaming = crew.kickoff(inputs={"topic": "AI"}) + +for chunk in streaming: + print(f"Task: {chunk.task_name} (인덱스 {chunk.task_index})") + print(f"Agent: {chunk.agent_role}") + print(f"Content: {chunk.content}") + print(f"Type: {chunk.chunk_type}") # TEXT 또는 TOOL_CALL + if chunk.tool_call: + print(f"Tool: {chunk.tool_call.tool_name}") + print(f"Arguments: {chunk.tool_call.arguments}") +``` + +### 스트리밍 결과 접근 + +`CrewStreamingOutput` 객체는 여러 유용한 속성을 제공합니다: + +```python Code +streaming = crew.kickoff(inputs={"topic": "AI"}) + +# 청크 반복 및 수집 +for chunk in streaming: + print(chunk.content, end="", flush=True) + +# 반복 완료 후 +print(f"\n완료됨: {streaming.is_completed}") +print(f"전체 텍스트: {streaming.get_full_text()}") +print(f"전체 청크 수: {len(streaming.chunks)}") +print(f"최종 결과: {streaming.result.raw}") +``` + +## 비동기 스트리밍 + +비동기 애플리케이션의 경우, 비동기 반복과 함께 `akickoff()`(네이티브 async) 또는 `kickoff_async()`(스레드 기반)를 사용할 수 있습니다: + +### `akickoff()`를 사용한 네이티브 Async + +`akickoff()` 메서드는 전체 체인에서 진정한 네이티브 async 실행을 제공합니다: + +```python Code +import asyncio + +async def stream_crew(): + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True + ) + + # 네이티브 async 스트리밍 시작 + streaming = await crew.akickoff(inputs={"topic": "AI"}) + + # 청크에 대한 비동기 반복 + async for chunk in streaming: + print(chunk.content, end="", flush=True) + + # 최종 결과 접근 + result = streaming.result + print(f"\n\n최종 출력: {result.raw}") + +asyncio.run(stream_crew()) +``` + +### `kickoff_async()`를 사용한 스레드 기반 Async + +더 간단한 async 통합이나 하위 호환성을 위해: + +```python Code +import asyncio + +async def stream_crew(): + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True + ) + + # 스레드 기반 async 스트리밍 시작 + streaming = await crew.kickoff_async(inputs={"topic": "AI"}) + + # 청크에 대한 비동기 반복 + async for chunk in streaming: + print(chunk.content, end="", flush=True) + + # 최종 결과 접근 + result = streaming.result + print(f"\n\n최종 출력: {result.raw}") + +asyncio.run(stream_crew()) +``` + + +고동시성 워크로드의 경우, 태스크 실행, 메모리 작업, 지식 검색에 네이티브 async를 사용하는 `akickoff()`가 권장됩니다. 자세한 내용은 [Crew 비동기 시작](/ko/learn/kickoff-async) 가이드를 참조하세요. + + +## kickoff_for_each를 사용한 스트리밍 + +`kickoff_for_each()`로 여러 입력에 대해 crew를 실행할 때, 동기 또는 비동기 여부에 따라 스트리밍이 다르게 작동합니다: + +### 동기 kickoff_for_each + +동기 `kickoff_for_each()`를 사용하면, 각 입력에 대해 하나씩 `CrewStreamingOutput` 객체의 리스트가 반환됩니다: + +```python Code +crew = Crew( + agents=[researcher], + tasks=[task], + stream=True +) + +inputs_list = [ + {"topic": "AI in healthcare"}, + {"topic": "AI in finance"} +] + +# 스트리밍 출력 리스트 반환 +streaming_outputs = crew.kickoff_for_each(inputs=inputs_list) + +# 각 스트리밍 출력에 대해 반복 +for i, streaming in enumerate(streaming_outputs): + print(f"\n=== 입력 {i + 1} ===") + for chunk in streaming: + print(chunk.content, end="", flush=True) + + result = streaming.result + print(f"\n\n결과 {i + 1}: {result.raw}") +``` + +### 비동기 kickoff_for_each_async + +비동기 `kickoff_for_each_async()`를 사용하면, 모든 crew의 청크가 동시에 도착하는 대로 반환하는 단일 `CrewStreamingOutput`이 반환됩니다: + +```python Code +import asyncio + +async def stream_multiple_crews(): + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True + ) + + inputs_list = [ + {"topic": "AI in healthcare"}, + {"topic": "AI in finance"} + ] + + # 모든 crew에 대한 단일 스트리밍 출력 반환 + streaming = await crew.kickoff_for_each_async(inputs=inputs_list) + + # 모든 crew의 청크가 생성되는 대로 도착 + async for chunk in streaming: + print(f"[{chunk.task_name}] {chunk.content}", end="", flush=True) + + # 모든 결과 접근 + results = streaming.results # CrewOutput 객체 리스트 + for i, result in enumerate(results): + print(f"\n\n결과 {i + 1}: {result.raw}") + +asyncio.run(stream_multiple_crews()) +``` + +## 스트림 청크 타입 + +청크는 `chunk_type` 필드로 표시되는 다양한 타입을 가질 수 있습니다: + +### TEXT 청크 + +LLM 응답의 표준 텍스트 콘텐츠: + +```python Code +for chunk in streaming: + if chunk.chunk_type == StreamChunkType.TEXT: + print(chunk.content, end="", flush=True) +``` + +### TOOL_CALL 청크 + +수행 중인 도구 호출에 대한 정보: + +```python Code +for chunk in streaming: + if chunk.chunk_type == StreamChunkType.TOOL_CALL: + print(f"\n도구 호출: {chunk.tool_call.tool_name}") + print(f"인자: {chunk.tool_call.arguments}") +``` + +## 실용적인 예시: 스트리밍을 사용한 UI 구축 + +다음은 스트리밍을 사용한 대화형 애플리케이션을 구축하는 방법을 보여주는 완전한 예시입니다: + +```python Code +import asyncio +from crewai import Agent, Crew, Task +from crewai.types.streaming import StreamChunkType + +async def interactive_research(): + # 스트리밍이 활성화된 crew 생성 + researcher = Agent( + role="Research Analyst", + goal="Provide detailed analysis on any topic", + backstory="You are an expert researcher with broad knowledge.", + ) + + task = Task( + description="Research and analyze: {topic}", + expected_output="A comprehensive analysis with key insights", + agent=researcher, + ) + + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True, + verbose=False + ) + + # 사용자 입력 받기 + topic = input("연구할 주제를 입력하세요: ") + + print(f"\n{'='*60}") + print(f"연구 중: {topic}") + print(f"{'='*60}\n") + + # 스트리밍 실행 시작 + streaming = await crew.kickoff_async(inputs={"topic": topic}) + + current_task = "" + async for chunk in streaming: + # 태스크 전환 표시 + if chunk.task_name != current_task: + current_task = chunk.task_name + print(f"\n[{chunk.agent_role}] 작업 중: {chunk.task_name}") + print("-" * 60) + + # 텍스트 청크 표시 + if chunk.chunk_type == StreamChunkType.TEXT: + print(chunk.content, end="", flush=True) + + # 도구 호출 표시 + elif chunk.chunk_type == StreamChunkType.TOOL_CALL and chunk.tool_call: + print(f"\n🔧 도구 사용: {chunk.tool_call.tool_name}") + + # 최종 결과 표시 + result = streaming.result + print(f"\n\n{'='*60}") + print("분석 완료!") + print(f"{'='*60}") + print(f"\n토큰 사용량: {result.token_usage}") + +asyncio.run(interactive_research()) +``` + +## 사용 사례 + +스트리밍은 다음과 같은 경우에 특히 유용합니다: + +- **대화형 애플리케이션**: 에이전트가 작업하는 동안 사용자에게 실시간 피드백 제공 +- **장시간 실행 태스크**: 연구, 분석 또는 콘텐츠 생성의 진행 상황 표시 +- **디버깅 및 모니터링**: 에이전트 동작과 의사 결정을 실시간으로 관찰 +- **사용자 경험**: 점진적인 결과를 표시하여 체감 지연 시간 감소 +- **라이브 대시보드**: crew 실행 상태를 표시하는 모니터링 인터페이스 구축 + +## 중요 사항 + +- 스트리밍은 crew의 모든 에이전트에 대해 자동으로 LLM 스트리밍을 활성화합니다 +- `.result` 속성에 접근하기 전에 모든 청크를 반복해야 합니다 +- 스트리밍을 사용하는 `kickoff_for_each_async()`의 경우, 모든 출력을 가져오려면 `.results`(복수형)를 사용하세요 +- 스트리밍은 최소한의 오버헤드를 추가하며 실제로 체감 성능을 향상시킬 수 있습니다 +- 각 청크는 풍부한 UI를 위한 전체 컨텍스트(태스크, 에이전트, 청크 타입)를 포함합니다 + +## 오류 처리 + +스트리밍 실행 중 오류 처리: + +```python Code +streaming = crew.kickoff(inputs={"topic": "AI"}) + +try: + for chunk in streaming: + print(chunk.content, end="", flush=True) + + result = streaming.result + print(f"\n성공: {result.raw}") + +except Exception as e: + print(f"\n스트리밍 중 오류 발생: {e}") + if streaming.is_completed: + print("스트리밍은 완료되었지만 오류가 발생했습니다") +``` + +스트리밍을 활용하면 CrewAI로 더 반응성이 좋고 대화형인 애플리케이션을 구축하여 사용자에게 에이전트 실행과 결과에 대한 실시간 가시성을 제공할 수 있습니다. \ No newline at end of file diff --git a/docs/pt-BR/concepts/crews.mdx b/docs/pt-BR/concepts/crews.mdx index 50bb47b84..b144ad8f9 100644 --- a/docs/pt-BR/concepts/crews.mdx +++ b/docs/pt-BR/concepts/crews.mdx @@ -32,6 +32,8 @@ Uma crew no crewAI representa um grupo colaborativo de agentes trabalhando em co | **Prompt File** _(opcional)_ | `prompt_file` | Caminho para o arquivo JSON de prompt a ser utilizado pela crew. | | **Planning** *(opcional)* | `planning` | Adiciona habilidade de planejamento à Crew. Quando ativado, antes de cada iteração, todos os dados da Crew são enviados a um AgentPlanner que planejará as tasks e este plano será adicionado à descrição de cada task. | | **Planning LLM** *(opcional)* | `planning_llm` | O modelo de linguagem usado pelo AgentPlanner em um processo de planejamento. | +| **Knowledge Sources** _(opcional)_ | `knowledge_sources` | Fontes de conhecimento disponíveis no nível da crew, acessíveis a todos os agentes. | +| **Stream** _(opcional)_ | `stream` | Habilita saída em streaming para receber atualizações em tempo real durante a execução da crew. Retorna um objeto `CrewStreamingOutput` que pode ser iterado para chunks. O padrão é `False`. | **Crew Max RPM**: O atributo `max_rpm` define o número máximo de requisições por minuto que a crew pode executar para evitar limites de taxa e irá sobrescrever as configurações de `max_rpm` dos agentes individuais se você o definir. @@ -303,12 +305,27 @@ print(result) ### Diferentes Formas de Iniciar uma Crew -Assim que sua crew estiver definida, inicie o fluxo de trabalho com o método kickoff apropriado. O CrewAI oferece vários métodos para melhor controle do processo: `kickoff()`, `kickoff_for_each()`, `kickoff_async()` e `kickoff_for_each_async()`. +Assim que sua crew estiver definida, inicie o fluxo de trabalho com o método kickoff apropriado. O CrewAI oferece vários métodos para melhor controle do processo. + +#### Métodos Síncronos - `kickoff()`: Inicia o processo de execução seguindo o fluxo definido. - `kickoff_for_each()`: Executa tasks sequencialmente para cada evento de entrada ou item da coleção fornecida. -- `kickoff_async()`: Inicia o workflow de forma assíncrona. -- `kickoff_for_each_async()`: Executa as tasks concorrentemente para cada entrada, aproveitando o processamento assíncrono. + +#### Métodos Assíncronos + +O CrewAI oferece duas abordagens para execução assíncrona: + +| Método | Tipo | Descrição | +|--------|------|-------------| +| `akickoff()` | Async nativo | Async/await verdadeiro em toda a cadeia de execução | +| `akickoff_for_each()` | Async nativo | Execução async nativa para cada entrada em uma lista | +| `kickoff_async()` | Baseado em thread | Envolve execução síncrona em `asyncio.to_thread` | +| `kickoff_for_each_async()` | Baseado em thread | Async baseado em thread para cada entrada em uma lista | + + +Para cargas de trabalho de alta concorrência, `akickoff()` e `akickoff_for_each()` são recomendados pois usam async nativo para execução de tasks, operações de memória e recuperação de conhecimento. + ```python Code # Iniciar execução das tasks da crew @@ -321,19 +338,53 @@ results = my_crew.kickoff_for_each(inputs=inputs_array) for result in results: print(result) -# Exemplo com kickoff_async +# Exemplo usando async nativo com akickoff +inputs = {'topic': 'AI in healthcare'} +async_result = await my_crew.akickoff(inputs=inputs) +print(async_result) + +# Exemplo usando async nativo com akickoff_for_each +inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}] +async_results = await my_crew.akickoff_for_each(inputs=inputs_array) +for async_result in async_results: + print(async_result) + +# Exemplo usando kickoff_async baseado em thread inputs = {'topic': 'AI in healthcare'} async_result = await my_crew.kickoff_async(inputs=inputs) print(async_result) -# Exemplo com kickoff_for_each_async +# Exemplo usando kickoff_for_each_async baseado em thread inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}] async_results = await my_crew.kickoff_for_each_async(inputs=inputs_array) for async_result in async_results: print(async_result) ``` -Esses métodos fornecem flexibilidade para gerenciar e executar tasks dentro de sua crew, permitindo fluxos de trabalho síncronos e assíncronos de acordo com sua necessidade. +Esses métodos fornecem flexibilidade para gerenciar e executar tasks dentro de sua crew, permitindo fluxos de trabalho síncronos e assíncronos de acordo com sua necessidade. Para exemplos detalhados de async, consulte o guia [Inicie uma Crew de Forma Assíncrona](/pt-BR/learn/kickoff-async). + +### Streaming na Execução da Crew + +Para visibilidade em tempo real da execução da crew, você pode habilitar streaming para receber saída conforme é gerada: + +```python Code +# Habilitar streaming +crew = Crew( + agents=[researcher], + tasks=[task], + stream=True +) + +# Iterar sobre saída em streaming +streaming = crew.kickoff(inputs={"topic": "AI"}) +for chunk in streaming: + print(chunk.content, end="", flush=True) + +# Acessar resultado final +result = streaming.result +``` + +Saiba mais sobre streaming no guia [Streaming na Execução da Crew](/pt-BR/learn/streaming-crew-execution). ### Repetindo Execução a partir de uma Task Específica diff --git a/docs/pt-BR/learn/kickoff-async.mdx b/docs/pt-BR/learn/kickoff-async.mdx index afdacf2e2..c1bf0e93c 100644 --- a/docs/pt-BR/learn/kickoff-async.mdx +++ b/docs/pt-BR/learn/kickoff-async.mdx @@ -7,17 +7,28 @@ mode: "wide" ## Introdução -A CrewAI oferece a capacidade de iniciar uma crew de forma assíncrona, permitindo que você comece a execução da crew de maneira não bloqueante. +A CrewAI oferece a capacidade de iniciar uma crew de forma assíncrona, permitindo que você comece a execução da crew de maneira não bloqueante. Esse recurso é especialmente útil quando você deseja executar múltiplas crews simultaneamente ou quando precisa realizar outras tarefas enquanto a crew está em execução. -## Execução Assíncrona de Crew +O CrewAI oferece duas abordagens para execução assíncrona: -Para iniciar uma crew de forma assíncrona, utilize o método `kickoff_async()`. Este método inicia a execução da crew em uma thread separada, permitindo que a thread principal continue executando outras tarefas. +| Método | Tipo | Descrição | +|--------|------|-------------| +| `akickoff()` | Async nativo | Async/await verdadeiro em toda a cadeia de execução | +| `kickoff_async()` | Baseado em thread | Envolve execução síncrona em `asyncio.to_thread` | + + +Para cargas de trabalho de alta concorrência, `akickoff()` é recomendado pois usa async nativo para execução de tasks, operações de memória e recuperação de conhecimento. + + +## Execução Async Nativa com `akickoff()` + +O método `akickoff()` fornece execução async nativa verdadeira, usando async/await em toda a cadeia de execução, incluindo execução de tasks, operações de memória e consultas de conhecimento. ### Assinatura do Método ```python Code -def kickoff_async(self, inputs: dict) -> CrewOutput: +async def akickoff(self, inputs: dict) -> CrewOutput: ``` ### Parâmetros @@ -28,97 +39,268 @@ def kickoff_async(self, inputs: dict) -> CrewOutput: - `CrewOutput`: Um objeto que representa o resultado da execução da crew. -## Possíveis Casos de Uso - -- **Geração Paralela de Conteúdo**: Inicie múltiplas crews independentes de forma assíncrona, cada uma responsável por gerar conteúdo sobre temas diferentes. Por exemplo, uma crew pode pesquisar e redigir um artigo sobre tendências em IA, enquanto outra gera posts para redes sociais sobre o lançamento de um novo produto. Cada crew atua de forma independente, permitindo a escala eficiente da produção de conteúdo. - -- **Tarefas Conjuntas de Pesquisa de Mercado**: Lance múltiplas crews de forma assíncrona para realizar pesquisas de mercado em paralelo. Uma crew pode analisar tendências do setor, outra examinar estratégias de concorrentes e ainda outra avaliar o sentimento do consumidor. Cada crew conclui sua tarefa de forma independente, proporcionando insights mais rápidos e abrangentes. - -- **Módulos Independentes de Planejamento de Viagem**: Execute crews separadas para planejar diferentes aspectos de uma viagem de forma independente. Uma crew pode cuidar das opções de voo, outra das acomodações e uma terceira do planejamento das atividades. Cada crew trabalha de maneira assíncrona, permitindo que os vários componentes da viagem sejam planejados ao mesmo tempo e de maneira independente, para resultados mais rápidos. - -## Exemplo: Execução Assíncrona de uma Única Crew - -Veja um exemplo de como iniciar uma crew de forma assíncrona utilizando asyncio e aguardando o resultado: +### Exemplo: Execução Async Nativa de Crew ```python Code import asyncio from crewai import Crew, Agent, Task -# Create an agent with code execution enabled +# Criar um agente coding_agent = Agent( - role="Analista de Dados Python", - goal="Analisar dados e fornecer insights usando Python", - backstory="Você é um analista de dados experiente com fortes habilidades em Python.", + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", allow_code_execution=True ) -# Create a task that requires code execution +# Criar uma tarefa data_analysis_task = Task( - description="Analise o conjunto de dados fornecido e calcule a idade média dos participantes. Idades: {ages}", + description="Analyze the given dataset and calculate the average age of participants. Ages: {ages}", agent=coding_agent, - expected_output="A idade média dos participantes." + expected_output="The average age of the participants." ) -# Create a crew and add the task +# Criar uma crew analysis_crew = Crew( agents=[coding_agent], tasks=[data_analysis_task] ) -# Async function to kickoff the crew asynchronously -async def async_crew_execution(): - result = await analysis_crew.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]}) +# Execução async nativa +async def main(): + result = await analysis_crew.akickoff(inputs={"ages": [25, 30, 35, 40, 45]}) print("Crew Result:", result) -# Run the async function -asyncio.run(async_crew_execution()) +asyncio.run(main()) ``` -## Exemplo: Execução Assíncrona de Múltiplas Crews +### Exemplo: Múltiplas Crews Async Nativas -Neste exemplo, mostraremos como iniciar múltiplas crews de forma assíncrona e aguardar todas serem concluídas usando `asyncio.gather()`: +Execute múltiplas crews concorrentemente usando `asyncio.gather()` com async nativo: ```python Code import asyncio from crewai import Crew, Agent, Task -# Create an agent with code execution enabled coding_agent = Agent( - role="Analista de Dados Python", - goal="Analisar dados e fornecer insights usando Python", - backstory="Você é um analista de dados experiente com fortes habilidades em Python.", + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", allow_code_execution=True ) -# Create tasks that require code execution task_1 = Task( - description="Analise o primeiro conjunto de dados e calcule a idade média dos participantes. Idades: {ages}", + description="Analyze the first dataset and calculate the average age. Ages: {ages}", agent=coding_agent, - expected_output="A idade média dos participantes." + expected_output="The average age of the participants." ) task_2 = Task( - description="Analise o segundo conjunto de dados e calcule a idade média dos participantes. Idades: {ages}", + description="Analyze the second dataset and calculate the average age. Ages: {ages}", agent=coding_agent, - expected_output="A idade média dos participantes." + expected_output="The average age of the participants." +) + +crew_1 = Crew(agents=[coding_agent], tasks=[task_1]) +crew_2 = Crew(agents=[coding_agent], tasks=[task_2]) + +async def main(): + results = await asyncio.gather( + crew_1.akickoff(inputs={"ages": [25, 30, 35, 40, 45]}), + crew_2.akickoff(inputs={"ages": [20, 22, 24, 28, 30]}) + ) + + for i, result in enumerate(results, 1): + print(f"Crew {i} Result:", result) + +asyncio.run(main()) +``` + +### Exemplo: Async Nativo para Múltiplas Entradas + +Use `akickoff_for_each()` para executar sua crew contra múltiplas entradas concorrentemente com async nativo: + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +coding_agent = Agent( + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", + allow_code_execution=True +) + +data_analysis_task = Task( + description="Analyze the dataset and calculate the average age. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +analysis_crew = Crew( + agents=[coding_agent], + tasks=[data_analysis_task] +) + +async def main(): + datasets = [ + {"ages": [25, 30, 35, 40, 45]}, + {"ages": [20, 22, 24, 28, 30]}, + {"ages": [30, 35, 40, 45, 50]} + ] + + results = await analysis_crew.akickoff_for_each(datasets) + + for i, result in enumerate(results, 1): + print(f"Dataset {i} Result:", result) + +asyncio.run(main()) +``` + +## Async Baseado em Thread com `kickoff_async()` + +O método `kickoff_async()` fornece execução async envolvendo o `kickoff()` síncrono em uma thread. Isso é útil para integração async mais simples ou compatibilidade retroativa. + +### Assinatura do Método + +```python Code +async def kickoff_async(self, inputs: dict) -> CrewOutput: +``` + +### Parâmetros + +- `inputs` (dict): Um dicionário contendo os dados de entrada necessários para as tarefas. + +### Retorno + +- `CrewOutput`: Um objeto que representa o resultado da execução da crew. + +### Exemplo: Execução Async Baseada em Thread + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +coding_agent = Agent( + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", + allow_code_execution=True +) + +data_analysis_task = Task( + description="Analyze the given dataset and calculate the average age of participants. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +analysis_crew = Crew( + agents=[coding_agent], + tasks=[data_analysis_task] +) + +async def async_crew_execution(): + result = await analysis_crew.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]}) + print("Crew Result:", result) + +asyncio.run(async_crew_execution()) +``` + +### Exemplo: Múltiplas Crews Async Baseadas em Thread + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +coding_agent = Agent( + role="Python Data Analyst", + goal="Analyze data and provide insights using Python", + backstory="You are an experienced data analyst with strong Python skills.", + allow_code_execution=True +) + +task_1 = Task( + description="Analyze the first dataset and calculate the average age of participants. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." +) + +task_2 = Task( + description="Analyze the second dataset and calculate the average age of participants. Ages: {ages}", + agent=coding_agent, + expected_output="The average age of the participants." ) -# Create two crews and add tasks crew_1 = Crew(agents=[coding_agent], tasks=[task_1]) crew_2 = Crew(agents=[coding_agent], tasks=[task_2]) -# Async function to kickoff multiple crews asynchronously and wait for all to finish async def async_multiple_crews(): - # Create coroutines for concurrent execution result_1 = crew_1.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]}) result_2 = crew_2.kickoff_async(inputs={"ages": [20, 22, 24, 28, 30]}) - # Wait for both crews to finish results = await asyncio.gather(result_1, result_2) for i, result in enumerate(results, 1): print(f"Crew {i} Result:", result) -# Run the async function asyncio.run(async_multiple_crews()) -``` \ No newline at end of file +``` + +## Streaming Assíncrono + +Ambos os métodos async suportam streaming quando `stream=True` está definido na crew: + +```python Code +import asyncio +from crewai import Crew, Agent, Task + +agent = Agent( + role="Researcher", + goal="Research and summarize topics", + backstory="You are an expert researcher." +) + +task = Task( + description="Research the topic: {topic}", + agent=agent, + expected_output="A comprehensive summary of the topic." +) + +crew = Crew( + agents=[agent], + tasks=[task], + stream=True # Habilitar streaming +) + +async def main(): + streaming_output = await crew.akickoff(inputs={"topic": "AI trends in 2024"}) + + # Iteração async sobre chunks de streaming + async for chunk in streaming_output: + print(f"Chunk: {chunk.content}") + + # Acessar resultado final após streaming completar + result = streaming_output.result + print(f"Final result: {result.raw}") + +asyncio.run(main()) +``` + +## Possíveis Casos de Uso + +- **Geração Paralela de Conteúdo**: Inicie múltiplas crews independentes de forma assíncrona, cada uma responsável por gerar conteúdo sobre temas diferentes. Por exemplo, uma crew pode pesquisar e redigir um artigo sobre tendências em IA, enquanto outra gera posts para redes sociais sobre o lançamento de um novo produto. + +- **Tarefas Conjuntas de Pesquisa de Mercado**: Lance múltiplas crews de forma assíncrona para realizar pesquisas de mercado em paralelo. Uma crew pode analisar tendências do setor, outra examinar estratégias de concorrentes e ainda outra avaliar o sentimento do consumidor. + +- **Módulos Independentes de Planejamento de Viagem**: Execute crews separadas para planejar diferentes aspectos de uma viagem de forma independente. Uma crew pode cuidar das opções de voo, outra das acomodações e uma terceira do planejamento das atividades. + +## Escolhendo entre `akickoff()` e `kickoff_async()` + +| Recurso | `akickoff()` | `kickoff_async()` | +|---------|--------------|-------------------| +| Modelo de execução | Async/await nativo | Wrapper baseado em thread | +| Execução de tasks | Async com `aexecute_sync()` | Síncrono em thread pool | +| Operações de memória | Async | Síncrono em thread pool | +| Recuperação de conhecimento | Async | Síncrono em thread pool | +| Melhor para | Alta concorrência, cargas I/O-bound | Integração async simples | +| Suporte a streaming | Sim | Sim | diff --git a/docs/pt-BR/learn/streaming-crew-execution.mdx b/docs/pt-BR/learn/streaming-crew-execution.mdx new file mode 100644 index 000000000..85a26e370 --- /dev/null +++ b/docs/pt-BR/learn/streaming-crew-execution.mdx @@ -0,0 +1,356 @@ +--- +title: Streaming na Execução da Crew +description: Transmita saída em tempo real da execução da sua crew no CrewAI +icon: wave-pulse +mode: "wide" +--- + +## Introdução + +O CrewAI fornece a capacidade de transmitir saída em tempo real durante a execução da crew, permitindo que você exiba resultados conforme são gerados, em vez de esperar que todo o processo seja concluído. Este recurso é particularmente útil para construir aplicações interativas, fornecer feedback ao usuário e monitorar processos de longa duração. + +## Como o Streaming Funciona + +Quando o streaming está ativado, o CrewAI captura respostas do LLM e chamadas de ferramentas conforme acontecem, empacotando-as em chunks estruturados que incluem contexto sobre qual task e agent está executando. Você pode iterar sobre esses chunks em tempo real e acessar o resultado final quando a execução for concluída. + +## Ativando o Streaming + +Para ativar o streaming, defina o parâmetro `stream` como `True` ao criar sua crew: + +```python Code +from crewai import Agent, Crew, Task + +# Crie seus agentes e tasks +researcher = Agent( + role="Research Analyst", + goal="Gather comprehensive information on topics", + backstory="You are an experienced researcher with excellent analytical skills.", +) + +task = Task( + description="Research the latest developments in AI", + expected_output="A detailed report on recent AI advancements", + agent=researcher, +) + +# Ativar streaming +crew = Crew( + agents=[researcher], + tasks=[task], + stream=True # Ativar saída em streaming +) +``` + +## Streaming Síncrono + +Quando você chama `kickoff()` em uma crew com streaming ativado, ele retorna um objeto `CrewStreamingOutput` que você pode iterar para receber chunks conforme chegam: + +```python Code +# Iniciar execução com streaming +streaming = crew.kickoff(inputs={"topic": "artificial intelligence"}) + +# Iterar sobre chunks conforme chegam +for chunk in streaming: + print(chunk.content, end="", flush=True) + +# Acessar o resultado final após o streaming completar +result = streaming.result +print(f"\n\nSaída final: {result.raw}") +``` + +### Informações do Chunk de Stream + +Cada chunk fornece contexto rico sobre a execução: + +```python Code +streaming = crew.kickoff(inputs={"topic": "AI"}) + +for chunk in streaming: + print(f"Task: {chunk.task_name} (índice {chunk.task_index})") + print(f"Agent: {chunk.agent_role}") + print(f"Content: {chunk.content}") + print(f"Type: {chunk.chunk_type}") # TEXT ou TOOL_CALL + if chunk.tool_call: + print(f"Tool: {chunk.tool_call.tool_name}") + print(f"Arguments: {chunk.tool_call.arguments}") +``` + +### Acessando Resultados do Streaming + +O objeto `CrewStreamingOutput` fornece várias propriedades úteis: + +```python Code +streaming = crew.kickoff(inputs={"topic": "AI"}) + +# Iterar e coletar chunks +for chunk in streaming: + print(chunk.content, end="", flush=True) + +# Após a iteração completar +print(f"\nCompletado: {streaming.is_completed}") +print(f"Texto completo: {streaming.get_full_text()}") +print(f"Todos os chunks: {len(streaming.chunks)}") +print(f"Resultado final: {streaming.result.raw}") +``` + +## Streaming Assíncrono + +Para aplicações assíncronas, você pode usar `akickoff()` (async nativo) ou `kickoff_async()` (baseado em threads) com iteração assíncrona: + +### Async Nativo com `akickoff()` + +O método `akickoff()` fornece execução async nativa verdadeira em toda a cadeia: + +```python Code +import asyncio + +async def stream_crew(): + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True + ) + + # Iniciar streaming async nativo + streaming = await crew.akickoff(inputs={"topic": "AI"}) + + # Iteração assíncrona sobre chunks + async for chunk in streaming: + print(chunk.content, end="", flush=True) + + # Acessar resultado final + result = streaming.result + print(f"\n\nSaída final: {result.raw}") + +asyncio.run(stream_crew()) +``` + +### Async Baseado em Threads com `kickoff_async()` + +Para integração async mais simples ou compatibilidade retroativa: + +```python Code +import asyncio + +async def stream_crew(): + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True + ) + + # Iniciar streaming async baseado em threads + streaming = await crew.kickoff_async(inputs={"topic": "AI"}) + + # Iteração assíncrona sobre chunks + async for chunk in streaming: + print(chunk.content, end="", flush=True) + + # Acessar resultado final + result = streaming.result + print(f"\n\nSaída final: {result.raw}") + +asyncio.run(stream_crew()) +``` + + +Para cargas de trabalho de alta concorrência, `akickoff()` é recomendado pois usa async nativo para execução de tasks, operações de memória e recuperação de conhecimento. Consulte o guia [Iniciar Crew de Forma Assíncrona](/pt-BR/learn/kickoff-async) para mais detalhes. + + +## Streaming com kickoff_for_each + +Ao executar uma crew para múltiplas entradas com `kickoff_for_each()`, o streaming funciona de forma diferente dependendo se você usa síncrono ou assíncrono: + +### kickoff_for_each Síncrono + +Com `kickoff_for_each()` síncrono, você obtém uma lista de objetos `CrewStreamingOutput`, um para cada entrada: + +```python Code +crew = Crew( + agents=[researcher], + tasks=[task], + stream=True +) + +inputs_list = [ + {"topic": "AI in healthcare"}, + {"topic": "AI in finance"} +] + +# Retorna lista de saídas de streaming +streaming_outputs = crew.kickoff_for_each(inputs=inputs_list) + +# Iterar sobre cada saída de streaming +for i, streaming in enumerate(streaming_outputs): + print(f"\n=== Entrada {i + 1} ===") + for chunk in streaming: + print(chunk.content, end="", flush=True) + + result = streaming.result + print(f"\n\nResultado {i + 1}: {result.raw}") +``` + +### kickoff_for_each_async Assíncrono + +Com `kickoff_for_each_async()` assíncrono, você obtém um único `CrewStreamingOutput` que produz chunks de todas as crews conforme chegam concorrentemente: + +```python Code +import asyncio + +async def stream_multiple_crews(): + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True + ) + + inputs_list = [ + {"topic": "AI in healthcare"}, + {"topic": "AI in finance"} + ] + + # Retorna saída de streaming única para todas as crews + streaming = await crew.kickoff_for_each_async(inputs=inputs_list) + + # Chunks de todas as crews chegam conforme são gerados + async for chunk in streaming: + print(f"[{chunk.task_name}] {chunk.content}", end="", flush=True) + + # Acessar todos os resultados + results = streaming.results # Lista de objetos CrewOutput + for i, result in enumerate(results): + print(f"\n\nResultado {i + 1}: {result.raw}") + +asyncio.run(stream_multiple_crews()) +``` + +## Tipos de Chunk de Stream + +Chunks podem ser de diferentes tipos, indicados pelo campo `chunk_type`: + +### Chunks TEXT + +Conteúdo de texto padrão de respostas do LLM: + +```python Code +for chunk in streaming: + if chunk.chunk_type == StreamChunkType.TEXT: + print(chunk.content, end="", flush=True) +``` + +### Chunks TOOL_CALL + +Informações sobre chamadas de ferramentas sendo feitas: + +```python Code +for chunk in streaming: + if chunk.chunk_type == StreamChunkType.TOOL_CALL: + print(f"\nChamando ferramenta: {chunk.tool_call.tool_name}") + print(f"Argumentos: {chunk.tool_call.arguments}") +``` + +## Exemplo Prático: Construindo uma UI com Streaming + +Aqui está um exemplo completo mostrando como construir uma aplicação interativa com streaming: + +```python Code +import asyncio +from crewai import Agent, Crew, Task +from crewai.types.streaming import StreamChunkType + +async def interactive_research(): + # Criar crew com streaming ativado + researcher = Agent( + role="Research Analyst", + goal="Provide detailed analysis on any topic", + backstory="You are an expert researcher with broad knowledge.", + ) + + task = Task( + description="Research and analyze: {topic}", + expected_output="A comprehensive analysis with key insights", + agent=researcher, + ) + + crew = Crew( + agents=[researcher], + tasks=[task], + stream=True, + verbose=False + ) + + # Obter entrada do usuário + topic = input("Digite um tópico para pesquisar: ") + + print(f"\n{'='*60}") + print(f"Pesquisando: {topic}") + print(f"{'='*60}\n") + + # Iniciar execução com streaming + streaming = await crew.kickoff_async(inputs={"topic": topic}) + + current_task = "" + async for chunk in streaming: + # Mostrar transições de task + if chunk.task_name != current_task: + current_task = chunk.task_name + print(f"\n[{chunk.agent_role}] Trabalhando em: {chunk.task_name}") + print("-" * 60) + + # Exibir chunks de texto + if chunk.chunk_type == StreamChunkType.TEXT: + print(chunk.content, end="", flush=True) + + # Exibir chamadas de ferramentas + elif chunk.chunk_type == StreamChunkType.TOOL_CALL and chunk.tool_call: + print(f"\n🔧 Usando ferramenta: {chunk.tool_call.tool_name}") + + # Mostrar resultado final + result = streaming.result + print(f"\n\n{'='*60}") + print("Análise Completa!") + print(f"{'='*60}") + print(f"\nUso de Tokens: {result.token_usage}") + +asyncio.run(interactive_research()) +``` + +## Casos de Uso + +O streaming é particularmente valioso para: + +- **Aplicações Interativas**: Fornecer feedback em tempo real aos usuários enquanto os agentes trabalham +- **Tasks de Longa Duração**: Mostrar progresso para pesquisa, análise ou geração de conteúdo +- **Depuração e Monitoramento**: Observar comportamento e tomada de decisão dos agentes em tempo real +- **Experiência do Usuário**: Reduzir latência percebida mostrando resultados incrementais +- **Dashboards ao Vivo**: Construir interfaces de monitoramento que exibem status de execução da crew + +## Notas Importantes + +- O streaming ativa automaticamente o streaming do LLM para todos os agentes na crew +- Você deve iterar através de todos os chunks antes de acessar a propriedade `.result` +- Para `kickoff_for_each_async()` com streaming, use `.results` (plural) para obter todas as saídas +- O streaming adiciona overhead mínimo e pode realmente melhorar a performance percebida +- Cada chunk inclui contexto completo (task, agente, tipo de chunk) para UIs ricas + +## Tratamento de Erros + +Trate erros durante a execução com streaming: + +```python Code +streaming = crew.kickoff(inputs={"topic": "AI"}) + +try: + for chunk in streaming: + print(chunk.content, end="", flush=True) + + result = streaming.result + print(f"\nSucesso: {result.raw}") + +except Exception as e: + print(f"\nErro durante o streaming: {e}") + if streaming.is_completed: + print("O streaming foi completado mas ocorreu um erro") +``` + +Ao aproveitar o streaming, você pode construir aplicações mais responsivas e interativas com o CrewAI, fornecendo aos usuários visibilidade em tempo real da execução dos agentes e resultados. \ No newline at end of file