Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
20 changes: 20 additions & 0 deletions DeepResearchAgent/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

ARG IMAGE_REPO=opea
ARG BASE_TAG=latest
FROM $IMAGE_REPO/comps-base:$BASE_TAG

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

USER root
ARG uvpip='uv pip install --system --no-cache-dir'
RUN pip install --no-cache-dir --upgrade pip setuptools uv && \
$uvpip -r requirements.txt

USER user

ENTRYPOINT ["python", "research_agent.py"]
40 changes: 40 additions & 0 deletions DeepResearchAgent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Deep Research Agent Application

Deep Research Agents are a new class of autonomous AI systems designed to perform complex, multi-step research tasks that typically require human-level reasoning, planning, and synthesis.

## Setup Deployment Environment

```
# 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=""

# set proxy if needed by your machine
export http_proxy=""
export https_proxy=""
export no_proxy=""


source ./set_env.sh
```

## Deploy the Services Using Docker Compose

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

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

```

## Validate Microservice

```shell
curl http://${host_ip}:8022/v1/deep_research_agent \
-X POST \
-d '{"question":"What is Deep Learning?"}' \
-H 'Content-Type: application/json'
```

## Benchmarks
1 change: 1 addition & 0 deletions DeepResearchAgent/benchmark/accuracy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## Deep Research Agent Benchmarks
11 changes: 11 additions & 0 deletions DeepResearchAgent/deep_researcher.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

agent:
type: langchain_deep_researcher
search_api: "tavily"
planner_provider: "openai"
planner_model: "meta-llama/Llama-3.3-70B-Instruct"
writer_provider: "openai"
writer_model: "meta-llama/Llama-3.3-70B-Instruct"
max_search_depth: 2
57 changes: 57 additions & 0 deletions DeepResearchAgent/docker_compose/intel/hpu/gaudi/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0


x-common-environment:
&common-env
no_proxy: ${no_proxy}
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: ${REGISTRY:-opea}/vllm-gaudi:${TAG:-latest}
container_name: vllm-gaudi-server
ports:
- "8000:8000"
volumes:
- ${HF_CACHE_DIR:-./data}:/data
environment:
<<: *common-env
HF_TOKEN: ${HF_TOKEN}
HF_HOME: ./data
HABANA_VISIBLE_DEVICES: all
OMPI_MCA_btl_vader_single_copy_mechanism: none
LLM_MODEL_ID: ${LLM_MODEL_ID}
VLLM_TORCH_PROFILER_DIR: "/mnt"
VLLM_SKIP_WARMUP: true
PT_HPU_ENABLE_LAZY_COLLECTIVES: true
healthcheck:
test: ["CMD-SHELL", "curl -f http://$HOST_IP: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

deep-research-agent-server:
image: ${REGISTRY:-opea}/deep-research-agent:${TAG:-latest}
container_name: deep-research-agent-server
ports:
- "8022:8022"
ipc: host
environment:
<<: *common-agent-env
45 changes: 45 additions & 0 deletions DeepResearchAgent/docker_compose/intel/set_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

# Navigate to the parent directory and source the environment
pushd "../../" > /dev/null
source .set_env.sh
popd > /dev/null

# Function to check if a 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
fi
}

# Check critical variables
check_var "HF_TOKEN"
export ip_address=$(hostname -I | awk '{print $1}')

# VLLM configuration
export VLLM_PORT="${VLLM_PORT:-8000}"
export VLLM_VOLUME="${VLLM_VOLUME:-/data2/huggingface}"
export VLLM_IMAGE="${VLLM_IMAGE:-opea/vllm-gaudi:latest}"
export LLM_MODEL_ID="${LLM_MODEL_ID:-meta-llama/Llama-3.3-70B-Instruct}"
export MAX_LEN="${MAX_LEN:-131072}"
export NUM_CARDS="${NUM_CARDS:-4}"
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}


# Hugging Face API token
export HF_TOKEN="${HF_TOKEN}"

# API keys
check_var "TAVILY_API_KEY"
export TAVILY_API_KEY="${TAVILY_API_KEY}"
13 changes: 13 additions & 0 deletions DeepResearchAgent/docker_image_build/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

services:
deep_research_agent:
build:
args:
http_proxy: ${http_proxy}
https_proxy: ${https_proxy}
no_proxy: ${no_proxy}
context: ../
dockerfile: ./Dockerfile
image: ${REGISTRY:-opea}/deep-research-agent:${TAG:-latest}
1 change: 1 addition & 0 deletions DeepResearchAgent/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
open_deep_research # https://github.com/langchain-ai/open_deep_research
39 changes: 39 additions & 0 deletions DeepResearchAgent/research_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

import argparse
import json
import os
import re
from typing import List, Union

from comps import opea_microservices, register_microservice
from comps.cores.telemetry.opea_telemetry import opea_telemetry
from pydantic import BaseModel
from utils import *

agent = create_agent("./deep_researcher.yaml")


class SimpleRequest(BaseModel):
question: Union[str, List[str]]


@register_microservice(
name="opea_service@deep_research_agent",
endpoint="/v1/deep_research_agent",
host="0.0.0.0",
port=8022,
)
@opea_telemetry
async def run(request: SimpleRequest):

question = f"Question: {request.question}"

result = await agent(question)

return result


if __name__ == "__main__":
opea_microservices["opea_service@deep_research_agent"].start()
117 changes: 117 additions & 0 deletions DeepResearchAgent/tests/test_compose_on_gaudi.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

set -xe
IMAGE_REPO=${IMAGE_REPO:-"opea"}
IMAGE_TAG=${IMAGE_TAG:-"latest"}
echo "REGISTRY=IMAGE_REPO=${IMAGE_REPO}"
echo "TAG=IMAGE_TAG=${IMAGE_TAG}"
export REGISTRY=${IMAGE_REPO}
export TAG=${IMAGE_TAG}
export MODEL_CACHE=${model_cache:-"./data"}
export HF_TOKEN=${HF_TOKEN}
export TAVILY_API_KEY=${TAVILY_API_KEY}

WORKPATH=$(dirname "$PWD")
LOG_PATH="$WORKPATH/tests"
ip_address=$(hostname -I | awk '{print $1}')

function build_docker_images() {
cd $WORKPATH/docker_image_build
echo "Build all the images with --no-cache, check docker_image_build.log for details..."
docker compose -f build.yaml build --no-cache > ${LOG_PATH}/docker_image_build.log

docker images && sleep 1s
}

function start_services() {
cd $WORKPATH/docker_compose/intel/hpu/gaudi
source set_env.sh

# Start Docker Containers
docker compose -f compose.yaml up -d --quiet-pull > ${LOG_PATH}/start_services_with_compose.log
n=0
until [[ "$n" -ge 200 ]]; do
echo "n=$n"
docker logs vllm-gaudi-server > vllm_service_start.log 2>&1
if grep -q "Warmup finished" vllm_service_start.log; then
break
fi
sleep 5s
n=$((n+1))
done
}

function validate_service() {
local URL="$1"
local EXPECTED_RESULT="$2"
local SERVICE_NAME="$3"
local DOCKER_NAME="$4"
local INPUT_DATA="$5"

local HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST -d "$INPUT_DATA" -H 'Content-Type: application/json' "$URL")
if [ "$HTTP_STATUS" -eq 200 ]; then
echo "[ $SERVICE_NAME ] HTTP status is 200. Checking content..."

local CONTENT=$(curl -s -X POST -d "$INPUT_DATA" -H 'Content-Type: application/json' "$URL" | tee ${LOG_PATH}/${SERVICE_NAME}.log)

if echo "$CONTENT" | grep -q "$EXPECTED_RESULT"; then
echo "[ $SERVICE_NAME ] Content is as expected."
else
echo "[ $SERVICE_NAME ] Content does not match the expected result: $CONTENT"
docker logs ${DOCKER_NAME} >> ${LOG_PATH}/${SERVICE_NAME}.log
exit 1
fi
else
echo "[ $SERVICE_NAME ] HTTP status is not 200. Received status was $HTTP_STATUS"
docker logs ${DOCKER_NAME} >> ${LOG_PATH}/${SERVICE_NAME}.log
exit 1
fi
sleep 1s
}

function validate_microservices() {
# Check if the microservices are running correctly.

validate_service \
"${ip_address}:8022/v1/deep_research_agent" \
"deep" \
"deep-research-agent" \
"deep-research-agent-server" \
'{"question": "what is the deep learning?"}'
}


function stop_docker() {
cd $WORKPATH/docker_compose/intel/hpu/gaudi
docker compose -f compose.yaml down
}

function main() {

echo "::group::stop_docker"
stop_docker
echo "::endgroup::"

echo "::group::build_docker_images"
if [[ "$IMAGE_REPO" == "opea" ]]; then build_docker_images; fi
echo "::endgroup::"

echo "::group::start_services"
start_services
echo "::endgroup::"

echo "::group::validate_microservices"
validate_microservices
echo "::endgroup::"

echo "::group::stop_docker"
stop_docker
echo "::endgroup::"

docker system prune -f

}

main
Loading
Loading