Skip to content
Open
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
4 changes: 2 additions & 2 deletions DeepResearchAgent/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ ARG IMAGE_REPO=opea
ARG BASE_TAG=latest
FROM opea/comps-base:$BASE_TAG

COPY ./deep_researcher.yaml $HOME/deep_researcher.yaml
COPY ./utils.py $HOME/utils.py
COPY ./research_agents $HOME/research_agents
COPY ./requirements.txt $HOME/requirements.txt
COPY ./agent_factory.py $HOME/agent_factory.py
COPY ./research_agent.py $HOME/research_agent.py

USER root
Expand Down
12 changes: 4 additions & 8 deletions DeepResearchAgent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ Deep Research Agents are a new class of autonomous AI systems designed to perfor

## Overview

In this application, we leverage the deep research agent implementation of [langchain-ai/open_deep_research](https://github.com/langchain-ai/open_deep_research), and deploy it on the Intel platform with opea microserice.

![Architecture Overview](assets/img/opea-deep-research-agent.png)
In this application, we leverage the deep research agent implementation of [langchain-ai/deepagents](https://github.com/langchain-ai/deepagents), and deploy it on the Intel platform with opea microserice.

## Setup Deployment Environment

```
# Configure deep_researcher.yaml with your llm model served by the vllm

```shell
# get your TAVILY_API_KEY from https://app.tavily.com/
export TAVILY_API_KEY=""

# get your HuggingFace Access Token from https://huggingface.co/docs/transformers.js/en/guides/private#step-1-generating-a-user-access-token
export HF_TOKEN=""

Expand All @@ -31,9 +28,8 @@ source ./set_env.sh

To deploy the Deep Research Agent services, execute the docker compose up command with the appropriate arguments. For a default deployment, execute:

```
```shell
docker compose -f docker_compose/intel/hpu/gaudi/compose.yaml up -d

```

## Validate Microservice
Expand Down
75 changes: 75 additions & 0 deletions DeepResearchAgent/agent_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

import os
from datetime import datetime
from typing import Any

from langchain_openai import ChatOpenAI


def create_deepagents_research_agent() -> Any:
from deepagents import create_deep_agent
from research_agents.deepagents.prompts import (
RESEARCH_WORKFLOW_INSTRUCTIONS,
RESEARCHER_INSTRUCTIONS,
SUBAGENT_DELEGATION_INSTRUCTIONS,
)
from research_agents.deepagents.tools import tavily_search, think_tool

# Limits
max_concurrent_research_units = os.environ.get("MAX_CONCURRENT_RESEARCH_UNITS", 3)
max_researcher_iterations = os.environ.get("MAX_RESEARCHER_ITERATIONS", 3)

# Custom instructions (if any)
instructions_researcher = os.environ.get("RESEARCHER_INSTRUCTIONS", RESEARCHER_INSTRUCTIONS)
instructions_research_workflow = os.environ.get("RESEARCH_WORKFLOW_INSTRUCTIONS", RESEARCH_WORKFLOW_INSTRUCTIONS)
instructions_subagent_delegation = os.environ.get(
"SUBAGENT_DELEGATION_INSTRUCTIONS", SUBAGENT_DELEGATION_INSTRUCTIONS
)

# Combine orchestrator instructions (RESEARCHER_INSTRUCTIONS only for sub-agents)
INSTRUCTIONS = (
instructions_research_workflow
+ "\n\n"
+ "=" * 80
+ "\n\n"
+ instructions_subagent_delegation.format(
max_concurrent_research_units=max_concurrent_research_units,
max_researcher_iterations=max_researcher_iterations,
)
)

# Get current date
current_date = datetime.now().strftime("%Y-%m-%d")

# Research agent definition
research_sub_agent = {
"name": "research-agent",
"description": "Delegate research to the sub-agent researcher. Only give this researcher one topic at a time.",
"system_prompt": instructions_researcher.format(date=current_date),
"tools": [tavily_search, think_tool],
}

# LLM serving endpoint
model = ChatOpenAI(
openai_api_base=os.environ.get("OPENAI_BASE_URL", "http://0.0.0.0:8000/v1/"),
openai_api_key=os.environ.get("OPENAI_API_KEY", "empty-api-key"),
model_name=os.environ.get("LLM_MODEL_ID", "meta-llama/Llama-3.3-70B-Instruct"),
temperature=0.0,
)

# Create the agent
return create_deep_agent(
model=model,
tools=[tavily_search, think_tool],
system_prompt=INSTRUCTIONS,
subagents=[research_sub_agent],
)


def create_agent(impl="DeepAgents") -> Any:
if impl == "DeepAgents":
return create_deepagents_research_agent()
else:
raise ValueError(f"Unknown agent implementation: {impl}")
Binary file not shown.
11 changes: 0 additions & 11 deletions DeepResearchAgent/deep_researcher.yaml

This file was deleted.

30 changes: 15 additions & 15 deletions DeepResearchAgent/docker_compose/intel/hpu/gaudi/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,12 @@ x-common-environment:
http_proxy: ${http_proxy}
https_proxy: ${https_proxy}

x-common-agent-environment:
&common-agent-env
<<: *common-env
HF_TOKEN: ${HF_TOKEN}
model: ${LLM_MODEL_ID}
TAVILY_API_KEY: ${TAVILY_API_KEY}
OPENAI_API_KEY: ${OPENAI_API_KEY}
OPENAI_BASE_URL: ${OPENAI_BASE_URL}

services:

vllm-service:
image: opea/vllm-gaudi:1.22.0
container_name: vllm-gaudi-server
ports:
- "8000:8000"
- ${VLLM_PORT:-8000}:8000
volumes:
- ${HF_CACHE_DIR:-./data}:/data
environment:
Expand All @@ -34,18 +24,18 @@ services:
OMPI_MCA_btl_vader_single_copy_mechanism: none
LLM_MODEL_ID: ${LLM_MODEL_ID}
VLLM_TORCH_PROFILER_DIR: "/mnt"
VLLM_SKIP_WARMUP: true
VLLM_SKIP_WARMUP: ${VLLM_SKIP_WARMUP:-true}
PT_HPU_ENABLE_LAZY_COLLECTIVES: true
healthcheck:
test: ["CMD-SHELL", "curl -f http://$HOST_IP:8000/health || exit 1"]
test: ["CMD-SHELL", "curl -f http://${HOST_IP}:${VLLM_PORT:-8000}/health || exit 1"]
interval: 10s
timeout: 10s
retries: 100
runtime: habana
cap_add:
- SYS_NICE
ipc: host
command: --model ${LLM_MODEL_ID} --tensor-parallel-size ${NUM_CARDS} --host 0.0.0.0 --port 8000 --max-seq-len-to-capture $MAX_LEN
command: --model ${LLM_MODEL_ID} --tensor-parallel-size ${NUM_CARDS} --enable-auto-tool-choice --tool-call-parser ${TOOL_CALL_PARSER} --host 0.0.0.0 --port 8000 --max-seq-len-to-capture ${MAX_LEN}

deep-research-agent-server:
image: ${REGISTRY:-opea}/deep-research-agent:${TAG:-latest}
Expand All @@ -56,4 +46,14 @@ services:
- "8022:8022"
ipc: host
environment:
<<: *common-agent-env
<<: *common-env
HF_TOKEN: ${HF_TOKEN}
model: ${LLM_MODEL_ID}
TAVILY_API_KEY: ${TAVILY_API_KEY}
OPENAI_API_KEY: ${OPENAI_API_KEY}
OPENAI_BASE_URL: ${OPENAI_BASE_URL}
MAX_CONCURRENT_RESEARCH_UNITS: ${MAX_CONCURRENT_RESEARCH_UNITS:-3}
MAX_RESEARCHER_ITERATIONS: ${MAX_RESEARCHER_ITERATIONS:-3}
RESEARCHER_INSTRUCTIONS: ${RESEARCHER_INSTRUCTIONS:-""}
RESEARCH_WORKFLOW_INSTRUCTIONS: ${RESEARCH_WORKFLOW_INSTRUCTIONS:-""}
SUBAGENT_DELEGATION_INSTRUCTIONS: ${SUBAGENT_DELEGATION_INSTRUCTIONS:-""}
93 changes: 75 additions & 18 deletions DeepResearchAgent/docker_compose/intel/hpu/gaudi/set_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,102 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

# Navigate to the parent directory and source the environment
# ==============================================================================
# Environment Configuration for DeepResearchAgent on Intel Gaudi HPU
# ==============================================================================

# Get the directory where this script is located
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"

# Source the parent environment configuration file
pushd "$SCRIPT_DIR/../../../../../" > /dev/null
source .set_env.sh
popd > /dev/null

# Function to check if a variable is set
# ------------------------------------------------------------------------------
# Helper Functions
# ------------------------------------------------------------------------------

# Validates that a required environment variable is set
check_var() {
local var_name="$1"
local var_value="${!var_name}"
if [ -z "${var_value}" ]; then
echo "Error: ${var_name} is not set. Please set ${var_name}."
return 1 # Return an error code but do not exit the script
return 1 # Return error but don't exit to allow other checks to run
fi
}

# Check critical variables
check_var "HF_TOKEN"
# ------------------------------------------------------------------------------
# Validate Required API Keys
# ------------------------------------------------------------------------------

check_var "HF_TOKEN" # HuggingFace token for model access
check_var "TAVILY_API_KEY" # Tavily API key for web search functionality

# ------------------------------------------------------------------------------
# Network Configuration
# ------------------------------------------------------------------------------

# Detect the primary IP address of the host machine
export ip_address=$(hostname -I | awk '{print $1}')
export HOST_IP=${ip_address}

# VLLM configuration
# Update proxy settings to include the host IP
export no_proxy=${no_proxy},${ip_address}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}

# ------------------------------------------------------------------------------
# vLLM Service Configuration
# ------------------------------------------------------------------------------

# Port where vLLM service will be accessible
export VLLM_PORT="${VLLM_PORT:-8000}"
export VLLM_VOLUME="${VLLM_VOLUME:-/data2/huggingface}"
export VLLM_IMAGE="${VLLM_IMAGE:-opea/vllm-gaudi:latest}"

# ------------------------------------------------------------------------------
# Language Model Configuration
# ------------------------------------------------------------------------------

# LLM model to use for the Deep Research Agent
# See supported models and tool call parsers at:
# https://docs.vllm.ai/en/stable/features/tool_calling/#automatic-function-calling
export LLM_MODEL_ID="${LLM_MODEL_ID:-meta-llama/Llama-3.3-70B-Instruct}"

# Parser for handling function/tool calls (must match the model)
export TOOL_CALL_PARSER="${TOOL_CALL_PARSER:-llama3_json}"

# Maximum sequence length for model context (131072 = ~128K tokens)
export MAX_LEN="${MAX_LEN:-131072}"

# Number of Gaudi accelerator cards to use
export NUM_CARDS="${NUM_CARDS:-4}"

# Directory for caching HuggingFace models
export HF_CACHE_DIR="${HF_CACHE_DIR:-"./data"}"
export OPENAI_BASE_URL="http://${ip_address}:8000/v1"
export OPENAI_API_KEY="empty"
export no_proxy=${no_proxy}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}

# OpenAI-compatible API endpoint URL for vLLM
export OPENAI_BASE_URL="http://${ip_address}:${VLLM_PORT}/v1"

# ------------------------------------------------------------------------------
# API Keys and Authentication
# ------------------------------------------------------------------------------

export HF_TOKEN="${HF_TOKEN}" # HuggingFace authentication token
export OPENAI_API_KEY="empty-api-key" # Placeholder for vLLM compatibility
export TAVILY_API_KEY="${TAVILY_API_KEY}" # Tavily search API key

# ------------------------------------------------------------------------------
# Deep Research Agent Configuration
# ------------------------------------------------------------------------------

# Maximum number of research units that can run concurrently
export MAX_CONCURRENT_RESEARCH_UNITS="${MAX_CONCURRENT_RESEARCH_UNITS:-3}"

# Hugging Face API token
export HF_TOKEN="${HF_TOKEN}"
# Maximum iterations per researcher before stopping
export MAX_RESEARCHER_ITERATIONS="${MAX_RESEARCHER_ITERATIONS:-3}"

# API keys
check_var "TAVILY_API_KEY"
export TAVILY_API_KEY="${TAVILY_API_KEY}"
# Custom instructions for agent behavior (leave empty for defaults)
export RESEARCHER_INSTRUCTIONS="" # Instructions for individual researchers
export RESEARCH_WORKFLOW_INSTRUCTIONS="" # Instructions for overall research workflow
export SUBAGENT_DELEGATION_INSTRUCTIONS="" # Instructions for task delegation between agents
8 changes: 8 additions & 0 deletions DeepResearchAgent/requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
deepagents
httpx
langchain_openai
langchain-tavily
langgraph-cli[inmem]
markdownify
rich
tavily-python
Loading
Loading