Самое оптимальное решение - на основе архитектуры. Легко раздавать разным командам работу над конкретными компонентами системы, особенно, если в системе уже определены интерфейсы.
Но если архитектура такого деления системы не позволяет, то у вас проблемы не исчерпываются раздачей задач. В общем случае приходится давать каждой команде работать над некоторым кодом на основе некоторого прототипа, с обязательным определением правил создания кода. Результат принимается на основе демонстрации работы прототипа и code review. После завершения всех прототипов команда интеграции должна будет вытащить нужный код из прототипов и объединить его в единое целое. Такая интеграция - задачка препротивная, надо сказать.