{"id":25212895,"url":"https://github.com/jina-ai/node-deepresearch","last_synced_at":"2025-05-13T21:12:40.678Z","repository":{"id":275520445,"uuid":"922423439","full_name":"jina-ai/node-DeepResearch","owner":"jina-ai","description":"Keep searching, reading webpages, reasoning until it finds the answer (or exceeding the token budget)","archived":false,"fork":false,"pushed_at":"2025-05-07T02:22:42.000Z","size":30956,"stargazers_count":4136,"open_issues_count":35,"forks_count":385,"subscribers_count":29,"default_branch":"main","last_synced_at":"2025-05-07T03:28:28.592Z","etag":null,"topics":["deepresearch","deepsearch"],"latest_commit_sha":null,"homepage":"https://search.jina.ai","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jina-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-26T06:46:28.000Z","updated_at":"2025-05-07T03:22:14.000Z","dependencies_parsed_at":"2025-04-07T23:00:30.117Z","dependency_job_id":"925367bd-a9dd-460a-a217-48f723260100","html_url":"https://github.com/jina-ai/node-DeepResearch","commit_stats":null,"previous_names":["jina-ai/node-deepresearch"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jina-ai%2Fnode-DeepResearch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jina-ai%2Fnode-DeepResearch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jina-ai%2Fnode-DeepResearch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jina-ai%2Fnode-DeepResearch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jina-ai","download_url":"https://codeload.github.com/jina-ai/node-DeepResearch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254029008,"owners_count":22002284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deepresearch","deepsearch"],"created_at":"2025-02-10T15:18:03.495Z","updated_at":"2025-05-13T21:12:35.663Z","avatar_url":"https://github.com/jina-ai.png","language":"TypeScript","funding_links":[],"categories":["Openai"],"sub_categories":[],"readme":"# DeepResearch\n\n[Official UI](https://search.jina.ai/) | [UI Code](https://github.com/jina-ai/deepsearch-ui) | [Stable API](https://jina.ai/deepsearch) | [Blog](https://jina.ai/news/a-practical-guide-to-implementing-deepsearch-deepresearch)\n\nKeep searching, reading webpages, reasoning until an answer is found (or the token budget is exceeded). Useful for deeply investigating a query.\n\n\u003e [!IMPORTANT]  \n\u003e Unlike OpenAI/Gemini/Perplexity's \"Deep Research\", we focus solely on **finding the right answers via our iterative process**. We don't optimize for long-form articles, that's a **completely different problem** – so if you need quick, concise answers from deep search, you're in the right place. If you're looking for AI-generated long reports like OpenAI/Gemini/Perplexity does, this isn't for you.\n\n```mermaid\n---\nconfig:\n  theme: mc\n  look: handDrawn\n---\nflowchart LR\n subgraph Loop[\"until budget exceed\"]\n    direction LR\n        Search[\"Search\"]\n        Read[\"Read\"]\n        Reason[\"Reason\"]\n  end\n    Query([\"Query\"]) --\u003e Loop\n    Search --\u003e Read\n    Read --\u003e Reason\n    Reason --\u003e Search\n    Loop --\u003e Answer([\"Answer\"])\n\n```\n\n## [Blog Post](https://jina.ai/news/a-practical-guide-to-implementing-deepsearch-deepresearch)\n\nWhether you like this implementation or not, I highly recommend you to read DeepSearch/DeepResearch implementation guide I wrote, which gives you a gentle intro to this topic.\n\n- [English Part I](https://jina.ai/news/a-practical-guide-to-implementing-deepsearch-deepresearch), [Part II](https://jina.ai/news/snippet-selection-and-url-ranking-in-deepsearch-deepresearch)\n- [中文微信公众号 第一讲](https://mp.weixin.qq.com/s/-pPhHDi2nz8hp5R3Lm_mww), [第二讲](https://mp.weixin.qq.com/s/apnorBj4TZs3-Mo23xUReQ)\n- [日本語: DeepSearch/DeepResearch 実装の実践ガイド](https://jina.ai/ja/news/a-practical-guide-to-implementing-deepsearch-deepresearch)\n\n## Try it Yourself\n\nWe host an online deployment of this **exact** codebase, which allows you to do a vibe-check; or use it as daily productivity tools.\n\nhttps://search.jina.ai\n\nThe official API is also available for you to use:\n\n```\nhttps://deepsearch.jina.ai/v1/chat/completions\n```\n\nLearn more about the API at https://jina.ai/deepsearch\n\n\n\n\n## Install\n\n```bash\ngit clone https://github.com/jina-ai/node-DeepResearch.git\ncd node-DeepResearch\nnpm install\n```\n\n[安装部署视频教程 on Youtube](https://youtu.be/vrpraFiPUyA)\n\nIt is also available on npm but not recommended for now, as the code is still under active development.\n\n\n## Usage\n\nWe use Gemini (latest `gemini-2.0-flash`) / OpenAI / [LocalLLM](#use-local-llm) for reasoning, [Jina Reader](https://jina.ai/reader) for searching and reading webpages, you can get a free API key with 1M tokens from jina.ai. \n\n```bash\nexport GEMINI_API_KEY=...  # for gemini\n# export OPENAI_API_KEY=... # for openai\n# export LLM_PROVIDER=openai # for openai\nexport JINA_API_KEY=jina_...  # free jina api key, get from https://jina.ai/reader\n\nnpm run dev $QUERY\n```\n\n### Official Site\n\nYou can try it on [our official site](https://search.jina.ai).\n\n### Official API\n\nYou can also use [our official DeepSearch API](https://jina.ai/deepsearch):\n\n```\nhttps://deepsearch.jina.ai/v1/chat/completions\n```\n\nYou can use it with any OpenAI-compatible client. \n\nFor the authentication Bearer, API key, rate limit, get from https://jina.ai/deepsearch.\n\n#### Client integration guidelines\n\nIf you are building a web/local/mobile client that uses `Jina DeepSearch API`, here are some design guidelines:\n- Our API is fully compatible with [OpenAI API schema](https://platform.openai.com/docs/api-reference/chat/create), this should greatly simplify the integration process. The model name is `jina-deepsearch-v1`.\n- Our DeepSearch API is a reasoning+search grounding LLM, so it's best for questions that require deep reasoning and search.\n- Two special tokens are introduced `\u003cthink\u003e...\u003c/think\u003e`. Please render them with care.\n- Citations are often provided, and in [Github-flavored markdown footnote format](https://github.blog/changelog/2021-09-30-footnotes-now-supported-in-markdown-fields/), e.g. `[^1]`, `[^2]`, ...\n- Guide the user to get a Jina API key from https://jina.ai, with 1M free tokens for new API key.\n- There are rate limits, [between 10RPM to 30RPM depending on the API key tier](https://jina.ai/contact-sales#rate-limit).\n- [Download Jina AI logo here](https://jina.ai/logo-Jina-1024.zip)\n\n## Demo\n\u003e was recorded with `gemini-1.5-flash`, the latest `gemini-2.0-flash` leads to much better results!\n\nQuery: `\"what is the latest blog post's title from jina ai?\"`\n3 steps; answer is correct!\n![demo1](.github/visuals/demo.gif)\n\nQuery: `\"what is the context length of readerlm-v2?\"`\n2 steps; answer is correct!\n![demo1](.github/visuals/demo3.gif)\n\nQuery: `\"list all employees from jina ai that u can find, as many as possible\"` \n11 steps; partially correct! but im not in the list :(\n![demo1](.github/visuals/demo2.gif)\n\nQuery: `\"who will be the biggest competitor of Jina AI\"` \n42 steps; future prediction kind, so it's arguably correct! atm Im not seeing `weaviate` as a competitor, but im open for the future \"i told you so\" moment.\n![demo1](.github/visuals/demo4.gif)\n\nMore examples:\n\n```\n# example: no tool calling \nnpm run dev \"1+1=\"\nnpm run dev \"what is the capital of France?\"\n\n# example: 2-step\nnpm run dev \"what is the latest news from Jina AI?\"\n\n# example: 3-step\nnpm run dev \"what is the twitter account of jina ai's founder\"\n\n# example: 13-step, ambiguious question (no def of \"big\")\nnpm run dev \"who is bigger? cohere, jina ai, voyage?\"\n\n# example: open question, research-like, long chain of thoughts\nnpm run dev \"who will be president of US in 2028?\"\nnpm run dev \"what should be jina ai strategy for 2025?\"\n```\n\n## Use Local LLM\n\n\u003e Note, not every LLM works with our reasoning flow, we need those who support structured output (sometimes called JSON Schema output, object output) well. Feel free to purpose a PR to add more open-source LLMs to the working list.\n\nIf you use Ollama or LMStudio, you can redirect the reasoning request to your local LLM by setting the following environment variables:\n\n```bash\nexport LLM_PROVIDER=openai  # yes, that's right - for local llm we still use openai client\nexport OPENAI_BASE_URL=http://127.0.0.1:1234/v1  # your local llm endpoint\nexport OPENAI_API_KEY=whatever  # random string would do, as we don't use it (unless your local LLM has authentication)\nexport DEFAULT_MODEL_NAME=qwen2.5-7b  # your local llm model name\n```\n\n\n## OpenAI-Compatible Server API\n\nIf you have a GUI client that supports OpenAI API (e.g. [CherryStudio](https://docs.cherry-ai.com/), [Chatbox](https://github.com/Bin-Huang/chatbox)) , you can simply config it to use this server.\n\n![demo1](.github/visuals/demo6.gif)\n\nStart the server:\n```bash\n# Without authentication\nnpm run serve\n\n# With authentication (clients must provide this secret as Bearer token)\nnpm run serve --secret=your_secret_token\n```\n\nThe server will start on http://localhost:3000 with the following endpoint:\n\n### POST /v1/chat/completions\n```bash\n# Without authentication\ncurl http://localhost:3000/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"jina-deepsearch-v1\",\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"Hello!\"\n      }\n    ]\n  }'\n\n# With authentication (when server is started with --secret)\ncurl http://localhost:3000/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer your_secret_token\" \\\n  -d '{\n    \"model\": \"jina-deepsearch-v1\",\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"Hello!\"\n      }\n    ],\n    \"stream\": true\n  }'\n```\n\nResponse format:\n```json\n{\n  \"id\": \"chatcmpl-123\",\n  \"object\": \"chat.completion\",\n  \"created\": 1677652288,\n  \"model\": \"jina-deepsearch-v1\",\n  \"system_fingerprint\": \"fp_44709d6fcb\",\n  \"choices\": [{\n    \"index\": 0,\n    \"message\": {\n      \"role\": \"assistant\",\n      \"content\": \"YOUR FINAL ANSWER\"\n    },\n    \"logprobs\": null,\n    \"finish_reason\": \"stop\"\n  }],\n  \"usage\": {\n    \"prompt_tokens\": 9,\n    \"completion_tokens\": 12,\n    \"total_tokens\": 21\n  }\n}\n```\n\nFor streaming responses (stream: true), the server sends chunks in this format:\n```json\n{\n  \"id\": \"chatcmpl-123\",\n  \"object\": \"chat.completion.chunk\",\n  \"created\": 1694268190,\n  \"model\": \"jina-deepsearch-v1\",\n  \"system_fingerprint\": \"fp_44709d6fcb\",\n  \"choices\": [{\n    \"index\": 0,\n    \"delta\": {\n      \"content\": \"...\"\n    },\n    \"logprobs\": null,\n    \"finish_reason\": null\n  }]\n}\n```\n\nNote: The think content in streaming responses is wrapped in XML tags:\n```\n\u003cthink\u003e\n[thinking steps...]\n\u003c/think\u003e\n[final answer]\n```\n\n\n## Docker Setup\n\n### Build Docker Image\nTo build the Docker image for the application, run the following command:\n```bash\ndocker build -t deepresearch:latest .\n```\n\n### Run Docker Container\nTo run the Docker container, use the following command:\n```bash\ndocker run -p 3000:3000 --env GEMINI_API_KEY=your_gemini_api_key --env JINA_API_KEY=your_jina_api_key deepresearch:latest\n```\n\n### Docker Compose\nYou can also use Docker Compose to manage multi-container applications. To start the application with Docker Compose, run:\n```bash\ndocker-compose up\n```\n\n## How Does it Work?\n\nNot sure a flowchart helps, but here it is:\n\n```mermaid\nflowchart TD\n    Start([Start]) --\u003e Init[Initialize context \u0026 variables]\n    Init --\u003e CheckBudget{Token budget\u003cbr/\u003eexceeded?}\n    CheckBudget --\u003e|No| GetQuestion[Get current question\u003cbr/\u003efrom gaps]\n    CheckBudget --\u003e|Yes| BeastMode[Enter Beast Mode]\n\n    GetQuestion --\u003e GenPrompt[Generate prompt]\n    GenPrompt --\u003e ModelGen[Generate response\u003cbr/\u003eusing Gemini]\n    ModelGen --\u003e ActionCheck{Check action\u003cbr/\u003etype}\n\n    ActionCheck --\u003e|answer| AnswerCheck{Is original\u003cbr/\u003equestion?}\n    AnswerCheck --\u003e|Yes| EvalAnswer[Evaluate answer]\n    EvalAnswer --\u003e IsGoodAnswer{Is answer\u003cbr/\u003edefinitive?}\n    IsGoodAnswer --\u003e|Yes| HasRefs{Has\u003cbr/\u003ereferences?}\n    HasRefs --\u003e|Yes| End([End])\n    HasRefs --\u003e|No| GetQuestion\n    IsGoodAnswer --\u003e|No| StoreBad[Store bad attempt\u003cbr/\u003eReset context]\n    StoreBad --\u003e GetQuestion\n\n    AnswerCheck --\u003e|No| StoreKnowledge[Store as intermediate\u003cbr/\u003eknowledge]\n    StoreKnowledge --\u003e GetQuestion\n\n    ActionCheck --\u003e|reflect| ProcessQuestions[Process new\u003cbr/\u003esub-questions]\n    ProcessQuestions --\u003e DedupQuestions{New unique\u003cbr/\u003equestions?}\n    DedupQuestions --\u003e|Yes| AddGaps[Add to gaps queue]\n    DedupQuestions --\u003e|No| DisableReflect[Disable reflect\u003cbr/\u003efor next step]\n    AddGaps --\u003e GetQuestion\n    DisableReflect --\u003e GetQuestion\n\n    ActionCheck --\u003e|search| SearchQuery[Execute search]\n    SearchQuery --\u003e NewURLs{New URLs\u003cbr/\u003efound?}\n    NewURLs --\u003e|Yes| StoreURLs[Store URLs for\u003cbr/\u003efuture visits]\n    NewURLs --\u003e|No| DisableSearch[Disable search\u003cbr/\u003efor next step]\n    StoreURLs --\u003e GetQuestion\n    DisableSearch --\u003e GetQuestion\n\n    ActionCheck --\u003e|visit| VisitURLs[Visit URLs]\n    VisitURLs --\u003e NewContent{New content\u003cbr/\u003efound?}\n    NewContent --\u003e|Yes| StoreContent[Store content as\u003cbr/\u003eknowledge]\n    NewContent --\u003e|No| DisableVisit[Disable visit\u003cbr/\u003efor next step]\n    StoreContent --\u003e GetQuestion\n    DisableVisit --\u003e GetQuestion\n\n    BeastMode --\u003e FinalAnswer[Generate final answer] --\u003e End\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjina-ai%2Fnode-deepresearch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjina-ai%2Fnode-deepresearch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjina-ai%2Fnode-deepresearch/lists"}