diff --git a/doc/development/ai_features/index.md b/doc/development/ai_features/index.md
index 272975b3cb916935136086298e07d4de9151f1f4..8ad87a0d8c06c54c1e57d51bb7395ffddb4247bb 100644
--- a/doc/development/ai_features/index.md
+++ b/doc/development/ai_features/index.md
@@ -164,6 +164,15 @@ If you currently run you local GDK as Self-Managed (default for GDK), no argumen
 
 It's recommended to run `gdk restart` after the task succeeded.
 
+If you need to use evaluation framework (as described [here](https://gitlab.com/gitlab-org/modelops/ai-model-validation-and-research/ai-evaluation/prompt-library/-/blob/main/doc/how-to/run_duo_chat_eval.md?ref_type=heads#evaluation-on-issueepic))
+you can run special Rake task: `GITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup_evaluation[<test-group-name>]'`.
+It repeats steps from original setup Rake task, and also imports specially prepared groups and projects.
+Since we use `Setup` class (under `ee/lib/gitlab/duo/developments/setup.rb`) that requires "saas" mode to create a group
+(necessary for importing subgroups), you need to set `GITLAB_SIMULATE_SAAS=1` if it's currently `GITLAB_SIMULATE_SAAS=0`.
+This is just to complete the import successfully, and then you can switch back to `GITLAB_SIMULATE_SAAS=0`.
+To run this task, your GDK server must be running. After running this Rake task, import process will be in progress for
+said groups and projects.
+
 ### Recommended: Set `CLOUD_CONNECTOR_SELF_SIGN_TOKENS` environment variable
 
 If you plan to run you local GDK as Self-Managed (for GDK), it is recommended to set this environment variable.
diff --git a/ee/lib/gitlab/duo/developments/setup.rb b/ee/lib/gitlab/duo/developments/setup.rb
index 09781575e6571071b25f24e44409ffe974c9582c..ac34445c3323319bd8fb806dc9b3ccb254481a47 100644
--- a/ee/lib/gitlab/duo/developments/setup.rb
+++ b/ee/lib/gitlab/duo/developments/setup.rb
@@ -205,6 +205,8 @@ def print_result
 
             For more development guidelines, see https://docs.gitlab.com/ee/development/ai_features/index.html.
           MSG
+
+          Group.find_by_full_path(@namespace)
         end
       end
     end
diff --git a/ee/lib/gitlab/duo/developments/setup_groups_for_model_evaluation.rb b/ee/lib/gitlab/duo/developments/setup_groups_for_model_evaluation.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a21dc886c8f82964978432148b4efaf8f11b2244
--- /dev/null
+++ b/ee/lib/gitlab/duo/developments/setup_groups_for_model_evaluation.rb
@@ -0,0 +1,173 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module Duo
+    module Developments
+      class SetupGroupsForModelEvaluation
+        STRUCTURE = {
+          'gitlab_com' => { projects: ['www-gitlab-com'], name: 'gitlab-com' },
+          'gitlab_org' => { projects: ['gitlab'], name: 'gitlab-org' }
+        }.freeze
+        DOWNLOAD_FOLDER = 'tmp'
+        SAMPLES_FOLDER = 'duo_chat_samples'
+        GROUP_FILE_NAME = '01_group.tar.gz'
+        FILE_NAME = 'duo_chat_samples.tar.gz'
+        DOWNLOAD_URL = 'https://gitlab.com/gitlab-org/ai-powered/datasets/-/package_files/135727282/download'
+        GROUP_IMPORT_URL = '/api/v4/groups/import'
+        PROJECT_IMPORT_URL = '/api/v4/projects/import'
+
+        def initialize(group)
+          @main_group = group
+          @current_user = User.find_by(username: 'root') # rubocop:disable CodeReuse/ActiveRecord -- we need admin user
+        end
+
+        def execute
+          ensure_dev_mode!
+          set_token!
+          ensure_server_running!
+          download_and_unpack_file
+          create_subgroups
+          create_subprojects
+          delete_temporary_directory!
+          clean_up_token!
+
+          print_output
+        end
+
+        private
+
+        attr_reader :main_group, :current_user, :token_value, :token
+
+        # rubocop:disable Style/GuardClause -- Keep it explicit
+        def ensure_dev_mode!
+          unless ::Gitlab.dev_or_test_env?
+            raise <<~MSG
+              Setup can only be performed in development or test environment, however, the current environment is #{ENV['RAILS_ENV']}.
+            MSG
+          end
+        end
+        # rubocop:enable Style/GuardClause
+
+        def set_token!
+          @token = current_user.personal_access_tokens.create(scopes: ['api'], name: 'Automation token',
+            expires_at: 1.day.from_now)
+          @token_value = "token-string-#{SecureRandom.hex(10)}"
+          @token.set_token(token_value)
+          @token.save!
+        end
+
+        def clean_up_token!
+          token.destroy!
+        end
+
+        def ensure_server_running!
+          return true if Gitlab::HTTP.get(instance_url).success?
+
+          raise 'Server is not running, please start your GitLab server'
+        end
+
+        def download_and_unpack_file
+          download_path = Rails.root.join(DOWNLOAD_FOLDER, FILE_NAME)
+
+          download_file(DOWNLOAD_URL, download_path)
+          unzip_file(DOWNLOAD_FOLDER, FILE_NAME)
+
+          FileUtils.rm(download_path)
+        end
+
+        def download_file(url, path)
+          File.open(path, 'wb') do |file|
+            file.write(Gitlab::HTTP.get(url).parsed_response)
+          end
+        end
+
+        def unzip_file(download_folder, file_name)
+          Dir.chdir(Rails.root.join(download_folder)) do
+            `tar -xzvf #{file_name}`
+          end
+        end
+
+        def create_subprojects
+          STRUCTURE.each do |name, structure|
+            structure[:projects].each do |project|
+              project_file_name = "02_#{project.tr('-', '_')}.tar.gz"
+              file = Rails.root.join(DOWNLOAD_FOLDER, SAMPLES_FOLDER, name, project_file_name)
+              namespace = main_group.children.find_by(name: structure[:name]) # rubocop:disable CodeReuse/ActiveRecord -- we need to find a group by name
+              create_subproject(name: project, file: file, namespace_id: namespace.id)
+            end
+          end
+        end
+
+        def create_subgroups
+          STRUCTURE.each do |name, structure|
+            file = Rails.root.join(DOWNLOAD_FOLDER, SAMPLES_FOLDER, name, GROUP_FILE_NAME)
+            create_subgroup(name: structure[:name], file: file)
+          end
+        end
+
+        def create_subgroup(params)
+          url = "#{instance_url}#{GROUP_IMPORT_URL}"
+
+          headers = {
+            'PRIVATE-TOKEN' => token_value
+          }
+          body = {
+            name: params[:name],
+            path: params[:name],
+            file: File.new(params[:file]),
+            parent_id: main_group.id
+          }
+
+          response = Gitlab::HTTP.post(url, headers: headers, body: body)
+
+          puts "API response for #{params[:name]} import"
+          puts response.body
+        end
+
+        def create_subproject(params)
+          url = "#{instance_url}#{PROJECT_IMPORT_URL}"
+
+          headers = {
+            'PRIVATE-TOKEN' => token_value
+          }
+          body = {
+            name: params[:name],
+            path: params[:name],
+            file: File.new(params[:file]),
+            namespace: params[:namespace_id]
+          }
+
+          response = Gitlab::HTTP.post(url, headers: headers, body: body)
+
+          puts "API response for #{params[:name]} import"
+          puts response.body
+        end
+
+        def instance_url
+          "#{Gitlab.config.gitlab.protocol}://#{Gitlab.config.gitlab.host}:#{Gitlab.config.gitlab.port}"
+        end
+
+        def delete_temporary_directory!
+          FileUtils.rm_rf(Rails.root.join(DOWNLOAD_FOLDER, SAMPLES_FOLDER))
+        end
+
+        def print_output
+          puts <<~MSG
+            ----------------------------------------
+            Setup for evaluation Complete!
+            ----------------------------------------
+
+            Visit "#{Gitlab.config.gitlab.protocol}://#{Gitlab.config.gitlab.host}:#{Gitlab.config.gitlab.port}/#{main_group.full_path}"
+            and please see if the subgroups structure looks like:
+            |
+            - gitlab-com
+            |   - www-gitlab-com
+            |
+            - gitlab-org
+            |   - gitlab
+          MSG
+        end
+      end
+    end
+  end
+end
diff --git a/ee/lib/tasks/gitlab/duo.rake b/ee/lib/tasks/gitlab/duo.rake
index 41ebcf8082bf7c9872ff7ad413f1d107ada19b50..26286170a65a95dddc332abb4bcb397d2d1d26a1 100644
--- a/ee/lib/tasks/gitlab/duo.rake
+++ b/ee/lib/tasks/gitlab/duo.rake
@@ -11,5 +11,11 @@ namespace :gitlab do
     task enable_feature_flags: :gitlab_environment do
       Gitlab::Duo::Developments::FeatureFlagEnabler.execute
     end
+
+    desc 'GitLab | Duo | Create evaluation-ready group'
+    task :setup_evaluation, [:root_group_path] => :environment do |_, args|
+      group = Gitlab::Duo::Developments::Setup.new(args).execute
+      Gitlab::Duo::Developments::SetupGroupsForModelEvaluation.new(group).execute
+    end
   end
 end
diff --git a/ee/spec/lib/gitlab/duo/developments/setup_groups_for_model_evaluation_spec.rb b/ee/spec/lib/gitlab/duo/developments/setup_groups_for_model_evaluation_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..712ec2b1ee67255aa67f49074161822156822129
--- /dev/null
+++ b/ee/spec/lib/gitlab/duo/developments/setup_groups_for_model_evaluation_spec.rb
@@ -0,0 +1,174 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Duo::Developments::SetupGroupsForModelEvaluation, :saas, :gitlab_duo, :silence_stdout, feature_category: :duo_chat do
+  let_it_be(:user) { create(:user, username: 'root') }
+  let(:group) { create(:group) }
+  let(:setup_evaluation) { described_class.new(group) }
+  let(:http_response) { instance_double(HTTParty::Response, body: 'File content') }
+  let(:file_double) { instance_double(File) }
+
+  before do
+    allow(SecureRandom).to receive(:hex).and_return('1')
+  end
+
+  describe '#execute' do
+    context 'when the server is running' do
+      before do
+        allow(http_response).to receive(:success?).and_return(true)
+        allow(http_response).to receive(:parsed_response).and_return({})
+        allow(Gitlab::HTTP).to receive(:get).and_return(http_response)
+        allow(Gitlab::HTTP).to receive(:get).with("https://gitlab.com/gitlab-org/ai-powered/datasets/-/package_files/135727282/download")
+          .and_return(http_response)
+      end
+
+      it 'goes through the process' do
+        expect(setup_evaluation).to receive(:set_token!)
+        expect(setup_evaluation).to receive(:ensure_server_running!)
+        expect(setup_evaluation).to receive(:download_and_unpack_file)
+        expect(setup_evaluation).to receive(:create_subgroups)
+        expect(setup_evaluation).to receive(:create_subprojects)
+        expect(setup_evaluation).to receive(:delete_temporary_directory!)
+        expect(setup_evaluation).to receive(:clean_up_token!)
+        expect(setup_evaluation).to receive(:print_output)
+
+        setup_evaluation.execute
+      end
+
+      describe '#set_token!' do
+        it 'creates token' do
+          expect { setup_evaluation.send(:set_token!) }.to change { PersonalAccessToken.count }.by(1)
+        end
+      end
+
+      describe '#clean_up_token!' do
+        it 'deletes token' do
+          setup_evaluation.send(:set_token!)
+
+          expect { setup_evaluation.send(:clean_up_token!) }.to change { PersonalAccessToken.count }.by(-1)
+        end
+      end
+
+      describe '#download_and_unpack_file' do
+        it 'unzips the file' do
+          expect(setup_evaluation).to receive(:unzip_file).with('tmp', 'duo_chat_samples.tar.gz')
+
+          setup_evaluation.send(:download_and_unpack_file)
+        end
+
+        it 'runs through files' do
+          expect(FileUtils).to receive(:rm)
+
+          setup_evaluation.send(:download_and_unpack_file)
+        end
+      end
+
+      describe '#delete_temporary_directory!' do
+        it 'deletes folder' do
+          expect(FileUtils).to receive(:rm_rf).at_least(:once)
+
+          setup_evaluation.send(:delete_temporary_directory!)
+        end
+      end
+
+      describe '#create_subgroups' do
+        it 'creates subgroups' do
+          expect(setup_evaluation).to receive(:create_subgroup).with(name: 'gitlab-com',
+            file: Rails.root.join("tmp/duo_chat_samples/gitlab_com/01_group.tar.gz"))
+          expect(setup_evaluation).to receive(:create_subgroup).with(name: 'gitlab-org',
+            file: Rails.root.join("tmp/duo_chat_samples/gitlab_org/01_group.tar.gz"))
+
+          setup_evaluation.send(:create_subgroups)
+        end
+      end
+
+      describe '#create_subprojects' do
+        it 'creates subprojects' do
+          gitlab_com_group = create(:group, name: 'gitlab-com', parent: group)
+          gitlab_org_group = create(:group, name: 'gitlab-org', parent: group)
+
+          expect(setup_evaluation).to receive(:create_subproject).with(
+            name: 'www-gitlab-com',
+            file: Rails.root.join("tmp/duo_chat_samples/gitlab_com/02_www_gitlab_com.tar.gz"),
+            namespace_id: gitlab_com_group.id
+          )
+          expect(setup_evaluation).to receive(:create_subproject).with(
+            name: 'gitlab',
+            file: Rails.root.join("tmp/duo_chat_samples/gitlab_org/02_gitlab.tar.gz"),
+            namespace_id: gitlab_org_group.id
+          )
+
+          setup_evaluation.send(:create_subprojects)
+        end
+      end
+
+      describe '#create_subgroup' do
+        it 'creates a subgroup' do
+          file = Rails.root.join("tmp/duo_chat_samples/gitlab_com/01_group.tar.gz")
+          body = { name: 'gitlab-com', path: 'gitlab-com', parent_id: group.id, file: file_double }
+
+          expect(File).to receive(:new).with(file).and_return(file_double)
+          expect(setup_evaluation).to receive(:token_value).and_return('token-string-1')
+
+          expect(Gitlab::HTTP).to receive(:post)
+                                    .with("#{setup_evaluation.send(:instance_url)}/api/v4/groups/import",
+                                      headers: { 'PRIVATE-TOKEN' => 'token-string-1' }, body: hash_including(**body))
+                                    .and_return(http_response)
+
+          setup_evaluation.send(:create_subgroup, name: 'gitlab-com', file: file)
+        end
+      end
+
+      describe '#create_subproject' do
+        it 'creates a subproject' do
+          gitlab_com_group = create(:group, name: 'gitlab-com', parent: group)
+
+          file = Rails.root.join("tmp/duo_chat_samples/gitlab_com/02_www_gitlab_com.tar.gz")
+          body = { name: 'www-gitlab-com', path: 'www-gitlab-com', namespace: gitlab_com_group.id, file: file_double }
+
+          expect(File).to receive(:new).with(file).and_return(file_double)
+          expect(setup_evaluation).to receive(:token_value).and_return('token-string-1')
+
+          expect(Gitlab::HTTP).to receive(:post)
+                                    .with("#{setup_evaluation.send(:instance_url)}/api/v4/projects/import",
+                                      body: hash_including(**body), headers: { 'PRIVATE-TOKEN' => 'token-string-1' })
+                                    .and_return(http_response)
+
+          setup_evaluation.send(:create_subproject, name: 'www-gitlab-com', file: file,
+            namespace_id: gitlab_com_group.id)
+        end
+      end
+
+      context 'when running not in dev or test mode' do
+        before do
+          stub_env('RAILS_ENV', 'production')
+          allow(Gitlab).to receive(:dev_or_test_env?).and_return(false)
+        end
+
+        it 'raises an error' do
+          expect { setup_evaluation.execute }.to raise_error(RuntimeError)
+        end
+      end
+
+      context 'when finished working' do
+        it 'shows a message' do
+          expect do
+            setup_evaluation.send(:print_output)
+          end.to output(a_string_including('Setup for evaluation Complete!')).to_stdout
+        end
+      end
+    end
+
+    context 'when the server is not running' do
+      before do
+        allow(http_response).to receive(:success?).and_return(false)
+        allow(Gitlab::HTTP).to receive(:get).and_return(http_response)
+      end
+
+      it 'raises an error' do
+        expect { setup_evaluation.execute }.to raise_error('Server is not running, please start your GitLab server')
+      end
+    end
+  end
+end